get_simple_path too fast after procedurally generated tilemap

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


I’m working on a 2D Zelda-like game. The map is procedurally generated.

  for x in range(chunk_size):
     for y in range (chunk_size):
        var a = terrain_noise.get_noise_2d(x+x_pos,y+y_pos)
          if a > snow_height:
           terrain_tile = SNOW
        elif a > mountain_height:
           terrain_tile = MOUNTAIN_DARK
        elif a > lower_mountain_height:
           terrain_tile = MOUNTAIN_LIGHT
        elif a > grass_height:
           terrain_tile = GRASS[randi()%GRASS.size()]
        elif a > sea_level:
           terrain_tile = SAND
        elif a > deep_sea_level:
           terrain_tile = SHALLOW_WATER
           terrain_tile = DEEP_WATER


All tiles in the tileset have a square navigation poligon of the exact tile size.

After the map is generated, some NPC should spawn a get to move around:

func spawn_guard(x_pos,y_pos):
   yield(get_tree().create_timer(1.0), "timeout")
   var spawn = guard.instance()
   var posi = Vector2(get_parent().get_node("World/Navigation2D/TerrainMap").map_to_world(Vector2(x_pos+20,y_pos+20)))
   spawn.position = posi
   var goal = Vector2(get_parent().get_node("World/Navigation2D/TerrainMap").map_to_world(Globales.player_pos))
   spawn.goal = goal 
   var path = $Navigation2D.get_simple_path(posi,goal)
   spawn.path = path

My problem is:
when yield is called at the beginning of the spawn_guard function to have a pause between map generation and spawning, everything works fine.
When I remove the yield line, the variable path is empty.

It looks like the map is not yet “finally built” (navigation poligons connected?), so get_simple_path returns an empty array.

How can I make sure, the tilemap is completed, so get_simple_path has all navigation poligons to get to work?

:bust_in_silhouette: Reply From: Andrea

the world state (the one needed for the simple_path to work) is not updated, it will be updated at the end of the frame, but you are calling the spaw_guard in the same frame.

the solution is to forcefully update the nav_polygon by turning it on and off again, but it’s not that easy for a tilemap

(i had the same problem 2 years ago, but i cant remember if I solved more efficiently than simply yield 1 frame, i’ll dig a little in my past project too see if i discover anything)