BenjaTK / Gaea

Procedural generation add-on for Godot 4.
https://benjatk.github.io/Gaea/
MIT License
1.08k stars 54 forks source link

Multi-threading/queueing chunk generation #34

Closed BenjaTK closed 4 months ago

BenjaTK commented 1 year ago

With #29 merged, the new chunk system is now available and working great. However, it could still use some optimizations. We could use threads, though I have no idea how to work with them. Do you think it needs more optimization?

titusio commented 1 year ago

The ChunkLoader could only load a limited amount of chunks per frame. We could queue the chunks we want to load instead of loading them right away.

BenjaTK commented 1 year ago

Multi-threading could possibly be added to non-chunked generators too, but idk how.

RAMENtheNOODLES commented 8 months ago

I was fiddling around with this yesterday, and I found out that adding multi-threading will require a pretty significant rewrite to the chunk generation, and even the rendering. Because of me being relatively new to this project, I do not know exactly how everything works, but I think I have a good understanding of what needs to be changed. I'll create a list to help me with figuring out what to work on and also show anyone else what would need to be done for multi-threading/queuing and also allow them to add on to the list if I missed something.



I will attempt to get this implemented, but I also hope that this helps anyone who wants to attempt this as well.

MatiasVME commented 6 months ago

I think you have to consider that multi treading is not very web compatible so you also have to consider that it is a toggleable option :S

BenjaTK commented 6 months ago

I was fiddling around with this yesterday, and I found out that adding multi-threading will require a pretty significant rewrite to the chunk generation, and even the rendering. Because of me being relatively new to this project, I do not know exactly how everything works, but I think I have a good understanding of what needs to be changed. I'll create a list to help me with figuring out what to work on and also show anyone else what would need to be done for multi-threading/queuing and also allow them to add on to the list if I missed something.

* Refreshing the required chunks by clearing the array every time is slow, especially if there are only certain chunks changing

* Rendering should be put in a separate thread, but the rendering part of this addon, is one of the things I do not exactly know where to start in terms of making it multi-threaded

* I agree with queuing chunks to be loaded/unloaded later, and the process of loading/unloading chunks should be in it's own thread

* Most of the generators would likely need to be modified to support multi-threading

I will attempt to get this implemented, but I also hope that this helps anyone who wants to attempt this as well.

Hey @RAMENtheNOODLES! Sorry I'm so late, but how did this attempt go?

DriftWare07 commented 6 months ago

Loading chunks with a gridmap is very slow. Is there a better renderer to use for this or can I optimize it in some way?

cullumi commented 4 months ago

Figured I'd pop into here with PR #116 .

I took a crack at threading both the Chunk Loaders and the Renderers using some past experience fiddling with this kind of thing. Right now they're implemented as threaded wrappers around the original nodes, but it could be rolled into the originals if it's found to be reliable enough (the threading can be toggled with an exported boolean).

The threaded chunk loader simply loads all the chunks on a separate thread so as to not block the main one.

The threaded renderers parallelize the rendering of chunks and immediately display them once the work is done. This is some proper multi-threading above and beyond just preventing the program from hanging.

Luckily, almost all of the changes are limited to the new wrapper scripts. The exceptions are certain calls that had to be deferred for thread-safety within the heightmap and chunk aware generators and the grid/tilemap renderers themselves. Those could also be done as thread_safe calls instead if that were desirable. This does however highlight the need for threading to be kept in mind when actually making various generation algorithms thread-safe.

There are more optimizations that could be done, but I think this addresses most of the points @RAMENtheNOODLES laid out:

  • Refreshing the required chunks by clearing the array every time is slow, especially if there are only certain chunks changing
  • Rendering should be put in a separate thread, but the rendering part of this addon, is one of the things I do not exactly know where to start in terms of making it multi-threaded
  • I agree with queuing chunks to be loaded/unloaded later, and the process of loading/unloading chunks should be in it's own thread
  • Most of the generators would likely need to be modified to support multi-threading

Lemme know what y'all think 😄

BenjaTK commented 4 months ago

This has since been fixed by @cullumi, thank you so much.