Flukz — open-source shmup community resource open-source GPL devlog  ·  about
// indie shmup & game-dev resource

Game Programming · June 30, 2026

Frame Pacing and Performance Profiling in Shmups: Finding and Fixing Hitches

Average framerate is a misleading metric for shmup performance. A game that averages 60 fps but drops to 38 fps for six frames every time a large enemy explodes is not a 60 fps game in any sense that the player experiences. Those six frames of dropped frame time are exactly the moments when the player is reacting to the explosion and repositioning — the worst possible moment for visual stutter. Consistent frame pacing, measured as frame-time variance rather than average fps, is the metric that matters.

Understanding frame time vs framerate

A 60 fps target means 16.67ms per frame. Frame time is the duration of a single frame; framerate is derived from it. Frame pacing refers to how consistent the frame-time intervals are. Perfect 60 fps has every frame exactly 16.67ms. A game with poor pacing might deliver: 16ms, 17ms, 16ms, 34ms (dropped frame), 15ms, 16ms... and average 60 fps over a second despite the visible stutter during the 34ms frame.

The practical implication: monitor both framerate and frame time in your debug build. A sudden spike in frame time is a hitch, regardless of what the average fps shows. Aim to keep frame time variance below 3ms in normal gameplay, with a maximum allowed spike of 6–8ms during known expensive events (large explosions, wave spawns).

Where shmup hitches come from

Profiling a shmup typically reveals hitches in one of five categories:

Using the engine profiler

Most game engines include a built-in frame profiler. Godot's profiler shows per-function CPU time per frame. Unity's Profiler shows similar data. The workflow for finding hitches:

  1. Run a gameplay session that includes the worst-case scenario: a boss with multiple simultaneous attacks, a large explosion cluster, and a wave transition.
  2. Record the profiler session or enable frame-time logging to a file.
  3. Identify the frames with the highest frame time. In most profilers, these appear as tall spikes in the frame time timeline.
  4. Click into a spike frame and read the call tree. The function consuming the most time in that frame is the first target for optimization.
  5. Fix the highest-cost function, re-profile, and repeat until frame time spikes are within the acceptable window.

Budgeting explosions

Large boss explosions are guaranteed to be frame time expensive and unavoidable — they are spectacle moments the game needs. The correct approach is to budget them explicitly rather than trying to make them cheap.

Define an explosion budget per frame: maximum particles spawned this frame from all explosion sources combined. A particle spawn queue holds all pending explosion requests and draws from them at the budget cap each frame until the queue is empty. The explosion may take two or three frames to fully spawn all particles, but no single frame exceeds budget. The visual impact is identical at 60 fps; the stutter is eliminated.

Delta-time normalisation as a fallback

Even well-optimized shmups will occasionally drop frames on low-end hardware. Delta-time normalisation ensures that game logic advances by the correct amount of simulated time regardless of how long the frame actually took. All movement, timer, and physics updates are multiplied by the delta time since the last frame rather than assuming a fixed frame duration.

Delta-time normalisation does not fix frame stutter — the player will still see the stutter visually. What it prevents is gameplay consequences from the stutter: bullets teleporting, hitboxes skipping, timers advancing incorrectly. A game that maintains correct simulation across dropped frames is far more playable on target-minimum hardware than one that freezes and then lurches forward.

The one caveat: delta-time normalisation and fixed timestep physics are in tension. Physics simulations designed for fixed timestep (as recommended in the fixed timestep guide) should remain on fixed steps; delta-time normalisation applies to rendering and non-physics game logic only.