Context:
In my falling sand simulation (In Rust), I have split the world into different chunks so that there can be multithreading. In each update cycle, there are four iterations so that the world updates in a checkerboard pattern as explained in this Noita GDC Talk (Linked to relevant portion). This is so that data is not mutated at the same time. In order to move between chunks, each ‘ChunkWorker’ (created for purposes of updating) borrows a center chunk of the iteration and neighboring regions that are not updated in that region.
Problem:
I will use the example of only ‘sand’ falling straight down through different chunks but the following happens going other directions as well: The simulation will work perfectly fine if the iterations cause chunks to updated from below-up, however if the opposite happens, when the cell is at the bottom of the top chunk it can see in the borrowed region that there is occupied space below, however it does not know if this space would be vacant or continue to be occupied for the update step as the iteration containing the chunk below has not processed. In that process it could open the space allowing the sand to freely continue falling but instead it causes a stutter and a line of ’empty/air’ cells because it thinks it cannot fall through the boundary. Reversing the iteration order causes problems for other types of cells that would travel in the opposite order, and the problem occurs when going horizontally as well.
Currently my simulation is running with a single buffer, a Vec in each chunk. I believe my options are either to:
- Create a secondary buffer to preserve un-updated state somehow and use this to communicate
- Or to create some kind of channel to communicate these transfers
- I can also probably just ignore and work around the problem, increasing chunk size so that the potential player/user would not notice this often and use other tricks/special rules. However this might impact the amount of gain from multithreading (I would need to test this)
Basically I am wondering what kind of data structure or algorithm should be used in this situation (In Rust) that would allow the whole world to update as if it was a single chunk, but able to take advantage of multithreading.
sammy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.