makepad/examples/gamemaker/resources/template/CLAUDE.md
Admin 4cfb51877c PerfGraph: generic frame profiler widget + Cx perf monitor channels
platform: Cx.perf_monitor — per-frame ring (240) of paint-to-paint gap +
per-channel CPU us. Built-in channels: event dispatch (outermost, minus
app-attributed time), script exec, GC, pass encode, nextDrawable wait.
Apps register custom channels: cx.perf_monitor.channel("physics", rgb).
Off until enabled; hooks in event dispatch, macos repaint, metal draw_pass.

widgets: PerfGraph — corner-pinned live panel (DrawVector strips): frame-gap
bars colored against 120/60Hz budgets with guide lines, stacked per-channel
CPU, legend with averages. Self-positions bottom-right (DrawVector geometry
+ deferred turtle alignment don't mix — no aligning parent).

gamemaker: PerfGraph hovers the game pane (F3 toggles), engine feeds script
+ physics channels (incl. hot-reload evals); engine text overlay moved to
F4; per-phase engine window kept for ag perf / AIGAME_PERF=1; new 'ag perf'
harness verb + template guidance (template CLAUDE.md force-added: runtime
resource, blanket CLAUDE.md gitignore had kept it untracked).

Measured on my-game-5: engine frame CPU ~0.3ms; the hiccup is frame pacing —
the 8ms NSTimer paint clock beats against the 120Hz display, the drawable
pool drifts full and nextDrawable blocks the main thread in a ~25-frame
sawtooth (avg 2-3.4ms, spikes 20-30ms). The graph shows it as red ramps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 15:10:27 +02:00

55 lines
2.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# __PROJECT_NAME__ — a kid's game, live inside Makepad
A child asks for changes by voice through the Game Maker app; you make them by
editing **`game.splash`** — the whole game is that one file, a Makepad splash
script evaluated live. **Every clean edit hot-reloads the world the kid is
watching, instantly, while you keep working.** A broken edit never replaces the
running game — the last working world stays up and the error waits for you in
`./tools/ag errors`.
**The complete `game.*` API reference is in your system prompt** (the Splash
Game DSL Guide). Verbs not listed there do not exist. This file is the
project-local workflow.
## Checking your work — ALWAYS
1. After every edit run `./tools/ag errors`. Empty = your edit is live in front
of the kid. An error = the kid still sees the OLD world; fix it.
(Broken edits and runtime crashes are also reported back to you
automatically as a "⚠ game error" message — but `ag errors` after each edit
remains YOUR check; don't wait to be told.)
2. To playtest: `./tools/ag test 120 tools/tapes/selftest.json` restarts the
game, replays the frame-numbered input tape, and writes `.agent/sheet.png`
(a grid of frames over time) + `.agent/probe.txt` (pos/vel of probed tags
every 15 frames). **Read the image**, and read the numbers — "the jump
clears the step" should be a probe line you saw, not a hope.
3. `./tools/ag peek` = 4 screenshots of the live game + entity state, without
interrupting the kid.
4. `./tools/ag logs` tails the game log (your `game.log()` lines + eval reports).
5. If the game feels slow: `./tools/ag perf` — per-phase frame profile (script,
physics, draw). Keep script under ~2ms; if `wait` dominates, it's not your
game's fault, leave it be.
Tapes are JSON: `{"probe": ["player"], "events": [{"f":5,"press":"right"},
{"f":30,"press":"jump"},{"f":33,"release":"jump"}]}` — actions are the input
names (`left right up down jump shoot grab`). Same tape, same frames: runs are
repeatable.
## House style
- Everything is procedural: colored shapes and synthesized sound. No image,
model, or audio files — no files besides game.splash.
- Give creatures a face (`game.part` eyes) and a name (`game.label`), and give
actions sounds (`game.sfx`) — without being asked. That's what makes it real.
- Outdoor game? `game.sky({})` + `game.terrain({smooth: true, bands: [...]})`.
- Small, visible changes. Tune constants and add shapes; avoid big rewrites.
- Movers are ~0.8×1.6×0.8. Keep the playfield within the terrain you built.
## Gotchas
- **Hex colors containing the letter `e` need the `#x` prefix**: `#x2ecc71`.
- `let` and `fn` go at the TOP of the file, before other statements.
- The file re-runs from the top on each edit — don't accumulate state across
edits. `game.time()` restarts at 0 on every reload.
- `on_touch` fires every overlapping tick — latch or remove, or you'll play 60
win jingles a second.