diff --git a/HANDOFF-MATCH.md b/HANDOFF-MATCH.md index b9b4c01..8d31790 100644 --- a/HANDOFF-MATCH.md +++ b/HANDOFF-MATCH.md @@ -98,8 +98,12 @@ communicating its own rules. Model A only works if the player can see they are b because hitting flat is a legal shot and not a mistake. **One lesson at a time:** the tap hint wins if both qualify, since teaching placement to someone who cannot reach the ball is the wrong lesson. Touch only (on a keyboard the aim is held keys, and SWIPE would name a gesture that does - not exist there), and it runs in the MATCH as well as classic — the match is `splatter` under a - permanent interlude, so a `G.mode === 'tennis'` gate would have missed the mode it was built for. + not exist there). **It belongs to the RALLY MODES and only those — classic and zombie tennis — + which is what `rallyFeel()` already means.** Not gore, and not gore's OPENER: `G.mode === + 'tennis'` covers classic AND that prologue, which is the wrong seam (Oliver, 2026-08-17: "if it + is in gore mode this would be the wrong place"). Note the match is not mode `'tennis'` at all — + it plays under splatter's permanent interlude — so the mode check alone would have missed the + very mode it was built for, in both directions at once. The words sit ABOVE the stroke: below them is the baseline, and 10px type over that white line is unreadable. diff --git a/index.html b/index.html index f59df57..dbd9ea2 100644 --- a/index.html +++ b/index.html @@ -659,6 +659,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') { - + diff --git a/src/render.js b/src/render.js index 09568d9..95f85c5 100644 --- a/src/render.js +++ b/src/render.js @@ -3,7 +3,7 @@ import { cv, ctx } from './dom.js'; import { BENCH, BENCH_STAGES, ZFAMS, famFrames, racketStage, TUNE, UI, EATEN_BURST, EATEN_SUMMARY, EATEN_RESTART, DONE_RESTART, COURT, P_BOUNDS, PLAYER_H, BOY_H, UMP_H, UMP_X, MACH_H, BOSS_ART, ZWOUND, woundStage, BOUNCE_IDLE, SPRITE_H, zombieH , WEAPONS, RACK_ROW, TOSS, HEAD_CROP, CUP_ROUNDS, TINT } from './config.js'; import { P, O, ball, score, crowd, G, court, tour, kit, skin } from './state.js'; -import { predictLanding, previewServe, slotId, slotStock, serveApexY } from './gameplay.js'; +import { predictLanding, previewServe, slotId, slotStock, serveApexY, rallyFeel } from './gameplay.js'; import { drillQueue, drillLegal, drillMult } from './drill.js'; import { zombies, gore, piles, parts, pellets, extras, shots, pops } from './zombies.js'; @@ -2731,12 +2731,17 @@ export function render() { } // the tennis struggle hints: both ride the exact failure they answer, and only one at a time — // teaching the flick to someone who cannot get a racket on the ball is the wrong lesson, so the - // tap always wins. The flick lesson also runs in the MATCH (G.match plays under splatter's - // permanent interlude, not mode 'tennis') and on touch only: on a keyboard the aim is held keys, - // and 'SWIPE' would be an instruction for a gesture that does not exist there. + // tap always wins. + // THE FLICK LESSON BELONGS TO THE RALLY MODES, which is what rallyFeel() already means: CLASSIC + // and ZOMBIE TENNIS. Not the gore mode, and not gore's OPENER either — that tennis is a prologue + // you play for one game before the court turns, and placement is not the skill it is asking for. + // (`G.mode === 'tennis'` covered classic AND that prologue, which is exactly the wrong seam; the + // match itself is not mode 'tennis' at all, it plays under splatter's permanent interlude.) + // Touch only: on a keyboard the aim is held keys and 'SWIPE' would name a gesture that does not + // exist there. const inRally = G.phase === 'rally' && ball.active && ball.lastHit === 'O'; if (G.mode === 'tennis' && inRally && G.passStreak >= 2) drawHitHint(); - else if (IS_TOUCH && inRally && (G.mode === 'tennis' || G.match) && G.flatStreak >= TUNE.flickHintAfter) + else if (IS_TOUCH && inRally && rallyFeel() && G.flatStreak >= TUNE.flickHintAfter) drawFlickHint(); // The free-floating register: no panel, one fixed slot, shouted. PERFECT, GAME N, DOUBLE KILL, // RETURNED, CHANGEOVER, weapon labels — everything that used to be plain white 12px text sitting