Skip to main content
skill Claude Code CX Codex Cursor GitHub Copilot

performance-optimization · gamedev-skills — Claude Code skill: finding the bottleneck

A skill that turns “the game runs slow” into a measured bottleneck and a specific fix: profile first, then pool objects, batch draw calls, cut allocations.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill performance-optimization -a claude-code
Open on GitHub

What performance-optimization does

The skill lays out a loop for performance work: measure in the engine profiler, fix the single largest cost, measure again on the same scene and hardware. It stays engine-neutral, so the same steps apply in Godot, Unity and Unreal. Inside is the workflow itself, a walk through frame-budget math, and fixes such as object pooling and draw-call reduction.

Each engine gets its own pointer. In Godot that means the Profiler, Visual Profiler and Monitors tabs plus Performance.get_monitor calls; in Unity the Profiler window with the Frame Debugger; in Unreal stat unit and stat scenerendering. Simulation cost is handed off to the neighbouring physics-tuning skill, while renderer settings and export stay with the engine skills.

Two conditions decide whether the loop lands. You need a reproducible worst-case scene, since a hitch you cannot trigger cannot be measured. Profiling a release build matters too, because editor and debug builds skew the CPU and GPU split. The rule the author keeps coming back to is blunt: do not optimize code you have not measured.

What it helps with

  • pin down what actually eats the frame in a given scene
  • remove garbage-collection hitches in C#
  • reuse bullets and particles through an object pool
  • cut draw calls on a scene full of overlapping sprites
  • set frame and asset budgets so gains do not slip back

Example prompts for the agent

  • FPS drops during the boss fight — profile it and tell me whether CPU or GPU is the bottleneck.
  • Move bullets and particles onto an object pool and measure the frame before and after.
  • Add per-subsystem budgets and a draw-call ceiling to the verification step.

How to install performance-optimization

1Skills CLI (Vercel)

npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill performance-optimization -a claude-code

2Manually: put the files in place

~/.claude/skills/performance-optimization/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/performance-optimization/

From the same set40

The whole set →
game-feel gamedev-skills Teaches the agent to add feedback to game actions: camera shake, hit-stop, eased tweens, squash and stretch, knockback. For mechanics that work but feel weightless. Claude Code CX Codex Cursor +1 9,400installs game-ui-ux gamedev-skills Engine-neutral game UI architecture skill for responsive layouts, screen stacks, gamepad focus, and event-driven HUD updates. Claude Code CX Codex Cursor +1 9,200installs level-design gamedev-skills Plans playable game levels from blockout through playtesting, covering routes, pacing, gates and encounters. Use it when working on whiteboxes, critical paths or room flow. Claude Code CX Codex Cursor +1 7,500installs camera-systems gamedev-skills Engine-neutral patterns for 2D and 3D game cameras: smooth follow, deadzones, look-ahead, bounds clamping, and third-person collision. Claude Code CX Codex Cursor +1 7,100installs audio-design gamedev-skills A skill that treats game audio as a mixer graph: buses, gain in decibels, sidechain ducking, adaptive music and beat-synced events. Samples use Godot 4.7, Unity gets notes. Claude Code CX Codex Cursor +1 7,100installs game-ai gamedev-skills Designs NPC decision-making, behavior trees, steering forces, and A* pathfinding. Useful when building game enemy logic across engines. Claude Code CX Codex Cursor +1 7,100installs input-systems gamedev-skills Engine-neutral input system: map keys to named actions, rebinding with conflict detection, keyboard, gamepad and touch support, analog deadzones, input buffering and coyote time. Claude Code CX Codex Cursor +1 6,800installs procedural-gen gamedev-skills Generates levels and loot tables using deterministic seeded algorithms. Useful for building procedural game content reproducible from a seed. Claude Code CX Codex Cursor +1 6,800installs

Other versions of performance-optimization

Similar

