I am trying to make a procedural map generation work and am close to finishing the base setup.
TL;DR:
The collision check in my script works most of the time, but sometimes, randomly doesn’t.
if I add a timer with 0.3 to 0.5 seconds wait to the method, it is way more consistent - so I suspect a race condition.
Need help for a proper replacement for the timer.
the anchor points have a position and rotation and are for aligning the map chunks to each other
to check for collisions, I build an AABB box from the chunk scene, since eventually it will consist out of multiple meshes.
Workflow:
add the first chunk to the scene
then in a loop / on timer:
get all chunks in the scene and pick one
get all anchors of that chunk that are not used for a chunk-connection
pick a chunk scene for the new chunk, instantiate and add it to the scene
get a random anchor from the new chunk and use it to rotate and align the new_chunk so it fits to the old_chunk
check if the new chunk is colliding with anything else
clean up the scene and mark the anchors as occupied if placement is fine, otherwise repeat
it mostly works but the collision check is a problem.
It works most of the time, but then suddenly just doesn’t for like one call and then works again for several.
Here is the method for it:
Since you mention a possible race-condition, I looked over the documentation for GDScript’s await keyword and any related features.
As it currently stands, the code for your check_is_colliding() function does not contain any coroutine-specific functionality. As such, it is not recognized as a coroutine when used as such inside of create_new_chunk(). As stated in the documentation:
If you use await with an expression that isn’t a signal nor a coroutine, the value will be returned immediately and the function won’t give the control back to the caller.
As for how to transform the check_is_colliding() function into a coroutine, I’m afraid I’m not the best person to ask. My first thought would, like you, be to await a timer for a small amount of time. However, I imagine there is a way to await a physics update so you don’t have to rely on an arbitrary waiting period between collision check iterations.
Does this suggest that even with a timer the system is not 100% reliable?
Sorry I can’t be of more help than this right now. If I think of something, I’ll keep you posted.
By the way, thanks for making a post with adequate information. That rarely happens.
Thanks for your input!
Tonight i will probably do some more testing to get to the core of it.
Yes, even with the timer, it is still not 100% reliable. It feels like it is a bit more reliable, but that might be a false impression due to the randomness and since without it I see errors faster.
But generally, would my approach be correct?
I also thought about using a grid map to denote which spaces are occupiedm but that would limit me to 2 dimensions and also limit me in designing the chunks.
Hello! I actually had a very similar idea for 3D chunk generation and ran into a very similar problem. I asked a question on here and someone recommended I call
(yes twice) before checking collisions. I think this is because you can instantiate and add a child but it won’t check for collisions until at least one physics frame has occurred. This caused a bunch of other issues; it seemed like the original caller function was executing the rest of it’s code before actually getting the collision check. I was able to get it to work by using “await” before any function that used the physics_frame update.
Basically, I have a function called “orient_and_place” which handles rotating the chunk based on it’s connection point and the anchor point it was selected to attach to. The double “await get_tree().physics_frame” is inside that helper function, so any time I call “orient_and_place” it has “await” in front of it. Additionally, any function that calls orient_and_place also needs to have await in front of it.