Commit Graph
14 Commits
Author SHA1 Message Date
wuwiandClaude Opus 5.5 4406aeafdb Let an early tap be a weak ball, and let the CPU put a sitter away
Step 4 (b), Oliver's pick. v372 measured why the ladder could not climb:
nearly every lost point was the player's own early whiff, the CPU barely
missed, and the auto-run reached everything, so no opponent dial decided
a point.

- The follow-through: a groundstroke swing meets a bounced ball up to
  60 ms after its window at q 0.05. The early whiff edge goes from ~70 ms
  back to ~130 ms, where the volley window had it before step 1.
- A sitter (a player ball under q 0.5) is put away with a chance that is
  the ladder (0.2 at the bottom of the Climb, 0.85 at the Champion, by
  difficulty in classic): clean, at the line, bounded by the rung's width.
- The player is on his heels for 0.5 s after a put-away of his own sitter.
  Without it the auto-run covered the whole court and no put-away won.
- Fixed a step-2 regression this surfaced: the drop's dig-out cap fired on
  every slice drive, so every low contact against the slicer was a sitter.

Measured at level 26: the Climb now slopes from 95% of points at the
Shambler to 28-39% at the Champion. The net rushers are still easier than
their neighbours. The log names put-aways. Three new tests; v373.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:25:49 +02:00
wuwiandClaude Opus 5.5 5dd5d71c33 Keep the praise word on screen, and take the cliff out of the groundstroke
Oliver on v371: the praise word is cut off on the left on the iPhone. It
is centred under the player's feet, so out wide it ran past the edge;
every pop is now clamped to the canvas by its measured width.

Step 4, measured first. The rally sim gets a human bot (taps on the timed
ring with a timing spread), a Climb mode and a lost-point breakdown. At
level 26 the ladder falls over six rungs and then goes flat: nearly every
lost point is the player's own early whiff, the CPU barely ever misses,
and the auto-run reaches everything, so no opponent dial decides points.
A quality ramp, a follow-through and CPU put-aways were each measured
and reverted; the options go to Oliver in PROJECT.md.

Shipped: in the rally modes q no longer drops from 1 to 0.43 one ms past
PERFECT; it falls smoothly to the window's edge (TUNE.qSeamless). A tap
30 ms early is q 0.86 instead of 0.61. Same window, same whiff edge. v372.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:01:24 +02:00
wuwiandClaude Opus 5.5 e25047ed0c End a shot's topspin dip at the bounce, so a kicking ball kicks up
A shot's extra gravity is its dive in flight, but it was carried through
the bounce: heavy topspin skidded away low and Oliver met nearly every
ball 0-25 cm off the grass. After its bounce a ball now falls under plain
gravity (tennis modes only), and every planner that rolls a bounce
forward switches at the same moment. The higher bounces pushed the
auto-run into volleys, so it now takes a kicking ball at the top of its
bounce, up to chest height. Median contact rises from 0.42 to 1.13 m at
the bottom of the ladder. v369.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:38:01 +02:00
wuwiandClaude Opus 5.5 4e7c816a25 Give the rally its length back: deep balls, baseliners, approaches off short balls
Every match had collapsed into serve, both at the net, reflex volleys at
~0.7 s per shot. The rally ball landed on the service line by definition,
the match CPU stood on the bounce and volleyed 90-100% of everything, and
the auto-run chased the earliest contact.

