Give him a sidestep, and split the messages into two voices

He died at every chapter boss because he could not move, and there were two
independent reasons for it. The movement block is 'rally'-only — a settled feel
decision the six boss AI styles were written around — and a boss is fought from
'pretoss'. On top of that canAimServe() is true through a boss fight, so his one
finger was already spent on the slingshot: there was no gesture left over that
could have meant "move".

So it is a SIDESTEP, not a walk. One committed step on a cooldown, carrying
invulnerability that beats both damage channels — the chip damage in hurtPlayer
and the instant-death contact test. The rule about walking stands untouched.

The gesture is picked by WHICH WAY the drag leaves the deadzone, decided once and
never revisited for that touch: down-ish is the pull the game already teaches,
sideways is the step. No timing window, no invisible mode, so "one gesture means
one thing" still holds. The finger-steer modes are untouched — stick.aimable is
false in a horde, so the drag is the absolute steer it always was. The apron demo
now alternates PULL DOWN and SWIPE TO DODGE, and Marvin has a page for it.

The rest of the playtest list:

- Bangers is bundled beside Silkscreen, and the register IS the category. The
  quiet face keeps the HUD, the rack, the control hints and RESUMING IN; the loud
  one takes SET, CHAPTER, EPIC!, PERFECT and every free-floating flash. Floating
  text gets one shared y and a drop shadow, so it survives crowd, clay and blood.
- Modals queue instead of being dropped. That was why the trainer and the weapon
  had to be crammed into one card after a won duel; the heal gets its own popup
  with the x_cross tin over it — a sprite loaded since that merge and drawn by
  nothing.
- weaponModal's first-sight gate moved inside the function. The barrels gated
  themselves and the tin ladder did not, so four weapons re-explained themselves
  every three games while a barrel weapon explained itself once.
- Ten rack slots. Past five it grows a second row upward rather than shrinking
  ten tiles under the thumb target; slots 0-4 stay welded to the bottom edge.
- The boss win holds for its own 3.6s and says EPIC!, with no GAME n NEXT line —
  the bar under the scoreboard already prints that permanently. That bar went
  from 6px to 7px, which is the smallest type in the game becoming words.
- The turn punches the camera in on him and the ground shakes harder at each beat.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-03 21:48:24 +02:00
1 parent 99774ab4be
commit 55c0f75c37
10 files changed
+345 -95

No files matched your search

