Optimization... How does it work?

As I am rather new to the world of developing video games, I always tend to come across patches in beta/alpha games that read Increased Optimization or Performance Update or something similar to that. I have a decent understanding of what game optimization means (increasing performance/FPS), but what I don’t know about is the process developers go through to optimize their game.

Although each game is different, in general, how does a developer go about optimizing his or her game? What are some of the most commonly used methods of increasing performance?

Any comments are welcome! Thanks!

Look at the profiler and try to improve parts that use the most time.

–Eric

5 Likes

What Eric said. Find your bottlenecks and improve them. Optimization is highly dependent on the game itself.

2 Likes
  1. Cache transforms
  2. Make sure all moving colliders have a rigid body
  3. Turn of colliders when you can. If an object only collides with the player, only enable it when it’s in range of the player.
  4. Never use mesh colliders or default 2d polygon colliders. They are always overkill.
  5. Tweak the Fixed Update in the time options.
  6. Use object pools instead of instantiate or destroy. They’re not that hard and can make a HUGE difference.
  7. Culling.
  8. LOD.
  9. Watch out for loops.
  10. Don’t do a function everyframe if you don’t need to.
  11. Asynchronous loading. (loading on a seperate CPU core, rather than stopping the game until something is loaded causing a “chug”).
1 Like
  1. Only if it actually would make a difference; in most cases it won’t.
  2. Yes.
  3. Maybe; detecting range and disabling/enabling has overhead. Profile first, since it could make things worse.
  4. No, mesh colliders are typically used for static background geometry and can’t really be replaced with primitive colliders. Same for polygon colliders, but even more so since the box collider, for example, is really a polygon collider in the shape of a box. Also convex mesh colliders are relatively fast and are reasonable to use when it’s not feasible to use primitive colliders. Careful about using the words “never” and “always”.
  5. Maybe, if you’re using physics.
  6. Yes.
  7. Automatic, unless you’re talking about occlusion culling, in which case potentially yes, if your scene would actually benefit.
  8. Maybe; profile first, and it depends on whether you’re GPU- or CPU-bound. GPUs are fast at drawing lots of polygons so the overhead of LOD might outweigh just drawing stuff as-is.
    9-11) Yes.

–Eric

2 Likes

Doing a distance check and comparing it to a float seems much cheaper than checking a collider and you could do it every 10 frames, or whatever. The only exception would be if it’s a sphere collider since they’re essentially distance checks anyhow.

At any rate, I did this for my project and tripled my FPS. I’ve also recommended it to others and they say it helped them too.

Oh, I would make my own mesh rather than a primitive if need be. I meant in context of, say, a 10k poly mesh such as a car.

And I’m not sure what you mean by “static background geometry”? Do you mean objects that don’t move, such as cliff faces or buildings?

EDIT: I just re-read that and I sound really arogant. For the record Eric knows WAY more than me and I meant to be inquisitive, not chsllanging what he said.

Sometimes. PhysX uses some very clever tricks to reduce the cost of collider checking. And turning colliders on and of is not free.

Really? I thought that that would be really cheap.

My tips, in approximate order. Except for number one. Always profile first, last and in between. Each step gets more difficult, so you want to do the later steps on as little code as possible.

Note these tips are around code optimisation, and only make sense if that is your bottle neck.

  • Profile
  • Fix any obvious issues (methods called thousands of times a frame, methods allocating MB of garbage, single gram spikes)
  • Profile
  • Optimise your overall systems by junking anything thy doesn’t need to be in the game
  • Profile
  • Optimise expensive systems. (Reduce the tick frequency, change algorithms)
  • Profile
  • Optimise expensive algorithms. (Split processing over multiple frames, optimise data structures)
  • Profile
  • Optimise code (Remove expensive calls, inline functions, general micro optimisations)
  • Profile
  • Thread whatever is left (threading often doesn’t increase performance, but it can make the frame rate appear smoother)
  • Profile

Combine those tips with general not being dumb when you code and you should be fine.

Tips to not be dumb:

  • Cache components
  • Don’t throw away big data structures
  • Don’t do stuff in Update that doesn’t need to be done every frame
  • Think twice about frequently calling any method that’s called out for performance in the docs.
3 Likes

It really depends on the exact set up. That’s why profiling is so important. Distance checks can get expensive if you have a lot of objects and they are moving fast.

But it’s not a bad thing to try, just make sure it works. As @Eric5h5 mentioned, always and never are dangerous. Unity makes so many different types of games that there is seldom an optimisation strategy that works on all of them.

For an example check out the Unite video on Mushroom 11. Object pooling primitive colliders of various different sizes won’t make a difference to most games. But it was essential for Mushroom 11.

1 Like

