POLISH-PLAN: schedule the DUEL, not the tin
Oliver's call: duels have to come round on their own so there is always a shot at a weapon. So the game-count schedule isn't the bug — it's attached to the wrong event. Item 5 now moves it from delivering tins to calling duels: same cadence, same umpire-restores-order framing, but the weapon has to be earned. Fires off proceedAfterClear(), which is the one moment the court is guaranteed empty (the wave was just cleared by hand and nothing has respawned). Clearing is already mandatory before play advances, so the schedule can't stall — a wall-clock timer would need its own wait-for-a-safe-moment logic and could fire mid-swarm. The existing opportunistic trigger stays as a bonus path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
64b297ce54
commit
5faaa99467
1 file changed
+41
-13
+41
-13
@@ -181,21 +181,49 @@ oder nicht."
|
||||
Note path 2 has a partial gate already: `G.shameGame` withholds the tin if *they* took a
|
||||
game since the last delivery. That is not the same as winning the duel.
|
||||
|
||||
**Build:** make winning the duel the ONLY source of weapons.
|
||||
- Delete the `tinDue` scheduling in `splatPoint()` and the `deliverTin()` call in
|
||||
`startChangeover()`. Keep the "CHANGEOVER" flash. `G.tinDue` / `TUNE.ballChangeFirst` /
|
||||
`ballChangeEvery` / `G.shameGame` all become dead — remove them rather than leaving
|
||||
vestigial state.
|
||||
- Keep `resolveInterlude('P') → deliverTin()`.
|
||||
**The design decision (Oliver, 2026-07-27):** duels must come round on their own after a
|
||||
while, "damit es immer die chance auf waffen gibt". So the schedule is not the problem — it
|
||||
is attached to the wrong event. **Move it from delivering tins to calling duels.** The
|
||||
cadence stays, the reward becomes something you have to earn, and the umpire-restores-order
|
||||
framing is unchanged.
|
||||
|
||||
**Consequence to check:** duels only trigger when the court is clear and a racket zombie is
|
||||
the last one standing (`gameplay.js:~760`). If that turns out to be rare, weapons become
|
||||
near-unobtainable. **Measure before shipping:** run a 5-minute simulated session and count
|
||||
duels. If it's under ~1 per two games, tell Oliver rather than silently re-adding a second
|
||||
source — the design question (how often should duels happen?) is his call.
|
||||
**Why the duel is rare today:** the trigger at `gameplay.js:~760` requires
|
||||
`zombies.length === 1 && zombies[0].variant === 'r' && !zombies[0].dueled` — the court has to
|
||||
be completely empty apart from one never-yet-dueled racket zombie. Racket zombies only appear
|
||||
when you win a game (`splatPoint`) or survive a horde (`endHorde`), and fresh shamblers spawn
|
||||
again the moment a clear finishes. So it fires by luck.
|
||||
|
||||
**Acceptance:** simulate a full game where the player loses the duel; `G.bombs` etc. must be
|
||||
unchanged. Win one; exactly one tin arrives.
|
||||
**Build:**
|
||||
- Rename the schedule to what it now schedules: `TUNE.ballChangeFirst`/`ballChangeEvery` →
|
||||
`duelFirst`/`duelEvery`, `G.tinDue` → `G.duelDue`. Keep the same arithmetic in
|
||||
`splatPoint()`. Suggested start: first duel after game 2, then every 3.
|
||||
- Delete the `deliverTin()` call in `startChangeover()` (keep the "CHANGEOVER" flash).
|
||||
`G.shameGame` — which withheld a tin if they took a game — has nothing left to gate;
|
||||
remove it rather than leaving vestigial state.
|
||||
- Keep `resolveInterlude('P') → deliverTin()` as the only weapon source.
|
||||
- **Fire the scheduled duel off the existing clear beat.** `proceedAfterClear()`
|
||||
(`gameplay.js:290`) already runs at the one moment the court is guaranteed empty — the
|
||||
player just cleared the wave by hand, and no new shamblers have spawned yet. That is the
|
||||
natural slot. There: if `G.duelDue`, consume it, ensure a racket zombie exists
|
||||
(`spawnRacketZombie()` if none, and clear `dueled` on the existing one so a veteran can be
|
||||
challenged again), and start the interlude instead of the changeover/game beat. The
|
||||
changeover follows after the duel resolves.
|
||||
- Leave the existing opportunistic trigger in place. The schedule is a floor, not a ceiling —
|
||||
a lucky clear can still produce a bonus duel, which is pure upside for weapon supply.
|
||||
|
||||
**Why this slot and not a timer:** clearing the wave is already mandatory before play
|
||||
advances (`G.clearing`, a settled feel decision Oliver was emphatic about), so the schedule
|
||||
can never stall. A wall-clock timer would need its own "wait for a safe moment" logic and
|
||||
could fire mid-swarm.
|
||||
|
||||
**Acceptance:**
|
||||
- Simulate ~10 games. A duel must occur at game 2, 5, 8 … regardless of how the waves fall.
|
||||
- Lose a duel → `G.bombs`/`triples`/`flames`/`guns` unchanged, and the next duel still
|
||||
arrives on schedule.
|
||||
- Win one → exactly one tin, and the item-8 modal names it.
|
||||
- No path reaches `deliverTin()` except `resolveInterlude('P')`
|
||||
(`grep -n "deliverTin" *.js` should show the definition, that one call, and the `window.T`
|
||||
test export — nothing else).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user