Menakta
Unreal Engine4 min

Rendering fifty years of history in Unreal

A strategy game with a timeline you can physically walk along. At daily resolution that is a quarter of a million objects. Here is how you draw them and keep the frame.

Suppose you want a strategy campaign whose history is not a menu you open, but a place you stand in. A timeline laid out in world space, decades long, that you walk along and inspect. Every year. Every month. Every day, if you zoom far enough in.

Do the arithmetic before you write any code, because it is unkind. A fifty year span at daily resolution is on the order of a quarter of a million ticks. If each tick is a mesh component, and the obvious first approach is that each tick is a mesh component, then you have asked the engine to own, track and submit around 226,800 separate objects.

That is 226,800 draw calls a frame, and several hundred megabytes of component overhead before you have loaded a single texture. It will not run. Not on your machine, not on anyone's.

The expensive operation is rarely the expensive operation. It is usually the cheap one, in a loop, at a scale nobody stopped to count.

The way out is to notice what is actually true of these objects: they are identical. Every tick on that timeline is the same mesh. They differ only in where they sit. And that is precisely the case hierarchical instanced static meshes exist for. One component holds thousands of instances, and the GPU draws the whole set in a single instanced call.

So you collapse the structure. Batch the ticks by type, hand each batch to a hierarchical instanced mesh component, and let the GPU do what it is good at. The quarter of a million components become seven. The draw calls follow them down. The memory drops by an order of magnitude, and the timeline becomes a thing you can zoom through rather than a thing that kills the process.

The general rule this keeps teaching: before you optimise the thing you are drawing, count how many times you have asked to draw it. Most real-time performance work is not clever. It is noticing that you have described your problem to the engine in the worst available way, and describing it again.

There is a design payoff too, and it is the part worth planning for. Once the timeline costs almost nothing to render, you can afford to show far more of it. Features that were cut on performance grounds come back onto the table. Doing this work early does not just protect the frame budget. It widens what the game is allowed to be.

The project

Grand Strategy Climate Game

Hearts of Iron, except the enemy is warming

Read the case study

More notes

Bring us the hard part

Frame budgets that will not hold. Netcode that falls over at scale. Latency you cannot find. That is the work we want.