The flick lesson belongs to the rally modes, and gore's opener is not one

The gate said `G.mode === 'tennis' || G.match`, and mode 'tennis' is two
different things: classic, and the single prologue game a gore run plays before
the court turns. Placement is not the skill that prologue is asking for.
rallyFeel() already draws exactly the line wanted — classic and zombie tennis,
the two modes that ARE rallies — so the hint rides that instead of a mode
string. Verified both ways on a phone-sized preview: the lesson beside the
player in zombie tennis, and gone under gore-opener conditions with everything
else identical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-17 08:39:17 +02:00
1 parent c613b6ceba
commit 67cb0b74d7
3 files changed
+17 -8

No files matched your search

+6 -2
View File
@@ -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 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 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 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 not exist there). **It belongs to the RALLY MODES and only those — classic and zombie tennis —
permanent interlude, so a `G.mode === 'tennis'` gate would have missed the mode it was built for. 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 The words sit ABOVE the stroke: below them is the baseline, and 10px type over that white line
is unreadable. is unreadable.
+1 -1
View File
@@ -659,6 +659,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') {
</div> </div>
</div> </div>
</div> </div>
<script type="module" src="src/main.js?v=278"></script> <script type="module" src="src/main.js?v=279"></script>
</body> </body>
</html> </html>
+10 -5
View File
@@ -3,7 +3,7 @@
import { cv, ctx } from './dom.js'; 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 { 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 { 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 { drillQueue, drillLegal, drillMult } from './drill.js';
import { zombies, gore, piles, parts, pellets, extras, shots, pops } from './zombies.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 — // 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 // 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 // tap always wins.
// permanent interlude, not mode 'tennis') and on touch only: on a keyboard the aim is held keys, // THE FLICK LESSON BELONGS TO THE RALLY MODES, which is what rallyFeel() already means: CLASSIC
// and 'SWIPE' would be an instruction for a gesture that does not exist there. // 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'; const inRally = G.phase === 'rally' && ball.active && ball.lastHit === 'O';
if (G.mode === 'tennis' && inRally && G.passStreak >= 2) drawHitHint(); 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(); drawFlickHint();
// The free-floating register: no panel, one fixed slot, shouted. PERFECT, GAME N, DOUBLE KILL, // 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 // RETURNED, CHANGEOVER, weapon labels — everything that used to be plain white 12px text sitting