In a fighting game, frame rate isn't a nice-to-have. Inputs, hitboxes and combos are all measured in frames, so a dropped frame can be the difference between a combo landing and a player throwing their controller. For Pixel Brawl, a locked 60 frames per second on handheld was a hard requirement from day one.
Measure before you fix
We started by building a stress-test scene: four players, the busiest stage and every effect firing at once. Then we profiled it on the real hardware, not in the editor. Most of our early assumptions about where time was going turned out to be wrong.
Where the time went
- Overdraw from layered transparent particles on the busiest stages
- Garbage collection spikes from small allocations during hit effects
- Too many draw calls from sprites that could have been batched
- Uneven frame pacing, even when the average frame time looked fine
What we did about it
We moved hit effects to pre-allocated pools so combat never allocates memory mid-fight. We packed sprites into atlases per stage so they batch together, and replaced some layered transparent effects with cheaper opaque versions that look almost identical at handheld resolution.
Frame pacing was the subtle one. A game can average 60 fps and still feel wrong if frames arrive unevenly. We locked the simulation to a fixed step and made sure rendering never got ahead of it, so every frame takes the same time.
Players never say "the frame pacing is great". They just say the game feels good. That's the goal.
Keeping it locked
Hitting 60 once is easy. Keeping it there for every patch is harder. The stress-test scene now runs automatically on every build, and if it misses budget, the build fails. That one change has saved us more time than any single optimisation.