Rally modes only (classic + every match; gore and the duel untouched):
rally balls land deep and mistiming only shortens them (no new long outs);
each shot latches the receiver's plan as it leaves the racket — from the
back he lets it bounce and meets it falling, up to 2.2 m behind the line,
a short ball pulls him in and he follows it to the net, nobody approaches
a man already there, and a volley below the tape is a weak block. Measured:
contacts 10.5-13.7 m from the net, back-court volleys 0-8%, 0.8-1.0 s per
baseline shot. Three new tests pin the shape; v361.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:55:05 +02:00
wuwiandClaude Opus 5.5 f33d46366a Diagnose why every rally ends in a net duel
Oliver: every match converges on serve, both at the net, reflex volleys,
won by a wrong-foot. Measured headless: rally balls land on the service
line by definition, the match CPU stands on the bounce point and volleys
90-100% of everything from opponent 6 up, and the auto-run always picks
the earliest contact. Diagnosis, research and a four-step plan go into
PROJECT.md (awaiting his go); tools/rally-sim.mjs is the gauge. Fallback
tag rally-baseline-v360 marks the shipped feel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 12:32:36 +02:00
wuwiandClaude Opus 5.5 806a739c6f Add MEMBERSHIP, the club's own 1980s VHS advert
cut.py --cut ad: a plummy announcer (one gpt-audio read per line, ad.sh)
sells St. Mordred's over the creepiest takes with yellow 80s supers, a
PLAY/STOP VCR read-out, two testimonials from the real lines and the small
print read at speed, until the game's umpire says "Quiet." and the jingle
dies. A VHS grade (chroma smear, scanlines, tape wobble) is the cut's own.
gen.py learns a voice command; one new silent Doris take.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:46:31 +02:00
wuwiandClaude Opus 5.5 da09b55525 Add FIFTEEN–LOVE, a 19-second umpire-scored spot
cut.py --cut score: no interview audio, only the game's own recorded
umpire. "Spectators are reminded to remain seated, especially the
deceased", then a love game called against the viewer, one member's stare
per point under a broadcast score bug, "Game. Set. Massacre." on black,
and "This match is still in progress" over the logo. cut.py now holds
named cuts, each with its own build folder and output file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:28:28 +02:00
wuwiandClaude Opus 5.5 2de45510a3 Add a 36-second cutdown of the trailer
cut.py --short builds a social-length version from the same takes: one
line per witness cut inside their takes, then the challengers beat,
"Quiet, please", "Play", the splat and Reg's stinger. Each cut keeps its
own build folder and output file, so cut 2, cut 3 and the short all stay.
words.py gives local Whisper word timestamps for cutting inside lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:09:05 +02:00
wuwiandClaude Opus 5.5 5fba837ead Tighten the trailer to 1:30 and fix its two audio faults
Cut 3 of LIFETIME MEMBERS: the intro music no longer runs into Reg's first
line, Ambrose finishes "...still waiting for a result" (line ends are now
measured off each take instead of the QA transcript), every shot is
tighter, and the black title cards are set larger. Cut 2 stays on disk
beside it as the reference.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 10:56:50 +02:00
wuwiandClaude Opus 5.5 d388004eac Add the LIFETIME MEMBERS trailer pipeline
A vertical live-action mockumentary trailer: the dead staff of St. Mordred's
(the game's bosses) each tell a different origin story, and the film ends on
"Quiet, please." / "Play." / splat. tools/trailer/ holds the whole pipeline:
stills and takes through the OpenRouter key (gen.py, stills.sh, clips.sh),
the frame graphics in HTML/CSS (frame.html), a QA listener (qa.py), the
music sectioner (segment.py) and the edit (cut.py). Media lands in the
gitignored promo/trailer/. SCRIPT.md is the screenplay and the cut notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 20:27:13 +02:00
wuwi a09856f8c9 Streamline mobile menus and refresh splash logo 2026-09-07 13:26:17 +02:00
wuwiandClaude Opus 5 532dd3b83e The shot list documents itself: all eight tins, five beats, ten bosses
The header block in tools/scenes.json is now the whole schema — every key with
its range and default, what each of the EIGHT weapons does (fire, laser and gun
were missing from both the docs and the validator), the five beats, the crowd
roster diversity walks in order, the bosses by chapter, and the traps worth
knowing: a serve tin is spent in about four seconds of autopilot fire, a burst
tin owns its own window, a horde locks the rack, a boss cannot start inside a
match, and `movement` fights the match's own auto-run legs.

Two scenes added from the campaign's own wish list: `epidemic` (the fire ball
lighting a whole wave off the body it hit) and `champion` (chapter ten, the
night court). Both verified on film.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 13:34:17 +02:00
wuwiandClaude Opus 5 472c86b36e The shot list becomes a config file, and the camera holds a phone
tools/scenes.json says WHAT to shoot; tools/clips.js only knows how. Every
knob Oliver asked for is a key: seconds, setting (gore/zombie), beat, court,
boss, weapons, movement, density, diversity, gore, games, screen — documented
in the file's own "_" block, validated in capture.py so a typo names itself
instead of coming back as fifteen seconds of empty court. Nine scenes ship in
the default list, across all four courts.

The frame is a PHONE now (393x852 -> 1080x2340), not 9:16: the portrait branch
derives its logical height from the canvas box, so a 9:16 take was never the
framing a player sees. The player has legs — held arrow keys through the real
axisX, so horde and flamer are no longer a statue with a flamethrower. The
crowd tops itself up where the game's own spawner puts it, diversity walks the
roster, and `gore` paints in the run's history a fifteen-second clip has no
time to earn. The pilot is picked by what the court is doing rather than by
config: tennis mode taps to swing, splatter draws the slingshot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 13:25:59 +02:00
wuwiandClaude Opus 5 491f3b97f1 The highlights shoot themselves: one command, seven vertical clips
`python3 tools/capture.py` fills promo/clips/ with 1080x1920 h264/aac takes of
the moments the campaign plan (item 4) already named — transition, horde,
flamer, mopboy, death on the gore side, boss and match on the zombie-tennis
side. capture.py serves the repo with tools/clips.js injected, opens a
throwaway-profile Chrome and converts each POSTed webm with ffmpeg; clips.js
stages every scene through the real doors on window.T and drives it with the
reachability soak's own mediocre autopilot. Nothing is faked for the camera.

The game gains four names on window.T (start, intoSplatter, startHorde,
sendBoy) and nothing else: the frame is pinned by the canvas box rather than
the window, RES 4 comes from lowPower 0 plus device-scale-factor 3, and the
audio is tapped by making BaseAudioContext's `destination` a gain node — so
audio.js needs no master bus for a tool that ships to nobody. tools/ and
promo/clips/ are ignored by git and docker alike.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 13:07:21 +02:00