curves-and-paths phaserjs Skill for working with curves, splines, Bezier paths, and path followers in Phaser 4. Draw paths, sample points along them, and animate sprites along trajectories. Claude Code CX Codex Cursor +1 750installs v3-to-v4-migration phaserjs Guides migration from Phaser 3 to Phaser 4. Explains renderer architecture changes, unified filters, and tint system updates. Claude Code CX Codex Cursor +1 711installs unity-developer rmyndharis Skill for building games on Unity 6 LTS with performance optimization, rendering pipeline setup, and cross-platform deployment. Writes C# code, configures URP/HDRP, and solves physics and asset management issues. Claude Code CX Codex Cursor +1 3,000installs orbit-card heygen-com Adds a 10-second 1920×1080 HyperFrames motion block where a single feature card orbits a dot sphere using exported Blender camera paths. Claude Code CX Codex Cursor +1 9,800installs sdf earthtojake This skill authors and validates SDFormat files for models and worlds, then helps prepare them for simulator handoff. Claude Code CX Codex Cursor +1 10,500installs urdf earthtojake This skill helps create, validate, and debug URDF robot descriptions. Use it when working with links, joints, geometry, meshes, or inertial data. Claude Code CX Codex Cursor +1 10,400installs hatch-pet official openai Creates and packages animated pets and spritesheets for Codex. Use it to turn a character concept, reference image, or brand cues into a pet. Claude Code CX Codex Cursor +1 3,300installs gcode earthtojake Slices STL, 3MF, and OBJ models into printer-ready G-code through OrcaSlicer. Use it when you need a print file without connecting to the printer. Claude Code CX Codex Cursor +1 9,500installs

Questions about performance-optimization

How do I install performance-optimization in Claude Code?

Run npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill performance-optimization -a claude-code. The skill lands in ~/.claude/skills/performance-optimization/SKILL.md.

What does performance-optimization do?

It walks from measurement to fix: read the frame in the profiler, find whether CPU or GPU is the bottleneck, repair the biggest cost, then re-measure on the same scene. Pooling, batching and allocation control come as the shared fixes.

How is it different from physics-tuning?

physics-tuning covers physics jitter, tunneling and timestep. This one is the cross-engine method for reading a frame and fixing render or logic cost.

Source text

SKILL.md · Apache-2.0
---
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)

```text
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)

```text
Godot 4.7     : Debugger ▸ Profiler (script/physics time), Visual Profiler (CPU vs GPU render time
                per pass) and Monitors tab (FPS, draw calls, memory).
                In code: Performance.get_monitor(Performance.TIME_PROCESS) returns SECONDS
                (× 1000 for ms); Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME for draw calls.
Unity 6.3 LTS : Profiler window (CPU/GPU/Memory/Rendering modules) + Frame Debugger for draw calls.
                In code: ProfilerRecorder on "CPU Main Thread Frame Time" / "GPU Frame Time"
                (release players need Frame Timing Stats enabled in Player Settings).
Unreal 5.8    : `stat unit` (Frame / Game / Draw / RHIT / GPU ms), `stat fps`,
                `stat scenerendering` (draw calls); Unreal Insights for deep traces.
# Read the split: Game = gameplay thread, Draw = render thread (both CPU), GPU = the graphics card.
# Whichever is closest to Frame is the bottleneck; that decides the fix.
```

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

```gdscript
# 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[Node2D] = []                     # Node3D for 3D; both have `visible`
func acquire() -> Node2D:
    var n: Node2D = _pool.pop_back() if not _pool.is_empty() else bullet_scene.instantiate()
    n.set_process(true); n.visible = true
    return n
func release(n: Node2D) -> 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)

