How to update a lot of random tiles in a 2D array?

Started by
12 comments, last by ankhd 11 years ago

You haven't provided nearly enough detail about your problem to really get at the potential problems. Based on what I've read you may have one or more of the following problems (among others which may not be listed here):

  1. Bad algorithm.
  2. Poor memory access patterns.
  3. Bad memory allocation and usage causing excess garbage collection pressure.

Updating only tiles within your "update radius" should be very fast unless your radius is so large, that it contains the entire map. Even then, you'd have to have a colossal map to have it take enough time to notice a really long pause (~1 second or more). How are you determining which tiles are in your "update radius"?

Maintaining homogeneous lists of each tile type could be advantageous, but you pay for it with memory. Suppose you put each type of tile in its own list and each list element points directly to the actual tile in your grid. This gives you the advantage of not having to search the entire grid for all elements of a certain type. But you're paying for this advantage in speed (by not having to search) by spending memory to have all that information already computed. I would say it's a worthy trade as long as your game requires you to perform many operations/queries on only subsets of your data, where your subsets typically match your tile types. If you have operations that require iterating over the entire 2D grid anyways, then this may not be worth doing, since at each tile you visit, you could perform the operation right then and there.

Creating new tiles entirely for the update is probably a bad idea. C# is garbage collected. If you create tons of new tiles every frame and remove references to the old tiles, you could be creating enormous pressure on the garbage collector. You should avoid orphaning data at all costs and just mutate existing memory if you want to avoid garbage collection hiccups.

Your description of "update" is woefully vague, but I suspect your update is performing something pathologically expensive or your overall algorithm for iteration is just far too excessive for what you want to accomplish. Even for large 2D grids, you shouldn't have much of a problem updating the entire grid if you've carefully designed your algorithms and data structures.

Advertisement
If grass is growing according to a certain schedule, I'd simply place tiles in a priority queue (efficiently answering only one query: which tiles are due for a special update at timesteps <=N?). You process tiles, swapping graphics, altering stats, and so on, and you put tiles back in the priority queue tagged with the appropriate future time of their next update. Obviously, tiles can be retired from the queue (e.g. grass reaches the growth limit), added to the queue (e.g. an inert dust tile gets seeded), rescheduled (e.g. grazing delays grass growth events), delayed if there are too many updates in a single frame (just process up to K events per timestep rather than all ripe ones, with K greater than the average number of events per timestep).

Omae Wa Mou Shindeiru

Are you sure your getting slow because of the update rather than the draw?

The game we are working on now is hex tile based and to avoid bottle neck in the draw we instance draw the tiles so that there is one draw call for each base tile. We also don't recreate the list of transforms for each tile every update.

If you have a base grass tile with say 100 instances of it in the world - perhaps you can simply update the base object mesh/texture/whatever your needing to update and have all of your instance tiles refer to the base. Only store essential information in the instances that must change per instance such as position and size and such.

Make your game like a river. Never dam it.
Eg. Make your update run for say ten tile then return to your app and on the next process round start at the last tile and keep repeating.
Remember treat you app like a river always flowing.

This topic is closed to new replies.

Advertisement