Add more dynamic things - water, ice, fire, crawling goo of dynamicismism - so you dont feel bad for looping through everything
Lets say by average grass needs to be updated every 4 mins.
You could do this:
Have different containers for grass tiles, 4 mins, 2 mins, 1 min, 30 sec... and so on (stop at some point)
After update of a tile, it goes to 4 min container with (4 + time since 4 min container was last updated) minutes of time.
When you update a container (tiles only updated when they reach 0 time!), you reduce the time of the below container (2 mins for 4 min container) from each tile in it, and move it to the container below.
4 min container could be the world. Everything else could be a list of tiles. That means you loop thru the world every 2 mins.
The last container needs to be checked at whatever update resolution you want (every 1 second, every 15 second...)
a) World (4 min) (half of all tiles here)
b) List (2 min) (fourth of all tiles here)
c) List (1 min) (eighth of all tiles here)
d) List (30 secs) (eighth of all tiles here) --check this lets say every 5 secs, reducing 5 sec from everything. If something goes below 0, (lets say -3), you add it to the 4 min container with time (4 minutes - that 3 seconds + time since last time the 4 min container was updated)
*might contain logical errors*
That seems somewhat reasonable at least. You can vary the amount of the containers. I would keep times half of the above time, seems optimal. Now, if you have a resolution of 5 secs, instead of updating ALL tiles by looping thru the whole world every 5 secs, you can loop thru the world every 2 minutes, and loop thru only a small part of the tiles every 5 secs.
If someone understand this, please come up with an O() thingy because it looks like it contains a log or something else cool.
Wait this doesnt make any sense. Forget all about moving tiles back to the 4 min container, unless they happen to die and start growing again