```text
Draw calls and render-state changes (material/shader/texture/blend switches) cost CPU submit time;
thousands of them make the render thread the bottleneck. 2D batchers merge runs of sprites that
share state (most bind several textures per batch), so ordering and atlasing decide the count.
- Atlas textures and share materials so sprites/meshes batch into one call.
- Identical meshes → GPU instancing (Unity; under URP/HDRP the SRP Batcher or GPU Resident Drawer
  takes precedence), MultiMesh / MultiMeshInstance (Godot), Instanced Static Mesh (Unreal).
- Static geometry → static batching / baking; mark non-moving objects static.
- Reduce overdraw: limit large overlapping transparent/particle layers (they re-shade pixels).
- Fewer real-time lights/shadows; bake lighting where it doesn't move.
Measure draw calls before and after — the count should drop, and so should GPU frame time.
```

### 5. Kill per-frame allocations (GC spikes = stutter)

```csharp
// Unity 6.3 LTS (C#). Allocating every frame fills the managed heap; the GC then stalls a frame.
// WRONG (new array + scene walk every call):
//   foreach (var e in FindObjectsByType<Enemy>(FindObjectsSortMode.None)) ...  // + LINQ, new[]
// (FindObjectsOfType is obsolete in Unity 6.3; its replacement still allocates.)
// RIGHT: cache references once, reuse buffers, avoid LINQ/boxing in Update.
void Update() {
    _hits = Physics.RaycastNonAlloc(ray, _hitBuffer);   // reuse a preallocated array
    for (int i = 0; i < _hits; i++) { /* ... */ }       // no per-frame allocation
}   // hit order is undefined and a full buffer may miss the nearest hit: size it, sort if needed
// Godot/GDScript: avoid building new arrays/dictionaries every frame in _process; reuse them.
```

## Pitfalls

- **Optimizing without profiling.** The intuitive culprit is usually wrong. Measure first, every
  time.
- **Profiling the editor / a debug build.** Editor overhead and unoptimized code mislead. Profile
  a release build on target hardware for real numbers.
- **Fixing the wrong side.** Micro-optimizing CPU code when the GPU is the bottleneck (or vice
  versa) changes nothing. Check the CPU-vs-GPU split first.
- **Micro-optimizing over algorithm.** Shaving a function when an O(n²) loop or a per-frame
  full-scene query is the real cost. Reduce the work, don't polish it.
- **Instantiate/free in hot loops.** Spawning and destroying bullets/particles every frame causes
  fragmentation and GC spikes. Pool them.
- **Per-frame allocations / LINQ / boxing in `Update`** (C#) feed the GC → periodic hitches.
  Cache and reuse.
- **Draw-call explosion** from unique materials and unbatched sprites/meshes. Atlas, share
  materials, instance, batch.
- **Unity "Enable GPU Instancing" with no effect** under URP/HDRP: the SRP Batcher takes
  precedence for compatible shaders. Check the Frame Debugger; for many identical meshes use the
  GPU Resident Drawer (Forward+, compute-capable APIs, not OpenGL ES).
- **Overdraw** from stacked transparents/particles/full-screen effects re-shading pixels.
- **No budgets.** Without per-subsystem ms and asset ceilings, performance silently regresses;
  enforce them in your build/CI checks.
- **Optimizing too early.** Don't contort a prototype for performance before it's fun or measured.

## References

- For per-engine profiler walkthroughs, the CPU-vs-GPU triage flowchart, a complete pooling
  manager, batching/instancing rules per engine, allocation/GC guidance, LOD/culling, and asset
  budgets (texture sizes, triangle counts, audio, mobile thermals), read
  `references/profiling-and-budgets.md`.

## Related skills

- `physics-tuning` — simulation cost, fixed-step budget, sleeping bodies, broadphase layers.
- `godot-export` — release/build settings that affect measured performance.
- `procedural-gen`, `game-ai` — common CPU hotspots (generation, pathfinding) to budget and defer.
- `roguelike`, `tower-defense`, `survival-crafting` — entity-heavy genres that need pooling/budgets.

© gamedev-skills · Apache-2.0 · gamedev-skills/awesome-gamedev-agent-skills

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor