How does game “optimization” work? Are people sitting there changing lines of code to more “optimal” ones? What is “optimized”?

1.97K views

The recent The Last of Us for PC made me realize I had no idea what’s meant by “optimizing” a game.

Same with optifine in Minecraft improving performance. How do these things work to just make games use fewer resources?

In: 158

105 Answers

Anonymous 0 Comments

A lot of overcomplicated answers here…

Example:

I give you a box and ask you to deliver it to the house across the street. You can either A) just walk across the street with the box, or B) you can spend a bunch of time to find car keys, load the box into the car, drive the car across the street, and finally unload the box.

Option A is faster and easier to accomplish, because it’s just one box. Now imagine the same scenario but with ten boxes. Since you can load all ten boxes into the car at one time, option B becomes faster than walking across the street 10 times, even though option B is more complicated.

>Are people sitting there changing lines of code to more “optimal” ones?

In short: Yes

Programmers may start with poorly optimized code which is easy to write, and then later go back and make highly optimized code which is harder to write.

Anonymous 0 Comments

Say you have the computer place 10 circles on the screen.

Then you want to check if any overlap.

One way is to check the location of a circle and compare it to the nine others. That’s nine checks, then you have to do that whole thing a total of ten times, once for each circle. That’s now 90 checks.

The code for that would be mostly simple to write, but takes a longer time to execute.

It would be faster if we write some more code that cuts out any checks that have previously been done already. We can check if circle A overlaps with any of the other nine. But when we check circle B, we don’t check if that one overlaps with A because it’s already been checked before.

The first circle checks nine others, the second checks the remaining 8, the third checks the remaining 7…

It’s slightly more complex code, but reduces the number of checks down to 45 instead of 90. Slightly more optimized.

Now, we can write even more code to cut out checks for circles that are clearly too far away, and prevent checking things twice.

It takes some setup, but we can list the circles in order based on their distance from an orgin point.

We start with the closest circle and start checking the list in order. Eventually we find a circle far enough from the orgin that we know the rest are too far away to overlap. So circle A might only have to check 3 circles for an overlap then stop because the rest of the circles in the list are futher and too far away.

Circle B might only have to check the next 3 or 4 in the list. Same with circle C and so forth…

Something like that might result in only 25 checks, which is slightly faster than doing 45 checks.

This isn’t exactly what programmers are usually doing when they optimize code, but I think it’s okay enough for a ELI5 answer.

In reality, they’re probably doing more with figuring out how to maximize performance of hardware and write code to take advantage of individual operations.

Anonymous 0 Comments

It really depends on the game/engine and how it is designed from a technical perspective. Most game engines have something like a profiler (you can just google unity profiler to see an image of what it looks like). While you are running your game in the editor you can use the profiler and it will show how many ms different operations take. That includes executing all the code for gameplay, as well as drawing everything on the screen.

