Posts Tagged ‘Optimization’

Hostile Hyper Jump – Optimized

Posted by
Tuesday, March 7th, 2017 2:23 pm

GIF!

Global highscores are in, the build is optimized and, so far, the bugs have been fixed!

There’s still time to partake in the Elympics.

Play it here!

Shape Struggle 1.1.0.6 post-compo: performance optimized

Posted by (twitter: @csanyk)
Tuesday, April 26th, 2016 7:50 pm

 

I’ve gone over the code for Shape Struggle, and optimized it for performance  On my machine, I can’t get it to drop frames in the latest post-compo build, 1.1.0.6.  The thing is, my laptop is pretty high-end (2.8GHz Xeon E3-1505M, 64GB RAM), so I’m not sure how well it runs on older machines… I need testers!

>>> Play and Rate Shape Struggle <<<

I figure my optimization tricks might help other developers, so in brief, here’s how I did it:

  1. Controller object:  I knew even before the compo ended that I needed to set up a controller object to optimize the performance of the up to 500 instances of oEnemy that I’d have active in the game.  But the code in the controller object from the 1.0 build was far from optimized.  I refactored and streamlined the code, eliminating redundant conditional checks, and pulling code out of loops to make them as tight as possible.

    I also pulled some Step event code out of the two most complex objects, oSquare an oPentagon, and put it into the controller object.  Doing so enabled me to write some of the code in the controller so that it runs once for all instances of oSquare and oPentagon, rather than once per instance.   This makes a huge difference in the amount of calculations necessary when there are hundreds of instances active.  No matter how many there are, there’s only one calculation performed.

  2. Simplified bullet object.  At maximum firepower, the player fires 5 bullets per shot, one shot every three steps.  At 60fps, that’s 100 bullets per second.  That’s 100 creation events per second.  I thought I should limit the number of bullets, and also I wanted to limit the range of the player’s weapon, so I put a timer in the bullet object that destroyed the bullet instance after 1 second.

    Potentially, I might have optimized this by implementing object pooling, so that rather than creating and destroying bullets, I would re-use the instances so I wouldn’t need to keep creating and destroying them.  But first, I tried removing the timer, and found that the game plays and feels exactly the same, so that timer code doesn’t matter.  Normally setting a variable and then decrementing it doesn’t take a lot of CPU.  But with up to 100 fewer creation events every second, and 100 fewer timers to decrement every step, it adds up.

    Object pooling might yield still more performance optimization, but simplifying the objects as much as possible first before making such efforts is smart.

  3. I also removed the collision check from the bullet object that checks for collisions with the wall, and put it in the wall. There’s only 8 wall instances, so 8 collision checks vs. up to 100 each step means a substantial savings in calculations.

Transformagician – Performance Optimization

Posted by
Saturday, April 23rd, 2016 3:16 am

The jam is over, the entry turned out great and the WebGL build (which most people are going to play) runs quite badly. What to do? Optimize!

Identifying the problem

When trying to improve performance you should always go for the elephant in the room. In most cases (including this one) taming the alpha male is enough. Run the profiler on the target build and see what is up (milliseconds) and what is down (framerate!). Let’s look at the rendering performance of the following scene.

Image 1: Benchmark scene

Figure 1: Rendering performance in Unity editor

Not bad! The deferred renderer does a pretty good job at batching drawcalls.

Figure 2: Rendering performance in WebGL build

Very bad! The WebGL build seems to fall back to forward rendering before a deferred lighting pass. Maybe this is why the batching is botched, I’m not quite sure, but there most certainly is a drawcall problem.

Solving the problem

One solution immediately springs to mind: Mesh.CombineMeshes. After some modifications the script works like a dream.

The walls in the scene are combined into a single mesh and the floors into another. As long as all the meshes share the same material there will be no trouble and the combined mesh looks just like a bunch of individual objects.

The only difference being a drastic reduction in draw calls. Let’s see just how drastic we’re talking about here:

Figure 3: Rendering performance in editor (with MeshCombine)

Mere three times faster… I think we can do better.

Figure 4: Rendering performance in WebGL build (with MeshCombine)

Fifteen times faster! I rest my case.

Conclusion

Use the profiler, identify the worst offender, smite it and rejoice. There are further optimization I could do, but why bother. At this point it’s already an effort in diminishing returns.

Getting less than 60 frames per second? Time to look in the mirror and get to work!

[cache: storing page]