Give every opponent a style, and split the soft ball into drop and lob

Step 2 of the rally rework: eight styles as dials on the opponent rows —
pusher, retriever, slicer, big hitter, baseliner, touch, net rusher,
all-court — read where the CPU chooses its shot (moonball, drop, lob,
spin), plans its approach and serves (serve and volley sprints in). The
walk-on names the style in one line so the player can plan against it.
A player lobbed at the net now backpedals and blocks, like the CPU.

Oliver on v363: the down-flick "always felt like a lob". The length is read
at contact and a thumb has usually travelled on; on the continuum even
50 px floated the ball. Below dropMax (90 px) it is now the drop, above it
the lob. Also un-flakes the machine-squeak test (seed 31337). v364.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5.5 committed 2026-10-14 11:25:52 +02:00
1 parent 72760a9d1e
commit 180288ef8f
7 files changed
+268 -42

No files matched your search

+2
View File
@@ -2369,6 +2369,8 @@ function modalRows(m, inner, skipBody) {
const push = r => { rows.push(r); return r; };
if (m.foe) {
push({ kind: 'split', h: m.foe.peer ? 38 : 26 });
// HOW IT PLAYS (the styles, step 2): one bold line, because a plan needs to know what it faces
if (m.foe.style) { const lead = wrapText(m.foe.style, F(8, 700), inner); push({ kind: 'rule', lead, h: lead.length * 12 + 4 }); }
const sub = [];
for (const l of m.foe.sub || []) sub.push(...wrapText(l, F(8, 0), inner));
if (sub.length) push({ kind: 'text', lines: sub, dim: true, h: sub.length * 12 + 2 });