For 3d games usually the most common optimizations come from limiting complex draw calls. [This blog has a really good breakdown](http://simonschreibt.de/gat/renderhell/) of how the graphics pipeline typically works. But basically each draw call is sending data to the GPU and saying “hey I need you to render all this stuff”. The goal is to minimize the number of draw calls you need while still maintaining the visual fidelity and stability of the game.

Some of the most common and easy performance boosts come from culling, basically cutting down what you want the GPU to do to the bare minimum. There are 3 super common types of culling that almost every game uses (unless they are poorly made tbh).

The first and most obvious one is view-frustrum culling, it basically says “if an object is not within the view frame of the camera, do not send it to be rendered”. Most engines do this by default but some actually don’t and you have to make sure it’s enabled.

The second pretty obvious one is called backface culling, which says “if a mesh has faces that are on the back side of the object don’t render them”. There are a few cases where you actually don’t want backface culling for certain special effects (think like xray effects) but for the most part this is another one that almost every game uses.

The last one is a lot more complicated and can be implemented A LOT of different ways, and that’s occlusion culling. Occlusion culling basically says “there is an object blocking this other object, so don’t render it”. That sounds simple in practice but the actual process of doing that can be fairly complicated. Doing it on a per-pixel basis is extremely inefficient and acutally causes more overhead a lot of the time. I mainly have experience with unity, and other engines do things differently, but in unity typically what you do is create an occlusion map, which is basically a voxelized representation of the scene (think turning objects into different sized cubes instead of their normal shape). When the camera looks out into the scene it will cast rays and see what parts of the baked occlusion it collides with. If it collides with one of the occlusion voxels it will basically tell the GPU “OK this space is blocked so anything directly behind it do not render”. It’s a little more complicated than that because you essentially have to tell the engine how small of a gap between those voxels is ok, and what isnt. This is a bit of a balancing act because if your occlusion is too dense it will not run optimized, but if its too sparse you will get things like objects disappearing behind gaps in stair cases for example. With unity occlusion culling applies to an entire mesh, not just certain polygons, other engines work differently, but if you’ve ever played a game where sometimes you look through a narrow gap at a certain angle and objects behind the gap disappear that is occlusion culling happening, just not tuned perfectly.

Occlusion culling gets even more advanced with things called portals, which typically deal with more dynamic spaces and gaps. For instance you might have doorways in your game, and you obviously don’t want to render what is behind the door, but as soon as the door opens you don’t want to see stuff popping in as it slides open. So typically stuff like that is flagged as an occlusion portal, where it can essentially be toggled on and off in the code based on a number of different things.

It’s also not uncommon to have custom occlusion coding set up for smaller objects in games, where they might fade in as you get close enough even though they would technically be visible from further away. Part of optimizing this can also come from “baking meshes” where you take multiple small objects and essentially bake them down into one large object that only contributes once to the draw call instead of a dozen times.

All of this is just scratching the surface of the basics of rendering. There is a lot of other stuff that is done for optimization. A big one is mixed baked/realtime lighting with light probes vs full realtime global illumination (this is the reason why in a game like Warzone for example, the night time map and the day time map are two completely separate files each weighing in at nearly 40gb, because the engine does not use full realtime global illumination, and lightmaps are BIG but efficient and look good). LOD’s are another huge one (level of detail). Especially in big open world games you might have 2-4 different versions of an object. The lowest level is what displays when the camera is right next to the object, and the highest level is what you are looking at from across the map. In some games the highest level LODs go from 3d objects to just flat 2d images of the object. RDR2 has some of the best implementations of distant objects in a recent game to me, and they have a fairly advanced system for fading between LODs so that you never really see the pop-in between different LODs.

I could go on, but yeah i think you get the picture. Shadows are another big one, limiting the number of shadows, which objects get shadows, what lights actually cast shadows, how far away the shadows are drawn. And all this is basically just on the rendering side, this isn’t even touching the optimizing “code” or game logic part of it. At least from almost all the projects i’ve worked on the main optimization comes from graphics optimization and reduction of draw calls. Only really complex games or big multiplayer games need a lot of coding optimization on modern machines (take that with a grain of salt, just speaking from my experience).

edit: just realized this is ELI5 not r/gamedev lmao

Anonymous 0 Comments

A lot of overcomplicated answers here…

Example:

I give you a box and ask you to deliver it to the house across the street. You can either A) just walk across the street with the box, or B) you can spend a bunch of time to find car keys, load the box into the car, drive the car across the street, and finally unload the box.

Option A is faster and easier to accomplish, because it’s just one box. Now imagine the same scenario but with ten boxes. Since you can load all ten boxes into the car at one time, option B becomes faster than walking across the street 10 times, even though option B is more complicated.

>Are people sitting there changing lines of code to more “optimal” ones?

In short: Yes

Programmers may start with poorly optimized code which is easy to write, and then later go back and make highly optimized code which is harder to write.

Anonymous 0 Comments

A well documented article about someone actually doing the hard work outside of the dev team itself:

https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times-by-70/

Anonymous 0 Comments

>Are people sitting there changing lines of code to more “optimal” ones?

in eli5: yes, they replace one way of doing things with a more opptimal one

there are many ways you can optimize games, like replacing how you store, process and access data, removing/remodeling procedures which slow down (bottleneck) the rest of your code, redesign processes so you can distribute it across multiple threads

Anonymous 0 Comments

It really depends on the game/engine and how it is designed from a technical perspective. Most game engines have something like a profiler (you can just google unity profiler to see an image of what it looks like). While you are running your game in the editor you can use the profiler and it will show how many ms different operations take. That includes executing all the code for gameplay, as well as drawing everything on the screen.

