diff --git a/PROJECT.md b/PROJECT.md index e5a5c28..e1703af 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -491,6 +491,25 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu `RETURNED`, `DOUBLE KILL`) is a footnote to something you already watched happen. Sharing the loud FACE with the milestone cards is right; sharing their SIZE made every footnote read as a milestone. +## Session log: the copy audit — every modal says what it means (2026-08-29, Oliver's ask) + +A sweep over every modal/card message for decoding-required copy, four finds fixed: + +- **The arcade's rules card said DEATH MATCH** — a leftover of the era when the solo mode WAS + one; the picker has said ARCADE/THE CLIMB for a day. It wears THE CLIMB now ("THE WHOLE CLUB, + BOTTOM UP / ONE GAME PER BODY — HOW FAR CAN YOU GET?"); netplay keeps DEATH MATCH (there it is + literally the mode) and says "WOUND YOUR FRIEND". +- **The tournament card's "UP YOUR LEAGUE'S DEAD HIERARCHY"** (the trigger for this audit) became + "YOUR LEAGUE, ROUND BY ROUND / WIN IT ALL — MOVE UP A LEAGUE" — the payoff was never named. +- **The ball-machine card never named the machine** ("SWING TO RETURN — OR SWISH IT AWAY", an + instruction without a subject) — "A BALL MACHINE / SWING ITS SHOTS BACK — OR SWISH THEM AWAY". +- **The drill's "FAST BEATS CLOSE · STREAKS PAY"** decrypted on the zoned card ("THE FASTEST + BODY — NOT THE NEAREST" / "THE WRONG BODY BREAKS THE STREAK" — checked against drill.js's + actual rule); the body keeps the old words for the suite. +- **SUDDEN DEATH only sold the win** — it names both stakes now ("LOSE: THE DEAD TAKE A GAME / + AND FIVE MORE CLIMB THE FENCE", the real resolveInterlude cost). Judged fine and left alone: + the boss walk-on, horde, barrel, trainer, training-court and bench copy. + ## Session log: the rules cards get zones too (2026-08-29, Oliver: "wichtige Infos, schwer zu erfassen") Same disease as the walk-on, same medicine: the three mode modals (THE TOURNAMENT, DEATH MATCH, diff --git a/index.html b/index.html index 65c22b7..fa44680 100644 --- a/index.html +++ b/index.html @@ -871,6 +871,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat - + diff --git a/src/beats.js b/src/beats.js index 6e791c2..4b7d0a9 100644 --- a/src/beats.js +++ b/src/beats.js @@ -83,7 +83,10 @@ export function startDuel() { if (!G.seen.duel) { // the rules change back — worth one real interruption, once per run G.seen.duel = true; showModal({ title: 'SUDDEN DEATH', color: UI.hot, - body: ["IT'S TENNIS AGAIN — ONE POINT", 'WIN IT AND THEY HAND YOU A WEAPON'] }); + body: ["IT'S TENNIS AGAIN — ONE POINT", 'WIN IT AND THEY HAND YOU A WEAPON'], + // both stakes named (the old card only sold the win): a lost duel is a real cost + rules: [{ lead: "IT'S TENNIS AGAIN — ONE POINT", sub: 'WIN: THEY HAND YOU A WEAPON' }, + { lead: 'LOSE: THE DEAD TAKE A GAME', sub: 'AND FIVE MORE CLIMB THE FENCE', hot: true }] }); } else G.flash = { text: 'SUDDEN DEATH', t: 1.6 }; } @@ -405,13 +408,23 @@ export function startMatch(cup = false, draw = null, train = 0) { } else if (!cup && !train && !G.seen.match) { G.seen.match = true; // Oliver's copy direction: name the stake, count the blood. TUNE.matchPlayerHp is the real - // number, so the modal can never drift from the pool it describes. - showModal({ title: 'DEATH MATCH', color: UI.hot, - body: ['WIN THE POINT — WOUND THE ZOMBIE', - 'ITS POINTS DRAW BLOOD — ' + TUNE.matchPlayerHp + ' AND YOU ARE EATEN'], - rules: [{ lead: 'WIN THE POINT', sub: 'WOUND THE ZOMBIE' }, - { lead: 'ITS POINTS DRAW BLOOD', sub: 'AT ZERO YOU ARE EATEN', hot: true, - pips: TUNE.matchPlayerHp }] }); + // number, so the modal can never drift from the pool it describes. The card wears the mode's + // OWN name: the solo arcade is THE CLIMB now — its card still saying DEATH MATCH was a + // leftover of the era when it was one (2026-08-29 copy audit). Netplay keeps the old title, + // because there it is literally the mode. + showModal(G.net + ? { title: 'DEATH MATCH', color: UI.hot, + body: ['WIN THE POINT — WOUND YOUR FRIEND', + 'ITS POINTS DRAW BLOOD — ' + TUNE.matchPlayerHp + ' AND YOU ARE EATEN'], + rules: [{ lead: 'WIN THE POINT', sub: 'WOUND YOUR FRIEND' }, + { lead: 'ITS POINTS DRAW BLOOD', sub: 'AT ZERO YOU ARE EATEN', hot: true, + pips: TUNE.matchPlayerHp }] } + : { title: 'THE CLIMB', color: UI.hot, + body: ['THE WHOLE CLUB, BOTTOM UP — ONE GAME PER BODY', + 'ITS POINTS DRAW BLOOD — ' + TUNE.matchPlayerHp + ' AND YOU ARE EATEN'], + rules: [{ lead: 'THE WHOLE CLUB, BOTTOM UP', sub: 'ONE GAME PER BODY — HOW FAR CAN YOU GET?' }, + { lead: 'ITS POINTS DRAW BLOOD', sub: 'AT ZERO YOU ARE EATEN', hot: true, + pips: TUNE.matchPlayerHp }] }); } matchOpponent(); matchReady(); diff --git a/src/drill.js b/src/drill.js index 6b674a8..14e55bc 100644 --- a/src/drill.js +++ b/src/drill.js @@ -110,7 +110,11 @@ export function startDrillStream() { if (!G.seen.drillRule) { G.seen.drillRule = true; showModal({ title: 'CLEARANCE DRILL', color: UI.pick, - body: ['DROP WHOEVER WOULD REACH YOU FIRST', 'FAST BEATS CLOSE · STREAKS PAY'] }); + body: ['DROP WHOEVER WOULD REACH YOU FIRST', 'FAST BEATS CLOSE · STREAKS PAY'], + // the body keeps the old words for the suite; the zoned card decrypts them ("FAST BEATS + // CLOSE" meant nothing until you had already failed it — 2026-08-29 copy audit) + rules: [{ lead: 'DROP WHOEVER WOULD REACH YOU FIRST', sub: 'THE FASTEST BODY — NOT THE NEAREST' }, + { lead: 'KILL STREAKS SCORE EXTRA', sub: 'THE WRONG BODY BREAKS THE STREAK' }] }); } d.t = 0; d.spawnT = 0; d.score = 0; d.streak = 0; d.kills = 0; d.faults = 0; d.lost = 0; d.msg = null; try { d.best = Number(localStorage.getItem('drillBest')) || 0; } catch { d.best = 0; } diff --git a/src/zombies.js b/src/zombies.js index 03a59a0..a267199 100644 --- a/src/zombies.js +++ b/src/zombies.js @@ -121,7 +121,10 @@ export function spawnMachine() { aside('ump_machine', 0.4); // benched with the rest of Daniel's personality — see aside() if (!G.seen.mach) { G.seen.mach = true; - G.card = { title: 'SWING TO RETURN — OR SWISH IT AWAY', color: UI.warm, t: 2.6 }; + // the card NAMES the thing it explains — an instruction without a subject read as noise + // (2026-08-29 copy audit) + G.card = { title: 'A BALL MACHINE', sub1: 'SWING ITS SHOTS BACK — OR SWISH THEM AWAY', + color: UI.warm, t: 2.8 }; } }