DEVLOG #17 – OPTIMIZATION
[h2]Howdy, partners![/h2]
Every game starts rough. At first, we’re focused on gameplay and visuals, not performance. It’s all prototypes, heavy assets, wild ideas… and suddenly, it’s running at 15 FPS. Yep, we’ve been there too. But now we’re on a mission to hit 60.
We optimize two big areas: CPU, meaning game logic, collisions, movement, AI, and GPU, so everything visual.
Optimization means finding smarter ways to do things and cutting what’s too heavy.
[h3]Farewell, Nanite[/h3]
Early on, we were thrilled about Nanite, Unreal Engine 5’s fancy rendering tech that lets you use ultra-detailed models. But as our world filled up, problems piled on: stutters, memory spikes, performance dips... We ran a ton of tests and eventually accepted the truth: Nanite just wasn’t the right fit for our game.
So we cut it. Maybe we’ll get back to it in our next game? It worked wonders in Expedition 33, but our guess is that projects really need a Nanite-oriented approach from the get-go.

Nanite triangle visualisation of the main street in our town, Bravestand.
Anything black is not nanite – the colorful ones are. You can see how the triangles change when you get closer.
💡further reading: "What is Nanite?"
[h3]Draw Calls, LODs, and Distant Tree Drama[/h3]
In an open world, managing draw calls is crucial. Each one is a command to the GPU to render something. We fight the flood with mesh instancing, meaning 100 identical trees are grouped together under a single draw call, and HLODs (Hierarchical Level of Detail), which simplify faraway stuff into chunky geometry.
We also rely heavily on LODs — simpler versions of objects used at a distance. Auto-generated ones usually work, but Unreal struggles with things like trees, often dropping entire branches. Our artist is currently handcrafting tree LODs to fix that.

Visualisation of the changing LODs of the train tracks and nature around them.

Visualisation of the density of the triangles in certain spots.
💡further reading: "Polycount, Optimization and Draw Calls"
[h3]Lighting on a Leash[/h3]
We use fully dynamic lighting, which looks great but hits performance hard. Most games bake lighting (pre-render it), but we wanted a real-time sun, beautiful mornings, and picturesque sunsets.
To keep it manageable, we reduced light precision and added a graphics setting so players can choose how often the sun moves to best suit the might of their machines.

Visualisation of lighting of a scene, in this case the town of Bravestand from a different angle.
The orange blobs signify overlaps of light coming from different light sources, which is more costly performance-wise.
💡further reading: "Lighting the Environment"
[h3]CPU: Simpler Collisions, Smarter Code[/h3]
First target? Collisions. And by collisions, we don’t mean just bumping into stuff – this concept includes overlaps and big trigger volumes: checking if animals are in their homes and if NPCs are at a certain location.
We simplified them to spheres, capsules, and boxes – as little complex shapes as possible. Most moving objects either have no real collision, or we fake it. Why? Because checking for hits and overlaps constantly drains CPU.

Visualisation of the collisions of different objects at the Saloon in town.
The bottles, for example, have spherical collisions.
💡further reading: "How to Optimize Collision Performance"
[h3]Data Loads and Animal AI[/h3]
Our world runs on big databases for animals, plants, and buildings. And in the case of buildings, every single module is a separate entry, and some buildings have dozens of modules! Pulling data was slow, but our backend dev sprinkled some magic and sped things up — though it’s still a work in progress.
We’re also refining NPCs and animals, which are complex due to animation, AI, collisions, and skeletal meshes. For example, animals and characters have 5fps animations when you’re not looking. ;)
We keep tweaking their behavior logic to make them smarter and leaner.
To track what’s slowing us down, we use the Unreal Insights tool.

Our main investigation tool for diving deep into optimization issues – the Unreal Insights graph.
Every game starts rough. At first, we’re focused on gameplay and visuals, not performance. It’s all prototypes, heavy assets, wild ideas… and suddenly, it’s running at 15 FPS. Yep, we’ve been there too. But now we’re on a mission to hit 60.
We optimize two big areas: CPU, meaning game logic, collisions, movement, AI, and GPU, so everything visual.
Optimization means finding smarter ways to do things and cutting what’s too heavy.
[h3]Farewell, Nanite[/h3]
Early on, we were thrilled about Nanite, Unreal Engine 5’s fancy rendering tech that lets you use ultra-detailed models. But as our world filled up, problems piled on: stutters, memory spikes, performance dips... We ran a ton of tests and eventually accepted the truth: Nanite just wasn’t the right fit for our game.
So we cut it. Maybe we’ll get back to it in our next game? It worked wonders in Expedition 33, but our guess is that projects really need a Nanite-oriented approach from the get-go.

Nanite triangle visualisation of the main street in our town, Bravestand.
Anything black is not nanite – the colorful ones are. You can see how the triangles change when you get closer.
💡further reading: "What is Nanite?"
[h3]Draw Calls, LODs, and Distant Tree Drama[/h3]
In an open world, managing draw calls is crucial. Each one is a command to the GPU to render something. We fight the flood with mesh instancing, meaning 100 identical trees are grouped together under a single draw call, and HLODs (Hierarchical Level of Detail), which simplify faraway stuff into chunky geometry.
We also rely heavily on LODs — simpler versions of objects used at a distance. Auto-generated ones usually work, but Unreal struggles with things like trees, often dropping entire branches. Our artist is currently handcrafting tree LODs to fix that.

Visualisation of the changing LODs of the train tracks and nature around them.

Visualisation of the density of the triangles in certain spots.
💡further reading: "Polycount, Optimization and Draw Calls"
[h3]Lighting on a Leash[/h3]
We use fully dynamic lighting, which looks great but hits performance hard. Most games bake lighting (pre-render it), but we wanted a real-time sun, beautiful mornings, and picturesque sunsets.
To keep it manageable, we reduced light precision and added a graphics setting so players can choose how often the sun moves to best suit the might of their machines.

Visualisation of lighting of a scene, in this case the town of Bravestand from a different angle.
The orange blobs signify overlaps of light coming from different light sources, which is more costly performance-wise.
💡further reading: "Lighting the Environment"
[h3]CPU: Simpler Collisions, Smarter Code[/h3]
First target? Collisions. And by collisions, we don’t mean just bumping into stuff – this concept includes overlaps and big trigger volumes: checking if animals are in their homes and if NPCs are at a certain location.
We simplified them to spheres, capsules, and boxes – as little complex shapes as possible. Most moving objects either have no real collision, or we fake it. Why? Because checking for hits and overlaps constantly drains CPU.

Visualisation of the collisions of different objects at the Saloon in town.
The bottles, for example, have spherical collisions.
💡further reading: "How to Optimize Collision Performance"
[h3]Data Loads and Animal AI[/h3]
Our world runs on big databases for animals, plants, and buildings. And in the case of buildings, every single module is a separate entry, and some buildings have dozens of modules! Pulling data was slow, but our backend dev sprinkled some magic and sped things up — though it’s still a work in progress.
We’re also refining NPCs and animals, which are complex due to animation, AI, collisions, and skeletal meshes. For example, animals and characters have 5fps animations when you’re not looking. ;)
We keep tweaking their behavior logic to make them smarter and leaner.
To track what’s slowing us down, we use the Unreal Insights tool.

Our main investigation tool for diving deep into optimization issues – the Unreal Insights graph.