How can I simulate thousands of things at high frame-rates?

I'm working on a simulation game like SimTower where I'd like to keep track of thousands of items at once.

Other games like this, appear to have hundreds or thousands of rooms with elevators with what looks like hundreds or thousands of people. I'm concerned about achieving the same thing in my game.

How can I realistically keep track of each individual person/room/elevator in the game? I assume I can only render what's on the screen, but how can I afford to constantly simulate everything that is off the screen?

• Questions about how a game implemented some feature are off-topic here, but questions asking how to implement a similar feature are generally fine, so I've turned your question into the latter. – user1430 Jun 1 '16 at 20:45

Thousands of things probably isn't that big of deal. As you note, even older games like SimTower could do this pretty reasonably. Consequently the first thing I'd suggest you do is the simple, straightforward option:

foreach(Thing t in AllOfTheThings) {
t.Simulate(elapsedTime);
}


Once you've done that, if your game still runs acceptably, then you're done. If it doesn't, or if it starts to slow down, profile the game to make sure you're actually bottlenecking on entity simulation code. If you aren't, solve that problem instead.

But after all that, if you are bottlenecking on entity simulation, there are some techniques you can employ.

• You can adjust the tick rate of entities. Instead of ticking all of them every frame, tick half of them one frame and half of them the other (for example, odd numbered entities on odd frames, even numbered ones on even frames). The delay in any individual entity update will not likely be noticed by the player, but you will have reduced your per-frame workload by half.

• Similar to the above, you can tick entities differently based on how far away they are from the player's current camera focus. This is common in open-world games like Skyrim, which always simulates active NPCs, but does so far less frequently for NPCs that are far away from the player because the player can't see or interact with them.

• The above two methods are ways of reducing the level of detail in the tick rate; you could instead reduce level of detail in the simulation. If an entity is too far away from the player's focal point, you can drop some highly-detailed aspects of their update to save time. You may not need to accurately simulate their pathfinding, for example. Instead, switch them to a coarser simulation that just makes sure their basic needs are met: Should I sleep? Teleport to bed instead of bothering to try to walk there. Should I shower? Teleport to the bathroom. Pathfinding can be expensive so this can save some time.

• If entities cannot affect eachother during their simulation, or you can identify isolated groups of entities that will not affect entities outside of that group during simulation, you can offload the processing of those entities or groups to worker threads, running them in parallel.

• Ensure your entities and the update system they use are designed to take advantage of cache coherency in their data. It can be a huge performance win.

All of these methods have pros and cons, and must be adapted to your specific scenario and the needs of your game. You may need to employ all of these methods, or maybe none, or maybe you can select a few that work best for the profiling data you've gathered.

One last piece of advice is to start your simulation relatively simple. You may be surprised as how complex simple simulations can end up looking in practice once you introduce sufficient scale and some basic randomization. You may be surprised to discover much of the "complicated" simulation you think is going on in SimTower and similar games really isn't all that complicated and ends up being quite trivial for a modern machine to perform at scale.

• cache coherency in their data of course big +1 but that requires to manage memory manually. for example by using C++ and not C#. – v.oddou Jun 2 '16 at 1:45

Almost every game fakes what ever it can get away with. The important thing is the impression of actual people going about their day. I would not do anything with the offscreen action. Instead when the player scrolls to a different location, I would spawn the people at random location but with some probability to where they were last time the player saw them. The same way should be done with what the people are doing. If this is done correctly and used together with the time of day, what the people has done allready in the day, what they prefer to do and other ideas you might have, it can seem they really do things outside the screen.

• Sounds okay, but don't do that in immediate offscreen locations - player will quickly notice that whenever he moves away/back everything resets. – Kromster Jul 8 '16 at 13:19