本文へ移動
cccskills
無料GitHub で公開

game-performance-budget

Use when touching anything that runs per frame, adding entities/effects at scale, or answering a stutter/frame-drop report - frame budgets per target FPS, per-system split, the profiler per engine, before/after numbers, and threshold tests.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md6.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Game Performance Budget

Overview

A game has a hard deadline every frame. Miss it and the player sees a hitch, whatever the average says. Performance work is therefore budgeting and measuring, not guessing: know the budget, measure before, change one thing, measure after, write both numbers down.

Core principle: No optimisation without a before and after measurement on the same scene, build type and machine. No hot-path change without proof it did not get slower.

The budget

TargetFrame budgetTypical for
30 FPS33.3 mslow-end mobile, some console cinematics
60 FPS16.67 msdefault for this agent unless the task or repo says otherwise
90 FPS11.1 msVR minimum
120 FPS8.33 mshigh-refresh displays, competitive games
144 FPS6.94 msPC competitive

Split it per system and leave headroom. An example 60 FPS CPU split (replace with the repository's own if it has one):

SystemBudget
Gameplay scripts3.0 ms
Physics2.0 ms
AI and pathfinding2.0 ms
Animation1.5 ms
Rendering (CPU submit)4.5 ms
UI1.0 ms
Audio0.5 ms
Headroom (OS, spikes, GC)2.17 ms

GPU time is a separate 16.67 ms; a frame is bound by whichever of CPU or GPU is slower. Memory gets a per-platform ceiling, and mobile adds thermal throttling: a game that holds 60 for two minutes and then drops is over budget.

Measure with the engine's tools

EngineFrame/CPUAllocations / memoryInstrument your code
UnityProfiler (CPU, Rendering, Physics modules), Profile Analyzer for before/afterProfiler GC Alloc column, Memory ProfilerProfilerMarker / using (marker.Auto()); Performance Testing package Measure.Method
GodotDebugger → Profiler, Visual Profiler, MonitorsMonitors: object/resource/node counts, static memoryPerformance.get_monitor(...), Time.get_ticks_usec() around a block
Unrealstat unit, stat game, stat gpu, Unreal Insights (-trace=cpu,frame,gpu)memreport -full, LLM (-llm)TRACE_CPUPROFILER_EVENT_SCOPE(Name), SCOPE_CYCLE_COUNTER
WebChrome Performance panel (Bottom-up), renderer.info (three.js), Babylon InspectorMemory panel heap snapshots before/after a scene changeperformance.mark / performance.measure
BevyFrameTimeDiagnosticsPlugin + LogDiagnosticsPlugin, Tracy via the trace_tracy featureTracy memoryinfo_span!("name").entered()

Profile a development build on the target class of device where you can; an editor profile carries editor overhead and a desktop GPU hides mobile limits. Headless Chromium renders WebGL in software — never judge frame time from it.

The before/after record

Put this in the closing message whenever a hot path changed:

Scene: Arena_Stress (200 enemies), dev build, M2 MacBook, 60 FPS target
                   before     after
frame median       14.1 ms    11.8 ms
frame p99          22.7 ms    13.9 ms
GC alloc / frame   3.2 KB     0 B
AI.Update          4.6 ms     2.1 ms   (path requests time-sliced, 8 per frame)

Median hides hitches — always report a high percentile (p95/p99) or the worst frame too. If you could not profile on this machine, say so and give the test-level number you did get.

Threshold tests

A performance test fails when the budget is exceeded, otherwise it is a log line nobody reads.

[Test]
public void StepAll_200Agents_StaysUnderTwoMs() {
    var grid = TestGrids.Arena64();
    var agents = TestAgents.Spawn(200, seed: 7);
    for (int i = 0; i < 5; i++) Pathfinder.StepAll(grid, agents, maxRequests: 8);
    var samples = new double[31];
    var sw = new System.Diagnostics.Stopwatch();
    for (int i = 0; i < samples.Length; i++) {
        sw.Restart(); Pathfinder.StepAll(grid, agents, maxRequests: 8); sw.Stop();
        samples[i] = sw.Elapsed.TotalMilliseconds;
    }
    Array.Sort(samples);
    Assert.That(samples[samples.Length / 2], Is.LessThan(2.0), "AI budget is 2 ms at 60 FPS");
}

The same shape works in every runner: warm up, take N samples, assert on the median (and a looser bound on the max). Where the repository uses a benchmark harness — Unity's Performance Testing package (Measure.Method), criterion in Rust, Vitest bench — record with it and keep the assertion. Keep thresholds generous enough for CI noise and tight enough to catch a 2× regression. Allocation tests are exact: zero means zero (unity-performance-and-gc).

Where frames usually go

  • Allocations and GC in per-frame code (rule no-alloc-in-hot-paths).
  • Draw calls / batches: too many materials, no atlas, no instancing, UI canvases rebuilt every frame.
  • Overdraw: stacked transparent particles and full-screen effects, worst on mobile.
  • Physics: mesh colliders on moving bodies, everything on one layer colliding with everything, continuous collision on objects that don't need it.
  • AI: pathfinding or perception for every agent every frame — time-slice it and run perception at 5–10 Hz.
  • Lookups: GetComponent, Find, get_node, TActorIterator per frame.
  • Hitches: shader compilation on first use (warm up / PSO caching), synchronous asset loads, a GC spike, a save on the main thread.
  • Idle work: off-screen or sleeping objects still ticking — Godot set_process(false) / VisibleOnScreenEnabler2D, Unity disabling components or CullingGroup, Unreal PrimaryActorTick.bCanEverTick = false and tick intervals, Bevy run conditions.

Procedure

  1. Name the budget and the scene that exercises the change.
  2. Measure before (median + p99 + allocations) and save the numbers.
  3. Change one thing.
  4. Measure after on the same scene, build type and machine.
  5. Keep the change only if it moved the number; add or update the threshold test.

Common Mistakes

  • Optimising what looks slow instead of what the profiler shows.
  • Reporting an average FPS instead of frame-time percentiles.
  • Profiling in the editor and generalising to a mobile build.
  • Micro-optimising a 0.05 ms function while a 6 ms one sits above it.

Red Flags

  • "Should be faster now" with no numbers.
  • A performance test with no assertion.
  • A hot-path diff with no before/after record in the closing message.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation

日本語の概要は準備中です。原文の説明を表示しています。

makifbaysal/tasktrooper1122026年10月11日 更新

makifbaysal のスキルをすべて見る

このスキルの問題を報告する