Drawn frames, not procedural fakes: brute lurch, boy stride, crowd applause
Every animation in this round gets real frames. The procedural squash-and-sway on the wounded brute read as fake on sight, and that gait is where the comedy lives. - Each brute wound stage now has its own 2-frame lurch (z_gw/z_gwb, z_gw2/z_gw2b, ...). The generator gave every B frame a dragged pole that only stage 1 actually carries, so it would have blinked in and out each step — stripped by keeping the largest blob, and where the pole touched the body, by cutting on column density (a torso is dense, a dragged pole is a thin diagonal). - Frames step off DISTANCE COVERED, never elapsed time — boy.dist for ball boys, z/bruteStride for brutes. A time-driven cycle moonwalks the moment speed and frame rate disagree, which is exactly what "he slides faster than the animation suggests" was. Change a speed now and the legs keep up on their own. - One boy, one slot. sendBoy no longer replaces a boy already on court: that was the appearing and disappearing, since every kill teleported him back to the wing mid-stride. New mess is appended to his round instead. He now walks for 10.5s a crossing, and there is a lot of mopping to do. - The applauding crowd is a real two-frame animation (seated / arms up), swapped per column on its own phase. The old "smooth wave" still shifted each column by a FRACTIONAL dy, and nearest-neighbour resampling at a fractional y re-snaps a column's pixel rows every frame — that boiling beside the HUD is what read as the scoreboard flickering. The board art is 99.9% opaque; nothing was ever showing through it. With the crowd calm the frame delta is now 0.0%. Benchmarks: 136/150 serve returns (90.7% ±2.4%, the 11/12 bar is inside one sigma), 30 human-tapped points = 50 hits / 0 whiffs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ff77922e85
commit
32401366fe
13 files changed
+77
-36
No files matched your search
+27
@@ -155,6 +155,33 @@ New foundations you must know before touching anything:
|
||||
exists, but only in tennis mode where there is nothing on the grass but a ball. `BOY_H` 1.2 → 1.5.
|
||||
- `TUNE.burnSpread` is a T-panel knob if Oliver wants fire hotter still.
|
||||
|
||||
## Second feedback round — "do it properly" (2026-07-27)
|
||||
Oliver rejected the procedural fakes on sight. The rule this round: **animation gets drawn frames.**
|
||||
- **Every brute wound stage now has a 2-frame lurch** (`z_gw`/`z_gwb`, `z_gw2`/`z_gw2b`, …). The
|
||||
procedural squash-and-sway that replaced them read as fake immediately — "that's where the comedy
|
||||
comes from". Generated by handing the generator a composite of the four A-frames
|
||||
(`assets/_sheet_gwound_a.png`, built with PIL) and asking for the stride swapped.
|
||||
**Gotcha:** the generator gave every B frame a dragged pole, but only stage 1's A frame has one —
|
||||
it would have blinked in and out each step. Stripped by keeping the largest connected blob
|
||||
(stages 2–3) and, where the pole touched the body (stage 4), by cutting on column density: the
|
||||
torso is dense, a dragged pole is a thin diagonal of ~7 px per column.
|
||||
- **Frames step off DISTANCE COVERED, never elapsed time** — `boy.dist` for ball boys,
|
||||
`zb.z / TUNE.bruteStride` for brutes. Time-driven cycles moonwalk whenever speed and frame rate
|
||||
disagree, which is exactly what "he slides faster than the animation suggests" was.
|
||||
Height for a wound stage ALWAYS comes from the A frame or the sprite pops size every step.
|
||||
- **One boy, one slot.** `sendBoy` no longer replaces a boy who is already out — that was the
|
||||
"appears and disappears": every kill teleported him back to the wing, so a kill streak restarted
|
||||
him several times a second. New work is appended to his round (`jobs`). One crossing is now 10.5s.
|
||||
- **The applauding crowd is a real two-frame animation** (`x_crowd` seated / `x_crowd2` arms up),
|
||||
swapped per column on its own phase. The previous "smooth wave" still shifted each column by a
|
||||
FRACTIONAL dy, and nearest-neighbour resampling of a scaled image at a fractional y re-snaps its
|
||||
pixel rows every frame — that boiling beside the HUD was the "scoreboard flicker". The board art
|
||||
is 99.9% opaque, so nothing was ever showing *through* it. **Test:** render twice without
|
||||
stepping — identical pixels means nothing in the draw path rolls dice; and with the crowd calm
|
||||
the frame-to-frame pixel delta must be 0.0%.
|
||||
- Editing a full-scene image (`x_crowd` → `x_crowd2`) preserved the layout far better than expected:
|
||||
mean difference 3.2/255, railing and tier rows unmoved. Worth reusing for other 2-frame swaps.
|
||||
|
||||
## Gotchas learned the hard way
|
||||
- Browser-pane verification: python http.server sends no cache headers, so edited ES
|
||||
modules often load STALE even after location.reload(). Reliable fix: preview_stop +
|
||||
|
||||
Reference in new issue
Block a user