Problem in trying procedural generation

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By tam0705

Hello everyone :slight_smile:

So I have a 2D top-down shooting game whose terrain is generated procedurally. I used Tilemap to ease the coding. I’ve managed coding the room & corridor generator, but I also wanted to generate boxes in the rooms. These boxes will act like chests, they have some items in them for players to collect. What I really want to ask is:

How can I generate those boxes without making them blocking corridors or other boxes?

I prefer the boxes to be generated in the edge of rooms, without, as mentioned, blocking corridors or hallways. Since each box has their own collision, I also want them not to block the other boxes, leaving them unreachable by players to open.

For more information, I have a Rect2 array (consisting rooms), and a dictionary (consisting corridors, with Rect2 rooms as keys and Vector2 arrays of corridor points as values) as my data after generating rooms and corridors. I hope this will make answering my question easier. :v

Is there any effective way to do this? Thanks. :slight_smile:

:bust_in_silhouette: Reply From: MysteryGM

Normally in games you would just use the NavMesh to check for this. Because a NavMesh has to avoid objects; remember to update the NavMesh, or maybe use 2.
Other path finding could also work.

If you don’t want to use a NavMesh, then spawn the object at any point. Use avoidance behavior to move it away from objects. This takes time, so it will cause a long loading delay.

I’m sorry but I don’t get your point about how to use NavMesh XD
Do you mean detecting tiles with NavMesh and replacing them with my box tiles?

And about the avoidance behaviour, what entities should I make these boxes avoid? I want them to stick on wall edges, so it’s certainly not walls right?

I’m sorry if I asked too much, I’m new in procedural generation. :slight_smile:

tam0705 | 2018-12-30 06:51

I don’t think a NavMesh is a good option here. I’m not sure though, since I’ve never used NavMesh. The avoidance behaviour way might fit your data better, but I think there is still a more suitable way.

Tapio Pyrhönen | 2018-12-31 07:20

:bust_in_silhouette: Reply From: Tapio Pyrhönen

If your rooms are in a Rect2 array, you can do something like this with them:

func find_places_for_boxes(var room_rect):
var arr = []
var box_size = 32

# Move along the walls in a loop
var x = room_rect.position.x + box_size / 2
while(x <= room_rect.end.x - box_size / 2):
	# Top wall
	arr.append(Vector2(x, room_rect.position.y + box_size / 2))
	# Bottom wall
	arr.append(Vector2(x, room_rect.end.y - box_size / 2))
	x += box_size

# Same thing for left and right walls
var y = room_rect.position.y + box_size / 2.0
while(y <= room_rect.end.y - box_size / 2.0):
	arr.append(Vector2(room_rect.position.x + box_size / 2.0, y))
	arr.append(Vector2(room_rect.end.x - box_size / 2.0, y))
	y += box_size

return arr

The function takes a rooms Rect2 as a parameter and returns an array of points that are near the walls. There are overlapping box points at the corners, and they can be removed like this:

func remove_overlapping(positions, margin):
var i = positions.size() - 1
while(i > 0):
	var i2 = i - 1
	while(i2 >= 0):
		if(positions[i].distance_to(positions[i2]) < margin - 1.0):
			i2 = -1
		i2 -= 1
	i -= 1
return positions

If you now instance a sprite for every point, it will look something like this:

Notice one of the rooms has badly placed boxes near the corners? Thats because the room size isn’t a multiple of the the box size. That should be easy to fix though.

I’m not sure what to do about the corridors. Maybe remove box points using the Rect.has_point or Rect.intersects method.

Here’s the sources for this test:

Thank you really much! I will try implementing this in my game. Maybe I’ll tweak it a little bit so it will work well as I wanted. :slight_smile:

tam0705 | 2018-12-31 08:19