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

+64 -2
View File
@@ -5323,14 +5323,76 @@ the hook for step 2's opponent.
- **Not done:** a lesson for the gesture (the ghost hand only teaches the side flick), and a "LOB"/"DROP"
word at contact. The arc says it. Add one if the phone test shows nobody finds it.
### v363's phone verdict: the drop never came (2026-10-14, fixed in v364)
Oliver: *"in touch nach unten erzeugt gefühlt immer einen Lob.. mir ist ein Stoppball nicht gelungen..
vielleicht ist die Geste zu subtil."* Two reasons stacked. The swing fires at `flickMin` (28 px) but the
length is read at CONTACT, by when the thumb has usually travelled on. And on the continuum even a 50 px
flick already floated the ball to mid-court. **Now it is two shots:** a down-flick shorter than
`dropMax` (90 px) is the drop, longer is the lob. The continuum survives only for the opponent's
moonball (`aim.soft` 0.85). Verified with real touch events: 50 px and 75 px give drops, 150 px a lob.
Pinned: a 75 px flick lands exactly where the shortest drop does. A slow, long swipe that is still
short of 90 px at contact is still a drop, so "long and brisk" is the lob gesture.
### Step 2: OPPONENTS WITH A GAME (2026-10-14, v364)
`config.STYLES`: eight styles as dials, one `style` per OPPONENTS row, and the walk-on carries the
style's `tag` as one bold row ("PUSHER — IT ALL COMES BACK HIGH"), because the player has to know what
he faces to plan against it. Dials:
- `loft`: a moonball habit, the soft ball at 0.85.
- `drop`: only when the player stands behind his line AND the body is 1.5 m inside its own.
- `lob`: when the player is at the net.
- `spin`: rally-ball bounce, >1 topspin kick, <1 slice.
- `charge`: lowers its short-ball line.
- `sv`: serve and volley.
Context-chosen shots are fine for the CPU; the one-gesture rule binds the player's thumb.
| style | who | does |
|---|---|---|
| pusher | Shambler, Punter, Steward | 45% moonballs, lobs a net man half the time |
| retriever | Ball Boy, Runner | some moonballs, lobs |
| slicer | Keeper, Seller | low ball (spin 0.8), the odd drop |
| power | Roller, Stringer, Brute | heavy topspin kick (1.15) |
| baseliner | Line Judge | mild topspin, the odd lob |
| touch | Mascot, Physio | drops you when you hang back, lobs you at the net |
| rusher | Umpire, Club Pro, Director | serve and volley, comes in 1.6 m earlier |
| allcourt | Head Coach, Champion | a little of everything |
Wiring:
- **Serve and volley:** `hitServe` stamps `ball.approach = 'O'`. `rz.rushing` is set while its own ball
flies, and the recovery SPRINTS instead of walking. `rxPlan` plays the return as a net man wherever
the run has got to (never a serve return), and net mode heads to `netStand` depth on the ball's line,
with `netReact` as the split step.
- **The player lobbed at the net** gets the CPU's rule: `intercept` flips his plan to `lob`, his
backpedal runs at `lobTurn`, and his reply is capped.
- `rzChaseSpeed`'s lob factor reads only the CPU's OWN plan.
Tests (160, ten seeds):
- every rung styled, tags fit
- pusher moonball and lob shares match the table, and it never drops
- big-hitter balls all kick
- touch drops from inside, never from behind its line
- the rusher charges more than 2 m behind its serve
- the player's plan turns to lob
The step-1 baseline-shape test now plays THE LINE JUDGE (a baseliner, `oppOf().foe` set; the body plays
the style, not the rung number), and its net share floor is 50%. The autopilot mistimes into short balls,
and a body is meant to come in on those. The back-court volley cap is the real guard. The depth and Climb
pace samplers skip soft balls, since a moonball's pace comes from its arc. Also fixed in passing: the
machine-squeak test was ~1% seed-fragile (one 3 m roll, about 5 grind ticks at 60%). It now keeps
rolling (seed 31337 found it).
**Not built:** the champion LEARNING whether the net works for him (Free Tennis's idea), a style for
classic's CPU, and a "DROP"/"LOB" word at contact.
# OPEN — leftovers, in rough priority order
Nothing here is broken; these are known gaps and unverified risks.
0. **THE RALLY GOES FLAT (2026-10-13), the top item.** Every match converged on serve, both at the net,
reflex volleys, won by a wrong-foot. Step 1 (the court gets its length) SHIPPED v361, awaiting the
phone verdict. Next up: step 3 (the soft ball, approved), step 2 (opponent styles), and step 4 (the legs:
the Champion runs 15.7 m/s). See the section of that name above. Fallback tag `rally-baseline-v360`.
phone verdict; the tap timing + leg knee (v362), the soft ball (v363, drop/lob split v364) and the
opponent styles (v364) followed. Awaiting the phone verdict on v364. See the section of that name
above. Fallback tag `rally-baseline-v360`.
1. **`RES` 4 is unverified on a real phone under load.** It nearly doubled the fill rate (810 -> 1080
device px across). Oliver has not reported stutter, but he also has not played a late horde since.