diff --git a/HANDOFF-MATCH.md b/HANDOFF-MATCH.md index 79e3bcf..21b4210 100644 --- a/HANDOFF-MATCH.md +++ b/HANDOFF-MATCH.md @@ -38,7 +38,7 @@ Oliver picked **A: blood-only**, of three options offered: blood already spent, and heals are how you last. **The measure becomes OPPONENTS FELLED.** - B — tennis-true: a lost game ends the run. Rejected for now (worth one playtest someday; it might be the mode's real personality). -- C — hybrid, lost game drops a rung. Rejected. +- C — hybrid, a lost game drops you an opponent. Rejected. **Important context for whoever implements this:** Oliver believed losing a match killed him ("i really die losing one match"). It does not — he was bleeding out during deuce wars and hitting @@ -55,10 +55,12 @@ communicating its own rules. Model A only works if the player can see they are b same `endRun` with a mode tag — see "The record shape" below. The blood also got a readout, one pip per hit left beside the board, because the vignette says "worse" and never says "how many". -2. ~~**Named opponent ladder**~~ **DONE, partly.** Rung N takes design N's name off the chapter - roster (`matchRung` in config) plus a personality that is DIALS — pace, width, flub, speed - scalings on numbers `racketAI` already reads. Name plate on the walk-on, board names it - (`short`), kills file under the rung so THE LADDER screen can list them. +2. ~~**Named opponent list**~~ **DONE, partly.** Opponent N takes design N's name off the chapter + roster (`matchFoe` in config, rows in `config.OPPONENTS`) plus a personality that is DIALS — pace, + width, flub, speed scalings on numbers `racketAI` already reads. Name plate on the walk-on, the + board names it (`short`), and the kill files under it so the OPPONENTS FELLED screen can list it. + *(The word "ladder" was retired — it had come to mean the opponent list, the wound stages AND a + stats screen. One word per thing now: OPPONENTS, WOUND STAGES, and a sprite FAMILY.)* **Still open, and still the cheapest depth in the mode:** `shots[]` and the PARRY are fully built and completely unused here. A body-shot thrower is a personality no dial can express. @@ -112,7 +114,7 @@ slots carry each MODE's own two numbers: `g` is what everything ranks on, so each mode's real measure goes in that slot and there is no second best stored anywhere to drift. `read(period, runs, mode)` filters; the stats screen is one function -with three sets of words (BODY COUNT / THE LADDER / THE RECORD). The world board stays the gore +with three sets of words (BODY COUNT / OPPONENTS FELLED / THE RECORD). The world board stays the gore mode's — it ranks kills in a run, and a five-body match would post a "5 kills" row next to a 300-kill massacre. A tennis board would rank FELLED with points won as the tiebreak; that is a server change. @@ -124,7 +126,7 @@ frame is picked off `racketAI`'s own `pose`, so the picture cannot drift from th Expansion ideas that survived discussion, in `PROJECT.md`'s LATER: the **tournament frame** (QUALIFYING → ROUND OF 16 → THE FINAL vs THE CHAMPION — gives the run a destination), the Hawk-Eye -**challenge** as an earned continue, sudden-death deuce past a rung, doubles, and **item 7: +**challenge** as an earned continue, sudden-death deuce past a given opponent, doubles, and **item 7: multiplayer** (ghost match first). --- diff --git a/src/gameplay.js b/src/gameplay.js index 46e832b..0b9153d 100644 --- a/src/gameplay.js +++ b/src/gameplay.js @@ -153,11 +153,11 @@ function doHit(ch, quality, aim) { // time than auto-run needs from the far corner. Opponent one gives you the flight time; the // rungs take it back. // ...and the RUNG's own pace trait rides on top, inside the cap: full pace is still the ceiling, - // a rung just gets there sooner or later than the flat ladder would (see matchRung in config). + // an opponent just gets there sooner or later than the flat curve would (see matchFoe in config). s *= Math.min(1, (TUNE.matchOppPace + (G.match.opp - 1) * TUNE.matchOppPacePer) * (ch.foe?.pace || 1)); } if (G.match) { - // THE OPPONENT'S WIDTH IS THE LADDER'S THIRD DIAL. Its returns scatter off aimError x (1 - 0.55 + // THE OPPONENT'S WIDTH IS THE THIRD DIAL. Its returns scatter off aimError x (1 - 0.55 // quality), which paints lines an auto-run player cannot reach — "still a LOT of unreachable // balls". Opponent one keeps its returns inside matchWideBase of the centre line; each rung // earns matchWidePer more width, so the line-painting is the LATE ladder, not the opening one. @@ -1045,7 +1045,7 @@ function racketAI(rz, dt) { const tz = Math.max(1.5, Math.min(COURT.svcFar, ball.z)); // chase laterally, hold deep on the far court const dx = ball.x - rz.x, dz = tz - rz.z, d = Math.hypot(dx, dz); if (d > 0.15) { - // THE MATCH LADDER ESCALATES HERE, not in hp: with regicide gone the pool is pure scoreboard, + // THE MATCH ESCALATES HERE, not in hp: with regicide gone the pool is pure scoreboard, // so a harder opponent is a FASTER one that flubs less. The BASE is boosted too — the duel's // 2.8 m/s lumber was tuned for one sudden-death point against a fresh player, and across a // whole game it read as "very weak and slow": opponent one already moves at matchSpeedBase.