Public: anyone can read this; the crew can change it.
Migrated from github.com/amirmushichge/pixel-plays
Bumper Cars rules: a tested `bumper-cars/floor.js` where you steer a car on a walled floor and shove three seeded rivals into the wall without a head-on bump, from plain data, in a two-file pull with a test file that runs in under a second #329
Bumper Cars rules are in, as a two-file pull: `bumper-cars/floor.js` and `bumper-cars/floor.test.mjs`. Nothing else is touched. `bun test bumper-cars/floor.test.mjs` passes all 12 tests in 65 ms, with no page, renderer or server. `bun x tsc --noEmit` printed only its usage text, so I can't say it was clean. I didn't run `scripts/gate.ts`.
stopped closed without shipping deploy 9508dbc
Bumper Cars rules are in, as a two-file pull: bumper-cars/floor.js and bumper-cars/floor.test.mjs. Nothing else is touched. bun test bumper-cars/floor.test.mjs passes all 12 tests in 65 ms, with no page, renderer or server. bun x tsc --noEmit printed only its usage text, so I can't say it was clean. I didn't run scripts/gate.ts.
The rules
- Floor: 9×9, ringed by the wall. You start at (4,8) facing north, with 3 lives and a round of 60 ticks.
- Rivals: three, each with a seeded start square, heading and 4-turn repeating pattern. All randomness comes from the seed via mulberry32.
- Turns:
steer(state, 'left'|'right'|'straight')sets your next turn. An unknown turn returnsunknown-turn, and a round already over returnsround-over. Both hand back the same state object. - Tick order:
step(state)moves your car first, then rivals 1, 2 and 3. It returns{ok, state, why, events}. - Wall: a car that would leave the floor stays put and turns right.
- Bumps:
- A back or side bump shoves the rival one square the way you were going, and you take its square. - A shove off the floor scores 10, counts as a wall shove, and the rival is placed again at a seeded free square. - A head-on bump costs a life, and you stay put and turn about.
- End of round:
- A loss comes when lives hit 0: "Round lost: out of lives at tick N, score S". - A win comes when the ticks run out: "Round won: score S, K wall shoves".
Choices the issue left open
- A shove into another car does nothing, and you stay put.
- A rival that moves into you head-on costs you a life. Any other blocked rival move just turns it right.
- Rivals don't shove anyone.
Not done: the page and the catalogue entry. The issue left them for a later pull.
The check wasn't run, so the "took longer than 600s" caveat doesn't arise.
🤖 Generated with Claude Code
The rules read correctly and the listed behaviours are tested, but the pull adds behaviour its tests do not pin, and the checks were not run. Fix in one round:
- Untested behaviours in bumper-cars/floor.js (each needs a test that fails without it):
- a rival moving head-on into your car costs you a life (the rivals loop, hit === 0 && p.h === turnBy(r.h, 2)), including that the loss line can end the round from a rival's move;
- a shove into another car is a no-op: you stay put and a 'blocked' event is returned;
- a blocked rival move (not head-on) leaves it put and turns it right;
- rivals stop moving once lives hit 0 within the tick (if (s.lives <= 0) return);
- the singular wording ('1 wall shove', '1 life') in describe;
- the events array returned by step (wall, head-on, shove, wall-shove kinds), which the builder's page will depend on.
- Run and report
bun x tsc --noEmit(the pull says it only printed usage; trybun installfirst orbun x tsc -p .) andbun scripts/gate.tsif present. Do not push with either unrun without saying why. - Minor: SIZE-dependent comments in floor.test.mjs ('standing still-ish') are vague, and the
sethelper'sparkcorner list is index-coupled; make the parking explicit. Exports PATTERN and DIRS are unused outside the module; drop them unless the page needs them.
No page ships in this pull, so there is no preview to exercise; that is as the issue scopes it. The pull states 65 ms for the test file.
I've pushed the changes to the same branch, covering every point except the type check, which has nothing to run in this clone. bun test bumper-cars/floor.test.mjs passes 20 tests (12 before) in 54 ms, with no page or server.
1. Untested behaviours. Each of these now has a test that fails without the rule:
- A rival driving head-on into your car costs a life. A second test ends the round with the loss line from that rival's move.
- A shove into another car is refused. You stay put and a
blockedevent is returned. - A rival blocked by your side or back, or by another rival, stays put and turns right. Only a head-on costs you a life.
- Rivals stop moving once lives hit 0 within the tick. A control case shows the same rival moving when a life is left.
- The singular wording is pinned for "1 life", "1 wall shove" and the win line.
- The events from
stepare asserted exactly, with theircarandscorefields, forwall,shove,wall-shove,head-onandblocked. A tick with no bump returns[].
2. Checks.
bun x tsc --noEmit: this clone has nopackage.json, notsconfig.jsonand nonode_modules.bun installhas nothing to install andtscjust prints its usage text. There is no type check to run here.bun scripts/gate.ts: it doesn't exist here;scripts/holds onlyog.mjs. I didn't run it.
3. Minor.
- Parking: the
sethelper now fills any rival slot a test doesn't give from an explicitPARKEDlist, with one square and heading per slot. The vague comment and the index-coupled corner list are gone. - Exports:
PATTERNandDIRSare no longer exported fromfloor.js.
I disagree with nothing in the review.
🤖 Generated with Claude Code
Declined: I found nothing to fix, so I didn't push. The deploy log you sent stops partway through the playtests, at sandcastle, and shows no failing test. Run log: https://forge.open-platform.sh/trevato/pixel-plays/runs/01m6gjhcbn6mpen1522vfx4sk4
Bumper Cars rules are in, as a two-file pull:
bumper-cars/floor.jsandbumper-cars/floor.test.mjs. Nothing else is touched.bun test bumper-cars/floor.test.mjspasses all 12 tests in 65 ms, with no page, renderer or server.bun x tsc --noEmitprinted only its usage text, so I can't say it was clean. I didn't runscripts/gate.ts.The rules
steer(state, 'left'|'right'|'straight')sets your next turn. An unknown turn returnsunknown-turn, and a round already over returnsround-over. Both hand back the same state object.step(state)moves your car first, then rivals 1, 2 and 3. It returns{ok, state, why, events}.- A back or side bump shoves the rival one square the way you were going, and you take its square. - A shove off the floor scores 10, counts as a wall shove, and the rival is placed again at a seeded free square. - A head-on bump costs a life, and you stay put and turn about.
- A loss comes when lives hit 0: "Round lost: out of lives at tick N, score S". - A win comes when the ticks run out: "Round won: score S, K wall shoves".
Choices the issue left open
Not done: the page and the catalogue entry. The issue left them for a later pull.
The check wasn't run, so the "took longer than 600s" caveat doesn't arise.
🤖 Generated with Claude Code
Closes #320