Every colour you are asked for is already on the far side

"make the game that it is actually winable meaning that all required colors
are visible on the far side before when a color combination is shown.. for
now no colors that are not in the current combination but occasional zombies
which don't have a color and are converging to the player trying to eat him".

Two rules define the file now. Every colour on court is IN the current
combination — no coloured decoys, so the strip can never name a body that is
not there. And a combination is only shown once its bodies are all on the far
side, which is free because the batch is BORN there: it is a property of the
construction rather than a check that could be wrong.

The pressure moved to the eaters: plain unbibbed shamblers on their own
clock, deliberately not flagged `drill` so they keep the gore mode's homing
and converge on you while the bibbed batch walks its lanes. Killing one is
never a fault; letting one reach you is the ordinary caught. The puzzle plays
fair and the danger arrives separately, which is a better trade than a puzzle
that cheats.

The batch is the round: kill the last of it and the next walks in on the same
frame with its combination already called.

One real bug, caught by the new test: killZombie resolved the drill BEFORE
splicing the body, so a combination drawn on the spot could name the corpse —
a round asking for a colour that is not on court, i.e. exactly the unwinnable
state this pass exists to prevent. Splice first, resolve second.

28 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-11 19:29:04 +02:00
1 parent 586e8d4e4b
commit abd6d4f789
6 files changed
+193 -137

No files matched your search

+19 -18
View File
@@ -345,27 +345,28 @@ export const TUNE = {
barrelRoll: 2.6, // m/s it trundles across the far court — fast enough to have to be led
barrelHp: 1, // anything pops it: ball, pellet, bomb, flame, swish. It is a target, not a body
barrelH: 1.15, // drawn height (a body is 1.8)
// ---- THE COACHING DRILL (src/drill.js) — the cognitive mode. SECOND DESIGN: a continuous
// stream. Bodies walk in from the far baseline forever; a ROUND is a colour combination drawn from
// whoever is on court, and finishing one draws the next on the spot. No walk-on, no announcement
// beat, no pause between rounds — every seam Oliver found is gone, the round itself stays.
drillMaxOnCourt: 6, // bibs on court at once. Hard-capped by DRILL_COLS (a colour appears once)
drillSeed: 4, // bodies placed at the start so the first round is callable immediately
drillSeedGap: 2.2,// m of depth between those seeded bodies — strung out, not a rank abreast
// ---- THE COACHING DRILL (src/drill.js) — the cognitive mode. THIRD DESIGN, and the one that
// makes it winnable: a BATCH of bibbed bodies is born on the far side, its combination is called
// off them immediately, and every colour on court is in that combination — no coloured decoys, so
// the strip can never name something you cannot see. Kill the last of a batch and the next walks
// in on the same frame. The danger is a separate channel: unbibbed EATERS on their own clock that
// converge on you the way ordinary shamblers do.
drillBatch: 3, // colours in a batch at the bottom of the ramp...
drillBatchMax: 6, // ...and at the top. Capped by DRILL_COLS — a colour is on court at most once
drillBatchDepth: 3.0, // m of depth a batch is staggered over. All of it still on the far side,
// which is the promise: you see every colour before you are asked for it
drillSpawnZ: 0.6, // z they enter at (the far baseline is 0)
drillNearZ: 9.0, // spacing is measured against bodies nearer than this — the ones still bunched
drillSpread: 3.4, // m either side of the centre line the lanes fan across
drillSeq: 3, // colours in a round at the start of the ramp...
drillSeqMax: 5, // ...and at the top of it
drillSpawnEvery: 3.4, // s between arrivals at the start...
drillSpawnMin: 1.2, // ...and at the top. THE difficulty dial: the court fills faster than you clear
drillSpeed: 0.80, // m/s they walk at the start...
drillSpeed: 0.80, // m/s a bibbed body walks at the bottom of the ramp...
drillSpeedMax: 1.9,// ...and at the top. Stamped per body AT SPAWN, so the ramp shows up as new
// arrivals outpacing the ones already walking, not as the court accelerating
drillRampT: 210, // s to go from the bottom of every curve above to the top. Time survived, not
// rounds won — a round-counted ramp cannot escalate while you stand still
drillCaughtBack: 45, // s of ramp handed back when one reaches you. The setback is real but not a reset
drillTones: 1, // volume of the colour arpeggio (0 = silent). It replaced the spoken call
// arrivals outpacing the ones already walking, not the court accelerating
drillEaterEvery: 7.0, // s between unbibbed eaters at the bottom of the ramp...
drillEaterMin: 2.2, // ...and at the top. THE difficulty dial now that the puzzle plays fair
drillEaterMax: 4, // eaters allowed on court at once — past this the puzzle is unreadable
drillEaterSpeed: 1.15,// they walk a touch faster than the batch: the batch is a list, this is a threat
drillRampT: 210, // s to go from the bottom of every curve above to the top
drillCaughtBack: 45, // s of ramp handed back when one reaches you. A real setback, not a reset
drillTones: 1, // volume of the colour arpeggio (0 = silent). It replaced the spoken call
fps: 60, // frame cap — 30 halves battery/heat but Oliver felt it; smoothness wins (0 = uncapped)
lowPower: 1, // >= 0.5 caps RES at 3 (−44% of pixels painted per frame) — the battery saver,
// flippable live from the T panel. DEFAULT ON since 2026-08-08: Oliver judged