Practically speaking it’s what people like Not_Sure, BoredMormon, and Eric5h5 are suggesting in terms of actual code and engine setup. Conceptually I like to think of it as when you’re signing your signature in cursive – then when you’re done most people go back and cross their T’s and dot their I’s. Optimization is basically like going back and crossing your T’s and dotting your I’s. In general, it’s usually about making your code cleaner, and your game run faster.

1 Like

For practical details, there is a dedicated book on this matter coming up next month, I don’t know what it will be worth but it could be interesting:

Use atlas textures and keep uniform scale so unity can actively batch to less draw calls.

3 Likes

Yup! Forgot that one.

I don’t know that I would call those “optimizations”, as you should be doing most of that stuff in the first place. They are just good practices.

^ This is optimization.

In addition, you can go back to assets/content/art to optimize, especially if spec has has changed since content was created. Sometimes it is easy to “over” create on the content during the early days. Going back and making sure that you don’t have extra geo/pixels. High frequency of keys in animations, unused animations, overly large textures, etc.

3 Likes

Thanks! Glad I got it right. Most of my optimisation comes from large scale chemical factories rather then code. In fact my current job is entirely about optimisation.

There is a term used a lot in process optimisation called ‘low hanging fruit’. It’s basically a reminder to focus on the easiest optimisations first. No point making a unit op 5% faster if you can just skip it altogether.

Understanding bottlenecks is also important. Improving a constrained unit op by 3% will give you more of a production boost then doubling the capacity of an under utilised asset.

Bottlenecks are also notorious for moving as you move through the optimisation process. Fortunately the profiling games in unity is cheap, you can profile after every optimisation step. I wish I could run a full scale profile of my factory in anything less then a month.

2 Likes

If your deep profiling picks up lots of Vector operations or methods that use them you can unroll these into inline calculations e.g.

VectorA = VectorB + VectorC;

Triggers a function call and can be unrolled to:

VectorA.x = VectorB.x + VectorC.x;
VectorA.y = VectorB.y + VectorC.y;
VectorA.z = VectorB.z + VectorC.z; // not needed for 2D

Note that a Vector, Matrix, Quaternion operations can all be candidates for this type of optimisation.

But also profile on the target hardware to compare performance, as at least WebGL is due to be enhanced with SIMD.js (Single Input Multiple Data) which could be used to speed up these operations within Unity.

2 Likes

This is one micro optimisation that can be super powerful in the right situations. It does make your code harder to read and maintain. I’ve used it a couple of times to squeeze more juice out of CFD.

But like most other micro optimisations if you aren’t doing a crazy heavy amount if calls it can be a waste of time.

Also remember that the profiler slows the code down and adds overhead, so you can get false positives (or should that be negatives) ensure you check the Self column vs the Time column. The Self column is the overhead the profiler adds.

Also make sure you use Deep and Normal Profiling as the Normal has less Self overhead and gives a better indicator of the problem areas. Deep allows you to dig further and helps you work out what is causing the bottleneck.

There are generally two categories of optimizations

  1. Avoiding the really bad things while building your game. There are some big, obvious no-no´s that you need to know and they should never make it into your game in the first place. For scripting this is things like putting unnecessary stuff in the update function or using findObject when there are better choices. For worldbuilding, stuff like not having a rigidbody on things you plan to move, havng unnecessary light sources etc.

  2. Profiling and finding problems during testing or near the end of your project - Maybe you have an area of your map that has FPS issues…

While you are building your game, you should always keep all these things in mind, but for the #2 issues, they are usually just small tweaks that you do not have to worry about UNTIL you have a problem. There is no need to micro-optimize parts of your game that do not cause issues while you are building the game. Wait til closer to the end to see if there is even a problem.

I´ll give you an example. Everyone says character models should be 10k tris or less as a ballpark figure. Let´s say I have a really awesome creature I want to put into my game that has 100k tris… way more than what is recommended. So by most people´s thinking I should probably have an artist redo the model and reduce the tris… and I should probably have LODs… right? Well what happens if in my game, that creature is inside of a big empty cave with only 1 light source, few particle effects and not much really going on. When I play my game with the 100k tri creature, I am easily getting 100fps while in that cave… and so if I had optimized, all I would have done is wasted time and money. i would have fixed a problem that didn´t exist.

As people have mentioned in this thread, there is usually some performance costs involved in some optimizations. In a way it is two steps forward, one step back. Plus there is just the issue of your time, optimization takes time… so don´t bother doing it unless you have a problem. I see a lot of people that do optimization stuff that isn´t needed… preventive medicine if you will… but that costs time and it is generally the least fun parts of making a game.

Most important. Learn the big no-no and never let them to get into your game. Then make your ga

3 Likes