Stuck on 2D top-down procedural dungeon builder from premade rooms

Godot Version

4.2

Question

Hi everybody :slight_smile: i’m very new to Godot and loving it so far.
So, I’m trying to blueprint a dungeon builder with that kind of flow

func dungeonBuilder(a given room)
	iterate over open doors from that given room
		instanciate a random new room from the premade pool & synchonise position/rotation to fit
		check if it overlap an other room
			if so, try others or close that door and continue
		register room data

_on_overlap():
	switch a control bool used inside dungeonBuilder() to handle overlaping management at dungeon generation time

ready():
	iteratively call dungeonBuilder()

It works great, every new room is correctly merged to the rest of the maze and emit an overlap signal as intended, BUT… i can’t manage to catch thoses signals inside my dungeonBuilder(), in fact, all signals are delivered AFTER the end of _ready() call, preventing me to handle overlaping during dungeon generation.

I even tryed to await some frames to maybe let signals lives theirs lifes

await get_tree().process_frame

it sometimes kind of work, other times it break my code, making me feel very dumb :cold_face:

Here is the full code : godot-4.2-level-builder/scenes/levels/root_level.gd at main · daSanchezMeister/godot-4.2-level-builder · GitHub

I have no clue how to workaround this case, i may have taken some weird design decision, if you think so please let me know as i really want to improve my skills.

Have a nice day folk!

The physics server updates once per physics frame. If you are creating areas/bodies and checking collisions against them inside a loop it won’t work as the physics server has not updated its state. You’ll need to wait at least a physics frame before being able to query the physics server for collisions/overlaps.

I’ve not tried this but it may be better not waiting for signals to fire and, after awaiting for the signal SceneTree.physics_frame, use Area2D.get_overlapping_areas() or query the physics server directly by using the PhysicsDirectSpaceState2D if you only have a Shape with PhysicsDirectSpaceState2D.intersect_shape()

3 Likes

You right, it worked !

Awaiting physics_frame instead of process_frame was the way, so i could use the inbuilt Area2D method instead of trying to catch a custom signal inside my dungeon build logic :

await get_tree().physics_frame
				
if room_B.area_node.has_overlapping_areas():
	room_B.queue_free()
	continue

then await again before every dungeonBuilder call

func _ready():
	for i in range(max_dungeon_size):
		await get_tree().physics_frame
		dungeon_builder(rooms_to_connect.pop_front())

Thanks a lot kind sir <3

Funny fact is as every iteration has an awaiting frame i literaly see the dungeon building in front of me at runtime and got so amazed by the maze it outcomes

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.