Nine agent skills for building Makepad/Rust games, ported from majidmanzarpour/threejs-game-skills. Same director-routed workflow and premium bar; runtime rewritten for this fork's game crates. - makepad-game-director entrypoint, routing, continuity, asset probe - makepad-gameplay-systems loop, movers vs rigid bodies, input, camera, netplay - makepad-aaa-graphics-builder lighting, shaders, budget, visual scorecard - makepad-game-ui-designer HUD, menus, touch and XR UI - makepad-debug-profiler defect bisection and profiling - makepad-qa-release verification ladder, evidence, packaging - makepad-3d-generator CC0 model search, casts, procedural geometry - makepad-image-generator texgen textures, palettes, sky, icons - makepad-audio-generator sample bank, mixer, material impacts, 3D audio Written against the real APIs in libs/game/*, libs/sim and apps/arcade: the game.* verb table, GameRenderer adaptive quality, the packed 6-float GameMeshVertex layout, script_mod! splash styling, makepad-test driving, and the BUDGETS.md numbers. No paid generation API is required - the CC0 library plus seeded makepad-game-gen replaces them. Includes install.sh (Codex/Claude), validate-skills.sh and a repo-aware probe_assets.sh; both scripts verified against this checkout.
121 lines
5.9 KiB
Markdown
121 lines
5.9 KiB
Markdown
---
|
|
name: makepad-qa-release
|
|
description: "Verify and ship Makepad games: cargo check/test/clippy, makepad-test driven runs with real input and screenshots, headless probes, bot playtests, performance evidence against BUDGETS, cross-platform and XR checks, and packaging with makepad-game-pkg. Use for QA, testing, verification, evidence, regression, release build, packaging and 'is it actually working' requests."
|
|
---
|
|
|
|
# Makepad QA & Release
|
|
|
|
Turn claims into evidence. The deliverable of this skill is a report someone else can check.
|
|
|
|
## The ladder
|
|
|
|
Climb only as far as the change warrants; never skip a lower rung.
|
|
|
|
| # | Rung | Command | Proves |
|
|
| --- | --- | --- | --- |
|
|
| 1 | Compiles | `cargo check -p <crate>` | syntax and types. **Not** the splash DSL |
|
|
| 2 | Lints | `cargo clippy -p <crate>` | repo `clippy.toml` conventions |
|
|
| 3 | Unit | `cargo test -p <crate>` | rules, in Cx-free crates |
|
|
| 4 | Driven | `cargo test -p makepad-arcade` with `makepad-test` | the real app under real input |
|
|
| 5 | Seen | `app.screenshot()` | what it actually looks like |
|
|
| 6 | Measured | `frame_p90_ms()`, probe examples | it holds frame time |
|
|
| 7 | Shipped | `cargo build --release` | it builds for delivery |
|
|
|
|
Required by change size:
|
|
|
|
| Change | Rungs |
|
|
| --- | --- |
|
|
| Constant, copy, colour | 1 |
|
|
| Rule in a Cx-free crate | 1, 3 |
|
|
| New mechanic | 1, 3, 4 |
|
|
| Any UI or visual change | 1, 4, 5 |
|
|
| Performance work | 1, 6 (before **and** after) |
|
|
| Full game / premium pass | all, plus the scorecard |
|
|
|
|
**Rung 1 does not cover the splash DSL.** It resolves at runtime, so a style or widget error passes `cargo check` and fails on launch. Any UI change requires rung 4 at minimum.
|
|
|
|
## Unit testing
|
|
|
|
The architecture exists to make this possible — `sim`, `gen`, `blocks`, `audio`, `net`, `coedit`, `pkg`, `assets` need no `Cx`.
|
|
|
|
```bash
|
|
cargo test -p makepad-game-sim
|
|
cargo test -p makepad-game-gen
|
|
cargo test -p makepad-game-blocks
|
|
cargo test -p makepad-game-net
|
|
```
|
|
|
|
Assert on observable behaviour, not internals: the mover clears a 0.4 m step and not a 1.5 m wall; the lap counts once per crossing; the level generator's goal is reachable from its spawn; the seeded generator produces byte-identical output twice.
|
|
|
|
**Test compositions as compositions.** Two half-tests in two crates can both pass while the car floats above the road — which is why `blocks` dev-depends on `gen` and `render`. If the claim spans crates, the test must too.
|
|
|
|
## Driven testing
|
|
|
|
```rust
|
|
use makepad_test::{makepad_test, TestApp, KeyCode, Selector};
|
|
|
|
#[makepad_test]
|
|
fn player_can_win(app: TestApp) {
|
|
app.wait_for_log_contains("game: ready");
|
|
app.press_key(KeyCode::ArrowUp);
|
|
app.wait_for_log_contains("race: won");
|
|
println!("evidence: {}", app.screenshot().display());
|
|
}
|
|
```
|
|
|
|
`TestApp` gives `type_text`, `press_return`, `press_key`, `press_key_with_modifiers`, `touch_down`, `screenshot`, `widget_dump`, `widget_snapshot`, `wait_for_log_contains`, `locator(Selector)`, `forward(msgs)`. Every method has a `try_` variant returning `TestResult`.
|
|
|
|
**Synchronise on logs, never on sleeps.** `wait_for_log_contains` is why the game should log `game: ready`, `state: paused`, `race: won`. One log line per state transition makes the whole flow machine-checkable.
|
|
|
|
## Bot playtest
|
|
|
|
A scripted player that plays the loop end to end, catching what unit tests cannot: unwinnable levels, softlocks, and slow leaks.
|
|
|
|
Cover: reach the win state; reach the lose state; play 5+ minutes without a crash, memory growth, or frame-time drift; win twice in a row (catches incomplete `reset()`); pause/resume mid-run; and, if networked, two sessions staying in sync.
|
|
|
|
On the script route, drive the bot with the same verbs (`autodrive`, `walk`, `chase`) rather than synthesising input events.
|
|
|
|
## Screenshots
|
|
|
|
Capture every state — menu, playing, paused, win, lose — at the **target aspect ratio**, and at each supported ratio (16:9, 4:3, tall phone) for UI claims.
|
|
|
|
Then **look at them and describe what you saw.** An agent that captures a file and does not inspect it has produced an artefact, not evidence. Name them for content: `artifacts/shots/playing-desert-1920x1080.png`.
|
|
|
|
## Performance evidence
|
|
|
|
```bash
|
|
cargo run -p makepad-arcade --example bigworld_probe --release
|
|
```
|
|
|
|
Report p90 in release on a named device, before and after, against `apps/arcade/BUDGETS.md`. Include `quality_level()` and `quality_reason()` — a good frame time achieved by adaptive quality silently dropping to q1 is not a good frame time.
|
|
|
|
## Asset verification
|
|
|
|
Assets degrade silently to primitives, so a screenshot cannot prove they loaded:
|
|
|
|
```rust
|
|
for id in scene_ids { assert!(renderer.model_is_loaded(id), "missing {id}"); }
|
|
```
|
|
|
|
Also confirm asset-dependent tests **ran** rather than skipped — without the library they skip with a hint, and a skipped test reported as passing is a false report.
|
|
|
|
## Cross-platform
|
|
|
|
Do not claim a platform you have not run. Desktop (macOS/Windows/Linux), Android (this fork's branch targets it), web (memory pressure is the constraint — see the fork's Route work), and Quest/XR (72 Hz, bandwidth-bound, comfort rules). For each claimed platform state whether you ran it or only built it.
|
|
|
|
## Release
|
|
|
|
1. `cargo build --release` for each target
|
|
2. Full ladder green
|
|
3. Scorecard ≥ 2.3, nothing below 2, for a premium claim
|
|
4. Credits present — `resources/CREDITS.toml`, so a package carries attribution
|
|
5. Package via `makepad-game-pkg`: `Manifest`, `Library`, `Registry`, `sha256` / `verify_digest`. Content-address and verify; a package whose digest is unverified is untrusted input.
|
|
|
|
## Reporting
|
|
|
|
Lead with the outcome. Then evidence, with commands and what they printed. Then remaining risks. State plainly what you did **not** run — an unrun check reported as passing is the single failure that invalidates the rest of the report.
|
|
|
|
## Required reading
|
|
|
|
- `references/test-harness.md` — writing unit and driven tests here.
|
|
- `references/release-checks.md` — the pre-ship checklist and packaging.
|