3
\$\begingroup\$

So, I'm not really sure where to start with this question. Feel free to tell me I'm stupid and Off Topic but I'd also like you to tell me why.

So, the maps in the game I am designing will consist of lots and lots and lots of voxels. Most of the voxels will just sit there and some of them will have methods run when they are touched or something happens around them. However, some blocks will constantly being doing something. Now, I'm not sure if I should have a array in every chunk (Group of voxels) that contains all the 'active' blocks or if there is another way. I know that some voxels will run code when they are loaded that makeup for all the time that they hadn't been doing anything but I may need to constantly run some voxels. (Machine that overheats or powers something can't just be loaded in 20 minutes after it blew up; or can it?)

So, now that that basic background is over, here is my question: Will an array storing all active entities in an area suffice as a way to run all the frame by frame methods of the blocks? Or is there a "normal" way to do this that I am unaware of?

EDIT: I just realized that the client that does rendering will not do a majority of the operations for the game engine. I will have a server that does it. The answer to this question is still largely relevant and helpful though. I just thought I'd mention my change.

\$\endgroup\$
3
\$\begingroup\$
  1. Yes, this is a reasonable approach. Note that in principle what you need is not an array, but a set. This is relevant because if one of your active voxels is destroyed/replaced, you need to be able to efficiently remove it from the set. If your platform doesn't have a set type, then use a hash table with the voxel coordinates as keys and dummy values.

  2. Another case that might arise is a voxel which does something on a schedule (once or repeating), but not every frame. If you want to support this efficiently, then you should keep track of the voxels to be triggered and the in-game-time to trigger them, and the best kind of data structure for that is a priority queue, which allows you to efficiently ask the question “which voxel needs to run next?” so you don't have to check the entire set.

  3. However, if you have many voxels which should update on the same schedule, but less than every frame, the set approach is again appropriate; you simply don't do it every frame. (If you need to spread the CPU load you could choose to do part of the work in each frame. Say you're doing it every 3 frames: Copy the set into an array, divide the length by 3, and iterate over one third for each of the next three frames.)

Note that these options are different not just in efficiency but in the resulting behavior of the game: a periodically triggered set will cause voxels to update all in sync at the same instant (there can be no phase difference), whereas the priority queue can represent the exact time instants of something like "this voxel does something 1.5 seconds after it comes into existence, and every 1.5 seconds after", but takes more resources to manage that extra information.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.