+68 -2
View File
@@ -317,8 +317,74 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu
`updateZombies`), never by handing back movement.
- **The player must always be ON SCREEN.** `P_BOUNDS.x` is 6.5 m but portrait only shows about
±4 m either side of the centre line at the baseline, so the walk bound alone let him leave the
frame entirely. `xLim = Math.max(xVis, COURT.W / 2)` — the camera limit, floored at the sideline so
every legal ball stays catchable.
frame entirely. `xLimit()` in gameplay — the camera limit, floored at the sideline so every legal
ball stays catchable. The walk and the sidestep share it.
- **The sidestep is how you move outside `rally`, and it is not a walk.** One committed step
(`TUNE.dodgeDist`) on a cooldown, carrying `TUNE.dodgeIFrame` seconds that beat BOTH damage
channels — the chip damage in `hurtPlayer` and the instant-death contact test. It exists because a
boss fight is spent in `pretoss`, so the rule above left you welded to the spot for the whole
fight and Oliver died at every chapter boss without ever being able to move.
- **Which way you leave the deadzone IS the gesture.** Decided once, at the `DEAD` crossing, and
never revisited for that touch: down-ish = the slingshot, sideways = the sidestep. This is how the
new gesture stays inside "one gesture means one thing" — there is no timing window and no hidden
mode, only the direction you actually moved. The finger-steer modes (horde, burst) are untouched:
`stick.aimable` is false there, so the drag is still the absolute steer it always was.
- **Two type registers, and the register IS the message's category.** Silkscreen for the HUD, the
rack, the control hints and `RESUMING IN` — things you read at leisure. Bangers (`B()` in render)
for `SET`, `CHAPTER`, `EPIC!`, `PERFECT` and every free-floating flash — things shouted at you.
Free-floating text carries a 1px shadow (`shadowText`) and one shared y (`FLASH_Y`), because it
has no panel and has to survive the crowd, sunlit clay and blood behind it.
## Session log: the sidestep, and two type registers (2026-08-03)
Oliver's post-ship playtest. One blocker and seven polish items; all eight landed.
**The blocker: he died at every chapter boss because he could not move.** Two independent causes,
and fixing either alone would have left him rooted. The movement block is `rally`-only (a settled
decision the six boss AI styles were written around), and a boss fight is spent in `pretoss`. On top
of that `canAimServe()` is true through a boss fight, so the one finger was already spent on the
slingshot — there was no gesture left over that *could* mean "move". The answer is a **sidestep**,
not a walk, so the settled decision stands; and the gesture is picked by the DIRECTION the drag
leaves the deadzone in, so nothing about "one gesture means one thing" bends. Both are in the
settled-decisions list above.
Two guards make the dodge worth spending: `hurtPlayer` (the ranged channel) and the contact test in
`updateZombies` (the instant-death channel). Verified by pinning a shambler on the player: alive at
`dodgeI` 0.3, eaten the frame it hit 0.
**The message system was seven unrelated looks; it is two registers now.** Bangers is bundled
alongside Silkscreen and the split is documented above. `drawCard`, `drawModal`'s title, `G.flash`
and the death summary shout; the control hints, the pull/dodge demos, the scoreboard and
`RESUMING IN` stay quiet. The types Oliver had not counted, for the record: the bottom control-hint
slot at `METER_Y`, the `drawPullHint` apron demo, the death summary, and the scoreboard/rack chrome.
**Modals queue now.** `showModal` used to *drop* a second popup opened in the same beat, which is
why the trainer and the weapon had to be crammed into one card after a won duel. `G.modalQ` is four
lines and it retires that hack: the weapon modal, then a real `WOUNDS TREATED` modal with the
`x_cross` first-aid tin over it (the sprite had been preloaded and drawn by nothing since the merge).
**One popup, one rule.** `weaponModal`'s first-sight gate moved INSIDE the function. The barrels
gated themselves and the tin ladder did not, so four weapons re-explained themselves every three
games for a whole run while a barrel weapon explained itself once. `deliverTin` gained the label
flash a barrel already had, or the fifth delivery onward would pay out in silence.
**Ten rack slots, second row on demand.** `RACK_MAX` 4 → 9. Ten tiles across 480px would be ~39 CSS
px on a phone, under the thumb target `rackHit` was widened for, so past five it grows a second row
UPWARD and slots 0-4 stay welded to the bottom edge. `METER_Y` derives from `rackTop()` now, so the
hint line and the apron demo lift with it.
**The apron demo alternates.** `demoSwipe(dx, dy, label)` is the old `drawPullHint` body with the
direction pulled out; `drawPullHint` alternates PULL DOWN and SWIPE TO DODGE on the 1.9s cycle, and
mimes away from whichever edge the player is standing against.
**The transition punches in.** `G.zoom` is a flat 2D scale about a projected world point, applied in
the same place and for the same reason as `G.shake` — a perspective dolly would want `camZ`,
`aimCam` and every projected HUD anchor to agree for the sake of one 1.15s beat. Escalating shake at
3.4 / 4.8 / 8.2 s.
**And the boss win holds.** `TUNE.bossWinT` (3.6s) is its own number so the routine SET card does not
drag with it. `EPIC!` in Bangers, chapter and crowd demoted to subs, and no `GAME n NEXT` line —
the bar under the scoreboard already prints the game number permanently.
## Session log: the second pass on the barrel weapons (2026-08-03)