Both players run from a video, and the middle chip finally plays you

Six sessions of asking an image model for a row of running figures, and it
never once drew a gait: three phases repeated with the same leg leading,
"ropeskipping, not running". A frame-by-frame LEFT/RIGHT skeleton spec, a
closing checklist, a loop clause, six figures instead of eight — all lost.
One 5-second image-to-video clip has no such problem, because it moves a
body instead of drawing poses. ~$0.42 a character through the key already in
.env, pose pinned at BOTH ends (pinned only at the front, she rotated into
profile halfway), stride period MEASURED off the frames rather than sampled
by eye — hers repeats in 6 clip frames, his in 23 — and the phases cut and
palette-snapped through _stride.cut. assets/_vidroll.py films and cuts it;
her first frame came from one still roll that took his approved pose as a
picture instead of a paragraph.

Wired: runN probes the sheet through SK() so the women's tour counts HER
frames, the player is no longer clamped to a two-frame pair, runHz 2.4 ->
1.9 ("this looks like roadrunner"), and the bench grew two PLAYER stops —
a cycle only ever seen mid-rally is a cycle nobody has watched.

Also in: the difficulty retune (medium is a real step above the shipped CPU
and is where `smart` first appears; hard stepped back off superhuman; easy
closed its gap) with MEDIUM's dial-for-dial pin to TUNE removed from the
test, and Oliver's own transparency fixes on the male frames.

SPRV 138 — the frames were right on disk and wrong on screen for an hour
because assets are cached for a year unless the ?v= moves. main.js v269.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Opus 5 committed 2026-08-15 17:53:58 +02:00
1 parent 2b7eb04e19
commit 1b7fc2cdcf
23 files changed
+352 -71

No files matched your search

+8 -11
View File
@@ -1251,8 +1251,9 @@ test('classic wears the match feel, and the difficulty table is a ladder', () =>
assert.ok(rallyFeel(), 'classic is a rally mode');
assert.ok(assistK() >= TUNE.matchAssist, 'classic gets the match assist floor');
G.classic = false;
// ...and DIFFS climbs monotonically on every dial, with MEDIUM pinned dial-for-dial to the
// shipped TUNE values so the middle chip can never drift from what "no difficulty" played like.
// ...and DIFFS climbs monotonically on every dial. MEDIUM used to be pinned dial-for-dial to the
// shipped TUNE values; that pin is gone (Oliver, 2026-08-15: "medium is too easy") — the middle
// chip is now its own tuning, above what "no difficulty" played like, and HARD stepped back.
// (The first cut scaled only flub/cap/speed and Oliver felt no difference — reaction, reach,
// qMin and serve are the dials a player actually reads as skill.)
const [e, m, h] = cfg.DIFFS;
@@ -1265,15 +1266,11 @@ test('classic wears the match feel, and the difficulty table is a ladder', () =>
assert.ok(e.serve < m.serve && m.serve < h.serve, 'harder serves better');
assert.ok(e.smart <= m.smart && m.smart < h.smart, 'harder plays the open court');
assert.ok(e.recover <= m.recover && m.recover < h.recover, 'harder recovers to centre faster');
assert.equal(m.smart, 0, 'MEDIUM aims at random, as the shipped classic did');
assert.equal(m.recover, 0.5, 'MEDIUM keeps the shipped recovery jog');
assert.equal(m.flub, TUNE.classicFlub, 'MEDIUM flub IS classicFlub');
assert.equal(m.quality, TUNE.classicQualityMax, 'MEDIUM quality IS classicQualityMax');
assert.equal(m.speed, 1.0, 'MEDIUM leaves aiSpeed alone');
assert.equal(m.qMin, TUNE.aiQualityMin, 'MEDIUM floor IS aiQualityMin');
assert.equal(m.reaction, TUNE.aiReaction, 'MEDIUM reaction IS aiReaction');
assert.equal(m.reach, TUNE.aiReach, 'MEDIUM reach IS aiReach');
assert.equal(m.serve, 1.0, 'MEDIUM leaves the serve alone');
// EASY is a step below the shipped no-difficulty CPU, MEDIUM a step above it — that ordering is
// the point of the retune, so it stays pinned even though the exact numbers are free to move.
assert.ok(e.flub > TUNE.classicFlub && m.flub < TUNE.classicFlub, 'EASY misses more than shipped, MEDIUM less');
assert.ok(e.reaction > TUNE.aiReaction && m.reaction < TUNE.aiReaction, 'MEDIUM reads faster than shipped');
assert.ok(e.reach < TUNE.aiReach && m.reach > TUNE.aiReach, 'MEDIUM out-reaches shipped');
});
// ---- NETPLAY (src/net.js + beats.startNetVs). The shot is the sync unit and THE RECEIVER OF A