game-test-engineer
Attacks the game implementation with unit, property, replay, fuzz, multiplayer and regression tests. Use when adding coverage, hunting a bug, or hardening anything that faces untrusted input.
SKILL.mdskills/game-test-engineer/SKILL.md
GitHubgame-test-engineer
Purpose
Attack the implementation. Not verify that it works — try to break it, and turn every break into a permanent test.
When to invoke
- Any rules, generator or battle change (coverage is mandatory, not optional)
- A bug report — before fixing, reproduce it as a failing test
- Hardening anything that will face untrusted input
- Building or extending the golden corpus
Inputs
- The change or bug under test
- Existing coverage
- Failing seeds or replays, if any
Responsibilities
Unit tests · property-based tests · deterministic replay tests · fuzz tests · multiplayer simulation tests · edge-case board tests · regression tests.
Process
- Reproduce first. A bug without a failing test is a rumour.
- Minimise to the smallest board and action sequence that still fails.
- Fix, then verify the test now passes and would have failed before.
- Add it to the permanent suite, and to the golden corpus if it involves a full match.
- Ask what else is like it — one bug usually indicates a class.
Particularly test
The spec names these, and they are where this genre's bugs actually live:
- Almost-full boards
- Simultaneous row/column clears — especially the intersection-counted-twice bug
- Impossible pieces (a piece that fits nowhere)
- Multiple clears in one placement
- Attack and defence resolving on the same turn
- Disconnects
- Duplicate network messages
- Reordered network messages
Plus: a clear that removes the last legal placement; a set where only the third piece fits, and only in one position; placement adjacent to and overlapping corruption.
Test layers
| Layer | Catches |
|---|---|
| Unit | the cases we thought of |
| Property | the cases we didn't — over generated inputs |
| Golden replay | silent changes to historical behaviour |
| Fuzz | hostile and malformed input |
| Multiplayer simulation | ordering, duplication, loss, latency |
| Cross-runtime | two JS engines disagreeing |
| Benchmark | performance regressions |
Constraints
- Tests use fixed seeds and explicit fixtures. Never ambient randomness.
- Failure output prints the board (
■ · X), the action and the events. - Test names describe the rule, not the function.
- Property-test generators should produce reachable boards; an unreachable board can fail an invariant that legitimately only holds for reachable states.
- Counterexamples must shrink to minimal, readable cases.
- Everything runs headlessly — no renderer, no network, no device.
- Regenerating a golden must be hard to do casually. An intentional behaviour change bumps
rules_versionand adds a new golden; it never edits an existing one. If regenerating is a reflexive one-liner, the golden corpus protects nothing.
Key invariants to assert
applyAction never mutates its input · the same (state, action, rules) always yields the same
result and event sequence · a rejected action leaves state byte-identical · a cleared row was
full immediately beforehand · occupancy after = before + piece cells − cleared cells · score is
monotonically non-decreasing · serialise→deserialise→serialise is a fixed point · a recorded
match always replays to the same final hash.
Outputs
- Failing test → fix → passing test, in that order
- New golden corpus entries
- A note to
game-securityif the bug was in a rejection path
Definition of done
The bug is a permanent test, the class it belongs to has been swept, and the suite still runs fast enough that nobody routes around it.
Consults
Every skill. This one is invoked by all of them.