Skip to content
Development
Skill

/performance-optimization

Find and fix game performance problems methodically — measure with the engine profiler first, reason about the frame-time budget, locate the CPU-vs-GPU bottleneck, then apply the right fix: object pooling, draw-call batching, fewer allocations/GC spikes, and asset budgets.

From plugin
awesome-gamedev-agent-skills
45567 skills
Install
$ npx -y skills add gamedev-skills/awesome-gamedev-agent-skills --skill performance-optimization --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/performance-optimization

Context preview

The summary Claude sees to decide when to auto-load this skill.

Find and fix game performance problems methodically — measure with the engine profiler first, reason about the frame-time budget, locate the CPU-vs-GPU bottleneck, then apply the right fix: object pooling, draw-call batching, fewer allocations/GC spikes, and asset budgets.

SKILL.md

performance-optimization.SKILL.md
name: performance-optimization
description: >
  Find and fix game performance problems methodically — measure with the engine profiler first,
  reason about the frame-time budget, locate the CPU-vs-GPU bottleneck, then apply the right fix:
  object pooling, draw-call batching, fewer allocations/GC spikes, and asset budgets. Engine-
  neutral method that pairs with each engine's profiler. Use when the user mentions performance,
  optimize, low/dropping FPS, frame drops, stutter, lag, profiler, frame budget, draw calls,
  batching, garbage collection/GC spikes, object pooling, or "the game runs slow".

Performance optimization

Performance work is a measurement discipline, not a bag of tricks. The method is always the same: **profile → find the one bottleneck → fix that → measure again**. This skill teaches that loop and the highest-leverage fixes (pooling, batching, allocation control, asset budgets), and points you at each engine's profiler. It pairs with `physics-tuning` for simulation cost.

When to use

  • Use when the frame rate is low or uneven, the game stutters/hitches, or it must hit a target

(60 FPS desktop, 30/60 mobile) and currently doesn't.

  • Use to decide *what* to optimize: profile, read the frame budget, and identify whether the CPU

or GPU is the bottleneck before changing any code.

  • Use to apply specific fixes: object pooling, draw-call/batch reduction, removing per-frame

allocations and GC spikes, and setting asset budgets.

**When *not* to use:** for physics jitter/tunneling/timestep specifically, use `physics-tuning`. For the engine's concrete profiler UI and rendering settings, use that engine skill (`godot-export` covers some build settings; engine cores cover the rest). This skill is the cross-engine method and the shared fixes.

The golden rule: measure first, never guess

Most performance "fixes" applied without profiling target the wrong thing and add complexity for no gain. **Do not optimize code you have not measured.** Open the profiler, find the single biggest cost in a representative scene on representative hardware, and fix that. Re-measure to confirm the fix helped before moving on. Profile a **release/optimized build** where it matters — editor and debug builds lie (editor overhead, no compiler optimization).

Core workflow

1. **Define the target and reproduce.** State the goal (e.g. 60 FPS = 16.67 ms/frame) and find a repeatable worst-case scene. "Sometimes slow" is unfixable; a reproducible spike is fixable. 2. **Profile before touching code.** Run the engine profiler and read the frame: total frame time, and the split between CPU (game logic, physics, scripts) and GPU (rendering). 3. **Find the bottleneck — CPU or GPU.** If GPU time ≫ CPU, attack draw calls/overdraw/shaders/ resolution. If CPU time dominates, attack scripts/physics/allocations. Fixing the wrong side does nothing. 4. **Fix the single biggest cost.** Prefer an **algorithmic** win (do less work, cache, spatial partition, run less often) over micro-optimizing a hot line. Apply the matching shared fix (pooling, batching, allocation removal). 5. **Re-measure on the same scene/hardware.** Confirm the number moved. Keep or revert based on data, not intuition. 6. **Set budgets so it stays fixed.** Per-frame ms budgets per subsystem, plus asset budgets (texture sizes, triangle counts, draw-call ceilings); add a perf check to verification. 7. **Report measured numbers.** State before/after frame time, the bottleneck found, and the fix — never "should be faster". If you could only measure in-editor, say so.

Patterns

1. Frame budget math (turn "feels slow" into a number)

target FPS → frame budget:   60 FPS = 16.67 ms   |   30 FPS = 33.3 ms   |   120 FPS = 8.33 ms
The WHOLE frame (CPU sim + render submit + GPU) must fit the budget; the GPU runs in parallel,
so the slower of CPU-frame and GPU-frame sets your FPS. Allocate sub-budgets, e.g. @60 FPS:
  gameplay/scripts ~5 ms · physics ~3 ms · rendering(CPU submit) ~4 ms · UI/other ~2 ms · slack.
If one subsystem blows its slice, that's your target — not whatever you assumed.

2. Measure with the engine profiler (do this before any fix)

Godot 4.7 : Debugger ▸ Profiler (script/physics time) and Monitors tab (FPS, draw calls, memory).
            In code: Performance.get_monitor(Performance.TIME_PROCESS) and
            Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME).
Unity 6.3 LTS   : Profiler window (CPU/GPU/Memory/Rendering modules) + Frame Debugger for draw calls.
            In code: a ProfilerRecorder tracking "CPU Main Thread Frame Time" for a HUD/log.
Unreal 5  : `stat unit` (Frame/Game/Draw/GPU ms), `stat fps`, `stat scenerendering` (draw calls);
            Unreal Insights for deep traces.
# Read the split: is the Draw/GPU line the biggest, or the Game/CPU line? That decides the fix.

3. Object pooling (stop allocating/freeing in hot loops)

# Bullets, particles, enemies, damage numbers: reuse a fixed set instead of instantiate()/free()
# every frame — that thrashes memory and (in C#) feeds the GC.
var _pool: Array[Node] = []
func acquire() -> Node:
    var n: Node = _pool.pop_back() if not _pool.is_empty() else bullet_scene.instantiate()
    n.set_process(true); n.visible = true
    return n
func release(n: Node) -> void:
    n.set_process(false); n.visible = false       # disable + hide; DON'T free
    _pool.append(n)                                # back to the pool for reuse
# RIGHT: pre-warm the pool at load; reuse. WRONG: instantiate()/queue_free() per shot.

4. Cut draw calls (the most common GPU-side win)

Each unique material/texture/state change is roughly a draw call; thousands of them stall the GPU.
- Atlas textures and share materials so sprites/meshes batch into one call.
- Identical meshes → GPU instancing (Unity), MultiMesh / MultiMeshInstance (Godot), Instanced
  Static Mesh (Unreal).
Read more
Ships withawesome-gamedev-agent-skills

<img src="docs/assets/banner.png" width="820" alt="awesome-gamedev-agent-skills — game-dev skills for AI coding agents.

Get the whole plugin
Stats
458
Stars
36
Forks
Active
Maintenance
Python
Language
Apache-2.0
License
1d ago
Last commit
1mo ago
Created

Repo: gamedev-skills/awesome-gamedev-agent-skills