I'm back baby!
So, here is the thing that's been consuming my development time lately. Cellular automation for use in real-time games frequently has to be heavily optimized. When you're cycling though every cell of a hundreds by hundreds array every frame, then even the overhead from those cells in which you just check contents and decide nothing needs to happen is significant.
My current strategy for negating this is to not use a big loop that iterates through every cell. Instead, I keep a list of every cell that _might_ change this frame. I calculate those and, any that do change, I add adjacent cells to the list for the next frame.
It's much MUCH faster, but it's worth noting that this is entirely because, for most of the game world, large portions are static between each frame. Stone is largely inert, so we don't need to worry about it except how other things react to it -- they are the initiating factors in that, so their routines handle the work. Empty spaces (that don't contain weird gases) are similar. These two cell types are 90% of the world. By removing them from consideration, it's worth a huge performance gain.
A huge gain, but it turns out, not huge enough. I remind you that, before, we kept performance under control by only updating the screen and a short distance outside of it. Under this system we update the whole world, and factoring in all of the cells that CAN change, it's a bit too much to reliably handle.
There is a way around it. We sort the update list, using one of the handy-dandy, heavily-optimized Python sort functions, with the sort key being a simple Cartesian distance from the player or cursor. Then we can just pop off the first few hundred or so every frame, and leave the rest for the next frame. If the player never goes anywhere near them they won't get handled, but as soon as he does they'll enter consideration.
It's a cheat, but real-time game development is basically a convoluted series of cheats, a set of makeshift concessions to processor speed and memory limits. Now that we have multicore machines and multi-gigabyte memory spaces this fundamental fact is sometimes obscured, but it doesn't change it.