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:
1 parent
99774ab4be
commit
55c0f75c37
10 files changed
+345
-95
No files matched your search
+68
-2
@@ -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)
|
||||
|
||||
|
||||
Reference in new issue
Block a user