Thanks a lot for all the replies
I already noticed one flaw in the way I update things. Instead of just changing a value when the grass is growing, I am actually creating a whole new instance of that specific tile. There's absolutely no reason for that, and I am pretty sure creating loads of new instances in one update cycle causes problems.
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)
I like the idea. I wasn't actually considering updating the entire world, only within my update radius. Doing this might very well make it possible though.
Thanks for the input
Computers are quite good at doing repetitive tasks In our game, we use a component system, and we can have a lot of components in a scene - updating usually takes negligible time, as long as you avoid doing stupid thigs (and do profile the code when you see it's slow). For compute-intesive tasks (like texture generation), parallelizing the code can dramataically speed it up.
What I'm saying is that you can simply go and update everything. Let every component know when it should and when it shouldn't update (either determining it interally, or by sending a message when it goes out of scope - e.g. Enabled/Visible properties). Alternatively, you can maintain a list of components that need to be updated. Don't worry - in C# references are more or less just pointers, so having lists of components that live in memory anyway won't take all that much memory... you'll end with lists of pointers, not duplicated objects.
You will have to have a list of components.. I'd rather use some sort of composition (component on top of component whose job is to randomly update its child component), as it is more flexible... and in time can allow you to do complex things with very little code.
I think I do obsess about performance lately. I haven't had the chance to test my game any other computers than my own, and a very old laptop. The laptop can't run the game very well, I do believe that it is because of my lighting, which is rather CPU intensive.
Currently the way I handle updates, is simply by iterating all the tiles within a certain distance from the player, and change the tiles accordingly. I am not happy with that approach though, since all dirt tiles within range will grow grass every time I run the update.
I always wondered what the difference is between references and pointers. I never did much C++, but I did learn that pointers was the force of C++, which had be wondered what the difference between those two were. It's nice to know that they're similar at least. - Thanks for your input
Several points may help you to cope with your problem.
- divide your map in several cluster/quadtrees, and process one or a few cluster at a time
- have a queue for each processing, to hopefully avoid scanning each of your tile. Remove the processed tile from the queue. If a tile need constant processing, it should reapply to the queue
- Avoid having to change lots of tile at the same time. In your case of the grass, shift the growth cycle for each tile so that if you have N tiles for grass, you have to update, say, N/8 tiles at each run of the loop
To sum up, divide and conquer...
After reading all these posts, I think I've decided on a queue system, as you suggested. I was thinking of keeping it all in one big queue (List) and then at certain intervals (maybe random) I update a certain amounts of tiles on the list, and remove them, if no more updates are required, or move them to the bottom of the queue.
This will also be very useful for plants, and farm objects that I am adding to the game soon. Also when winter is over, I can use this to melt the snow over time.
I really appreciate all the input I got from you guys
Thanks a lot!