This week I'll talk about slow performance and how we deal with it.
Suppose at some point during game development you're playing the game and it starts running slow, big frame drops. The first thing you should pay attention to is what you did to reach this point. Then try to reproduce it. Sometimes it's a freak incidence and you won't be able to reproduce it as it may not be a problem with your game but rather with windows or the game development program (luckily these occurrences are rare). Ok, so you've go a reproducible moment in which the game starts running slow. Now what?
First diagnose! To determine the source of the problem you can:
- Go through the latest changes that have been made and assess whether these might be the source of the problem. In some cases you won't be able to see anything that should lead to this problem. That's because your changes usually have side effects and so the performance drop might occur somewhere else in the code. It can also happen that this problem was actually always there but has never been noticed before.
- Use a profiler. Unity for example has a handy built-in profiler that allows you to see how much time is spend in what areas.
- If you don't have a profiler, you can also use time to measure how much time is taken for certain functions.
- Comment pieces of code until it is running smoothly again. From there you can usually check the commented code and find the problem.
- Debug using breakpoints. This allows you to go through the code at run-time step by step allowing you to see what exactly is happening. I usually consider this to be a last resort and I barely ever have to use it. It may however prove handy when debugging complex code.
|The Unity profiler, showing you how much time is spent in each area. (Click to enlarge)|
Now solve it! So you've found the source of the problem, what you can do now:
- It may be inefficient coding. For instance looking up objects in the scene every frame when you can just as well look it up once and store a reference to the object. So optimize!
- If you cannot optimize anymore, you could consider faking the effect you're trying to achieve. Many games fake a lot of effects and it's not even noticeable for most players.
- If you cannot optimize anymore, you can use a different calculation that approximates the effect. While less accurate it may still prove acceptable.
- If you've exhausted all possible options, it may be that what you're trying to achieve is simply not possible. The game design may have to be altered, but this is usually a last resort. Most game designers usually have a fair understanding (or at least should have) of what is possible and what is not. Also most programmers will pick up on computational complexity when reading the game design and discuss it.
As an example I recently had a problem with performance in which the game started running slow when there were too many enemies of a certain type. I got to the point where the game started running slow and opened the unity profiler (as seen above). Here I quickly noticed that 'ParticleSystem.Update' was taken way too much time per frame (over a 100ms). At the same time I noticed how many particles where active in the scene (see image below). This is usually not so much of a problem for Unity, except that each of these particles had collision with the rest of the world which is quite expensive and unnecessary! The problems really became noticeable when many enemies were throwing these projectiles with particles on them. Artists tend to look at what's cool and so much of how cpu or gpu heavy it is. So in this case the problem was quickly fixed by disabling particle collision. Unfortunately not all performance issues are this easy to solve ;)
|The particles on these cookies were causing slow performance as each particle had collision on objects.|