Topic was automatically imported from the old Question2Answer platform.
Asked By
CowThing
Old Version
Published before Godot 3 was released.
In a game like a roguelike, where a level if fully generated before the player starts playing it, how would I do “background loading” with the function that is generating the level? Since the level generation could be doing several loops to place and modify things across a whole level it does create a noticeable freeze in the game before the level is fully loaded.
Is there a way to have the level still generate as fast as possible and have it not freeze the game, much like background loading does for loading a resource?
I didn’t do this myself ever but the first thing I woud try is coroutines:
var thread = Thread.new()
func do_stuff(arg):
var area
# Expensive operations here
# Avoid loading when other stuff is happening
call_deferred("load_area", area)
func load_area(area):
pass # load the area
func start_load(arg1, arg2):
if not thread.is_active(): # Can't run on active thread
thread.start(self, "do_stuff", arg1, arg2)
More complicated solutions may involve the thread-run method emitting a signal or something like that, or a queue of areas to load in case the thread is busy.
I think this is what I want, to use threads. But I don’t really understand how threads work. I have it set up so that all the map creation is done in one function, and use thread.start() to start the function, like in your example.
I’m creating and modifying nodes in the build function. The first thing the function does is instances the base map scene, then I do all the generation, adding more nodes as children of the map, and modifying values. Then in the load function I pass in the completed map node so I can add it as a child to my main game, allowing it to enter the tree and start working.
The problem is it takes a lot longer to build in the thread. Like every time a node is created and added as a child it waits one frame, instead of doing it all as fast as possible. I’m not really sure what I’m doing wrong.
CowThing | 2017-03-03 15:39
Maybe you could try using dictionaries or arrays to create a virtual “tree” and then commit them all to scene when it’s complete? If you are using call deferred also that will cause things to wait a frame or so.
raymoo | 2017-03-03 17:04
Have you tried to change the thread’s priority? Because AFAIK it is set to low by default.
No matter what you do, level generation cannot happen instantly. Since the player must wait until the level generation finishes, a wait is unavoidable.
What you can do instead is create a ‘loading’ scene, which shows a progress bar while you generate the level. Once the level generation finishes, you can load it & player can start playing.