For 3d games usually the most common optimizations come from limiting complex draw calls. [This blog has a really good breakdown](http://simonschreibt.de/gat/renderhell/) of how the graphics pipeline typically works. But basically each draw call is sending data to the GPU and saying “hey I need you to render all this stuff”. The goal is to minimize the number of draw calls you need while still maintaining the visual fidelity and stability of the game.

Some of the most common and easy performance boosts come from culling, basically cutting down what you want the GPU to do to the bare minimum. There are 3 super common types of culling that almost every game uses (unless they are poorly made tbh).

The first and most obvious one is view-frustrum culling, it basically says “if an object is not within the view frame of the camera, do not send it to be rendered”. Most engines do this by default but some actually don’t and you have to make sure it’s enabled.

The second pretty obvious one is called backface culling, which says “if a mesh has faces that are on the back side of the object don’t render them”. There are a few cases where you actually don’t want backface culling for certain special effects (think like xray effects) but for the most part this is another one that almost every game uses.

The last one is a lot more complicated and can be implemented A LOT of different ways, and that’s occlusion culling. Occlusion culling basically says “there is an object blocking this other object, so don’t render it”. That sounds simple in practice but the actual process of doing that can be fairly complicated. Doing it on a per-pixel basis is extremely inefficient and acutally causes more overhead a lot of the time. I mainly have experience with unity, and other engines do things differently, but in unity typically what you do is create an occlusion map, which is basically a voxelized representation of the scene (think turning objects into different sized cubes instead of their normal shape). When the camera looks out into the scene it will cast rays and see what parts of the baked occlusion it collides with. If it collides with one of the occlusion voxels it will basically tell the GPU “OK this space is blocked so anything directly behind it do not render”. It’s a little more complicated than that because you essentially have to tell the engine how small of a gap between those voxels is ok, and what isnt. This is a bit of a balancing act because if your occlusion is too dense it will not run optimized, but if its too sparse you will get things like objects disappearing behind gaps in stair cases for example. With unity occlusion culling applies to an entire mesh, not just certain polygons, other engines work differently, but if you’ve ever played a game where sometimes you look through a narrow gap at a certain angle and objects behind the gap disappear that is occlusion culling happening, just not tuned perfectly.

Occlusion culling gets even more advanced with things called portals, which typically deal with more dynamic spaces and gaps. For instance you might have doorways in your game, and you obviously don’t want to render what is behind the door, but as soon as the door opens you don’t want to see stuff popping in as it slides open. So typically stuff like that is flagged as an occlusion portal, where it can essentially be toggled on and off in the code based on a number of different things.

It’s also not uncommon to have custom occlusion coding set up for smaller objects in games, where they might fade in as you get close enough even though they would technically be visible from further away. Part of optimizing this can also come from “baking meshes” where you take multiple small objects and essentially bake them down into one large object that only contributes once to the draw call instead of a dozen times.

All of this is just scratching the surface of the basics of rendering. There is a lot of other stuff that is done for optimization. A big one is mixed baked/realtime lighting with light probes vs full realtime global illumination (this is the reason why in a game like Warzone for example, the night time map and the day time map are two completely separate files each weighing in at nearly 40gb, because the engine does not use full realtime global illumination, and lightmaps are BIG but efficient and look good). LOD’s are another huge one (level of detail). Especially in big open world games you might have 2-4 different versions of an object. The lowest level is what displays when the camera is right next to the object, and the highest level is what you are looking at from across the map. In some games the highest level LODs go from 3d objects to just flat 2d images of the object. RDR2 has some of the best implementations of distant objects in a recent game to me, and they have a fairly advanced system for fading between LODs so that you never really see the pop-in between different LODs.

I could go on, but yeah i think you get the picture. Shadows are another big one, limiting the number of shadows, which objects get shadows, what lights actually cast shadows, how far away the shadows are drawn. And all this is basically just on the rendering side, this isn’t even touching the optimizing “code” or game logic part of it. At least from almost all the projects i’ve worked on the main optimization comes from graphics optimization and reduction of draw calls. Only really complex games or big multiplayer games need a lot of coding optimization on modern machines (take that with a grain of salt, just speaking from my experience).

edit: just realized this is ELI5 not r/gamedev lmao

Anonymous 0 Comments

It really depends on the game/engine and how it is designed from a technical perspective. Most game engines have something like a profiler (you can just google unity profiler to see an image of what it looks like). While you are running your game in the editor you can use the profiler and it will show how many ms different operations take. That includes executing all the code for gameplay, as well as drawing everything on the screen.

For 3d games usually the most common optimizations come from limiting complex draw calls. [This blog has a really good breakdown](http://simonschreibt.de/gat/renderhell/) of how the graphics pipeline typically works. But basically each draw call is sending data to the GPU and saying “hey I need you to render all this stuff”. The goal is to minimize the number of draw calls you need while still maintaining the visual fidelity and stability of the game.

Some of the most common and easy performance boosts come from culling, basically cutting down what you want the GPU to do to the bare minimum. There are 3 super common types of culling that almost every game uses (unless they are poorly made tbh).

The first and most obvious one is view-frustrum culling, it basically says “if an object is not within the view frame of the camera, do not send it to be rendered”. Most engines do this by default but some actually don’t and you have to make sure it’s enabled.

The second pretty obvious one is called backface culling, which says “if a mesh has faces that are on the back side of the object don’t render them”. There are a few cases where you actually don’t want backface culling for certain special effects (think like xray effects) but for the most part this is another one that almost every game uses.

The last one is a lot more complicated and can be implemented A LOT of different ways, and that’s occlusion culling. Occlusion culling basically says “there is an object blocking this other object, so don’t render it”. That sounds simple in practice but the actual process of doing that can be fairly complicated. Doing it on a per-pixel basis is extremely inefficient and acutally causes more overhead a lot of the time. I mainly have experience with unity, and other engines do things differently, but in unity typically what you do is create an occlusion map, which is basically a voxelized representation of the scene (think turning objects into different sized cubes instead of their normal shape). When the camera looks out into the scene it will cast rays and see what parts of the baked occlusion it collides with. If it collides with one of the occlusion voxels it will basically tell the GPU “OK this space is blocked so anything directly behind it do not render”. It’s a little more complicated than that because you essentially have to tell the engine how small of a gap between those voxels is ok, and what isnt. This is a bit of a balancing act because if your occlusion is too dense it will not run optimized, but if its too sparse you will get things like objects disappearing behind gaps in stair cases for example. With unity occlusion culling applies to an entire mesh, not just certain polygons, other engines work differently, but if you’ve ever played a game where sometimes you look through a narrow gap at a certain angle and objects behind the gap disappear that is occlusion culling happening, just not tuned perfectly.

Occlusion culling gets even more advanced with things called portals, which typically deal with more dynamic spaces and gaps. For instance you might have doorways in your game, and you obviously don’t want to render what is behind the door, but as soon as the door opens you don’t want to see stuff popping in as it slides open. So typically stuff like that is flagged as an occlusion portal, where it can essentially be toggled on and off in the code based on a number of different things.

It’s also not uncommon to have custom occlusion coding set up for smaller objects in games, where they might fade in as you get close enough even though they would technically be visible from further away. Part of optimizing this can also come from “baking meshes” where you take multiple small objects and essentially bake them down into one large object that only contributes once to the draw call instead of a dozen times.

All of this is just scratching the surface of the basics of rendering. There is a lot of other stuff that is done for optimization. A big one is mixed baked/realtime lighting with light probes vs full realtime global illumination (this is the reason why in a game like Warzone for example, the night time map and the day time map are two completely separate files each weighing in at nearly 40gb, because the engine does not use full realtime global illumination, and lightmaps are BIG but efficient and look good). LOD’s are another huge one (level of detail). Especially in big open world games you might have 2-4 different versions of an object. The lowest level is what displays when the camera is right next to the object, and the highest level is what you are looking at from across the map. In some games the highest level LODs go from 3d objects to just flat 2d images of the object. RDR2 has some of the best implementations of distant objects in a recent game to me, and they have a fairly advanced system for fading between LODs so that you never really see the pop-in between different LODs.

I could go on, but yeah i think you get the picture. Shadows are another big one, limiting the number of shadows, which objects get shadows, what lights actually cast shadows, how far away the shadows are drawn. And all this is basically just on the rendering side, this isn’t even touching the optimizing “code” or game logic part of it. At least from almost all the projects i’ve worked on the main optimization comes from graphics optimization and reduction of draw calls. Only really complex games or big multiplayer games need a lot of coding optimization on modern machines (take that with a grain of salt, just speaking from my experience).

edit: just realized this is ELI5 not r/gamedev lmao

Anonymous 0 Comments

A well documented article about someone actually doing the hard work outside of the dev team itself:

https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times-by-70/

Anonymous 0 Comments

>Are people sitting there changing lines of code to more “optimal” ones?

in eli5: yes, they replace one way of doing things with a more opptimal one

there are many ways you can optimize games, like replacing how you store, process and access data, removing/remodeling procedures which slow down (bottleneck) the rest of your code, redesign processes so you can distribute it across multiple threads