The crowd sheet becomes an animation sheet: three frames, and the stand sits back
Oliver: "when clapping I barely see any movement at all now.. also all of the art could be colored a little more dim as it is perspective wise farther in the background and should not steal too much attention" — and then, "can't we make an animation sprite sheet of the new crowd?", which is the answer to the first half of the first one. A third roll (_crowdroll.py mid) takes the arms-up frame as its reference and asks for the same standing people with their hands brought together in front of their faces. It drifts by 53% of its pixels and that does not matter: the same filter keeps only what was stand and became person. 100 arm blobs in pose 1, 74 in pose 2, 134 spectators once merged, 28 of them owning BOTH poses — those 28 cycle between two raised poses, which is a clap; the rest alternate with the seated frame, which is arms going up and down. The point is the cycle, not the pose. A raiser is ~8x6 logical px on a phone and one that appears and then holds for a second is not something the eye catches; arms moving at 3.5 Hz is. Measured: 2-3% of the stand band now changes every 90 ms during a won game, against near zero before. The sheets are one file per court now — three frames stacked, graded as a single image so they cannot drift apart in colour — and x_crowd2/_c2/_h2 are deleted. TUNE.standBack 0.22 dims the crowd and the boards on every court before the night court's own dim and the splatter rot, in the one function both the cached backdrop and the live raisers already read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1ad2898530
commit
0250e9bd20
14 files changed
+333
-198
No files matched your search
+52
-20
@@ -21,8 +21,8 @@ the state-machine contracts that have historically produced the show-stoppers. T
|
||||
it as a build stage, so a red suite cannot deploy — but finding out from Coolify is the slow way.
|
||||
|
||||
Last updated 2026-08-21 (THE CROWD: rolled again, in far more detail, once for all three courts;
|
||||
the clap frame is now the seated sheet plus the raised arms and nothing else, and the stand animates
|
||||
ONE SPECTATOR AT A TIME off `src/crowd.js`. The wave, the idle fidget, paparazzi that scale with the
|
||||
every frame is the seated sheet plus that pose's raised arms and nothing else, the sheet is a real
|
||||
three-frame animation sheet, and the stand animates ONE SPECTATOR AT A TIME off `src/crowd.js`. The wave, the idle fidget, paparazzi that scale with the
|
||||
moment, and an aww that still claps. See "THE CROWD, ROLLED AGAIN". Before that 2026-08-20 (THE SHELL: a Capacitor iOS project, haptics on the existing sfx call
|
||||
sites, portrait enforced in Info.plist, and swipe-left-to-go-back in the menus — the web build
|
||||
unchanged and still primary. See "THE SHELL"). Before that, same day: the friend across the net gets his OWN sheets — the player's kit, drawn
|
||||
@@ -348,24 +348,36 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu
|
||||
`mopRound` walks him to a stain, holds him there for `TUNE.boyMopDwell` while the push cycle
|
||||
animates in place, then moves him on. Three sheets: `x_boymop` (stopped, working),
|
||||
`x_boycarry` (walking with the mop shouldered), `x_boyrun` (tennis-mode fetch).
|
||||
- **THE CLAP FRAME IS THE SEATED FRAME PLUS THE ARMS, and that is meant literally.** `x_crowd2` is
|
||||
built FROM `x_crowd` by `assets/_crowdpass.py`, which copies only the pixels that were STAND in
|
||||
the seated roll and became PERSON in the clap roll — 93 pairs of raised arms and hands, 1.2% of
|
||||
the sheet. Not the raiser's face, not his shirt, not his seat: those are the seated sheet's own
|
||||
pixels and cannot drift. Each pair of arms has a box in **`src/crowd.js`** (generated), and
|
||||
render.js raises **one spectator at a time** out of that table. It was NOT true before 2026-08-21:
|
||||
the clap sheet was a separate roll that differed from the seated one in 13-16% of its pixels,
|
||||
everywhere, so the animation re-hashed the crowd rather than raising arms — Oliver, "the crowd
|
||||
wobbles with a client side animation right now.. that feels odd." **Never hand-edit one crowd
|
||||
frame, and never edit `src/crowd.js`.** Re-roll with `_crowdroll.py`, then re-run `_crowdpass.py`,
|
||||
which rebuilds the pair, the three court grades and the table together. Draws stay integer-aligned
|
||||
with **no vertical offset**: a fractional `dy` on a scaled image re-snaps its pixel rows every
|
||||
frame under nearest-neighbour — that boiling beside the HUD was the "scoreboard flicker".
|
||||
- **THE CROWD SHEET IS AN ANIMATION SHEET, and every frame of it is frame 0 plus arms.** One file
|
||||
per court, `FRAMES` frames stacked vertically: 0 seated (what the cached backdrop draws), 1 arms
|
||||
raised high, 2 hands together in front of the face. `assets/_crowdpass.py` builds 1 and 2 by
|
||||
copying, out of two further rolls, ONLY the pixels that were STAND in the seated roll and became
|
||||
PERSON — about 1.2% of the sheet each. Not a raiser's face, not his shirt, not his seat: those are
|
||||
frame 0's own pixels and cannot drift. **`src/crowd.js`** (generated) boxes each of the 134
|
||||
spectators who can move, with a mask of which raised frames they appear in — 28 own both, and
|
||||
those 28 cycle between the two poses, which is a clap rather than an appearance. render.js
|
||||
animates **one spectator at a time** out of that table.
|
||||
It was NOT true before 2026-08-21: the clap sheet was a separate roll differing from the seated
|
||||
one in 13-16% of its pixels, everywhere, so the animation re-hashed the crowd rather than raising
|
||||
arms — Oliver, "the crowd wobbles with a client side animation right now.. that feels odd."
|
||||
**Never hand-edit a crowd frame, and never edit `src/crowd.js`.** Re-roll with `_crowdroll.py`,
|
||||
then re-run `_crowdpass.py`, which rebuilds every frame, all three court grades and the table
|
||||
together. Draws stay integer-aligned with **no vertical offset**: a fractional `dy` on a scaled
|
||||
image re-snaps its pixel rows every frame under nearest-neighbour — that boiling beside the HUD
|
||||
was the "scoreboard flicker".
|
||||
- **A raiser is ~8x6 logical px, so a pose that appears and holds is invisible.** What reads as
|
||||
applause is the CYCLE — arms high, hands together, up, down, at about 3.5 Hz — and how many people
|
||||
are doing it at once (`crowd.pop`). Oliver on the first per-person cut: "when clapping I barely see
|
||||
any movement at all now."
|
||||
- **The three courts are ONE crowd, graded.** `x_crowd`, `x_crowd_c` and `x_crowd_h` are the same
|
||||
roll under three per-channel histogram matches onto the courts' old palettes, so anything the
|
||||
crowd art gains shows up on all three. They were three separate rolls until 2026-08-21, and the
|
||||
cost of that was exactly what Oliver reported of the first pass: "the whole thing somehow does not
|
||||
translate well to the other courts, there the difference is barely visible."
|
||||
roll under three per-channel histogram matches onto the courts' old palettes, applied to the whole
|
||||
stack at once so the frames cannot drift apart in colour. They were three separate rolls until
|
||||
2026-08-21, and the cost of that was exactly what Oliver reported: "the whole thing somehow does
|
||||
not translate well to the other courts, there the difference is barely visible."
|
||||
- **The stand sits BACK.** `TUNE.standBack` (0.22) dims the crowd and the boards on every court,
|
||||
before the night court's own `dim` and the splatter rot. Oliver: "all of the art could be colored
|
||||
a little more dim as it is perspective wise farther in the background and should not steal too
|
||||
much attention." It is the only thing on screen that is thirty metres away.
|
||||
`assets/_sheet_crowd1.png` is the pre-brightening original of the FIRST crowd, kept for history.
|
||||
|
||||
## Settled feel decisions — do not regress silently
|
||||
@@ -2314,7 +2326,7 @@ it is the WRONG tool, superseded by the reference-sheet flow. Route by job:
|
||||
| THE SAME CHARACTER IN SOMEONE ELSE'S CLOTHES, every pose at once | `_frontroll.py` — famroll's trick pointed at the tennis poses: image 1 is the ten `o_*` frames composed from disk, image 2 is the body to dress them in. Two calls made the whole netplay family. Ten `_regen` batches would have been ten chances for the man to drift. |
|
||||
| Single-sheet remaster, boss roster, any non-family sprite | `_regen.py` + `_regen_batches.json` — the only jobs it is still for. |
|
||||
| Standalone art (logo, panels) | `_key.py`; coarse legacy sheets, `_slice.py`. |
|
||||
| The CROWD — the art itself | `_crowdroll.py` (two rolls: the seated master, then the same picture with arms up) -> `_crowdpass.py` (throws the drift away, keeps the arms, grades the three courts, writes `src/crowd.js`). Both frames of all three courts come out of one run; there is no such thing as editing half of it. |
|
||||
| The CROWD — the art itself | `_crowdroll.py` (three rolls: `seat`, then `clap` from it, then `mid` from that) -> `_crowdpass.py` (throws the drift away, keeps the arms, stacks the frames, grades the three courts, writes `src/crowd.js`). Every frame of all three courts comes out of one run; there is no such thing as editing half of it. |
|
||||
|
||||
**And when installed sprites look WORSE than the `_refcheck/fam_*.png` sheet they came from, the
|
||||
suspect is the CUT, not the roll** — the sheets on disk are the evidence, and a re-cut is free (see
|
||||
@@ -2595,6 +2607,26 @@ never the right tool. It is deleted. The art is rolled.
|
||||
- **MORE PHOTOGRAPHERS.** `TUNE.flashEvery` 5.0 -> 1.9. At a five-second mean, jittered, spread over
|
||||
a stand this wide, Oliver never saw one.
|
||||
|
||||
### The clapping was invisible, and the stand was too loud (2026-08-21, same day)
|
||||
|
||||
*"when clapping I barely see any movement at all now.. also all of the art could be colored a little
|
||||
more dim as it is perspective wise farther in the background and should not steal too much
|
||||
attention."* Then: *"can't we make an animation sprite sheet of the new crowd?"* — which is the right
|
||||
question and the answer to the first half of the first one.
|
||||
|
||||
- **A THIRD ROLL, and the sheets became animation sheets.** `_crowdroll.py mid` takes the arms-up
|
||||
frame as its reference and asks for the same standing people with their hands brought together in
|
||||
front of their faces. It drifts harder than the first (53% of pixels) and it does not matter: the
|
||||
same filter keeps only stand-turned-person. 100 arm blobs in pose 1, 74 in pose 2, 134 spectators
|
||||
once merged, **28 of them with both poses** — those 28 cycle between two raised poses, which is a
|
||||
clap; the rest alternate with the seated frame, which is arms going up and down. Either way the
|
||||
stand is now MOVING rather than holding, and that is what the eye catches at 8x6 logical px.
|
||||
Measured: 2-3% of the stand band changes every 90 ms during a won game, against near zero before.
|
||||
- **One file per court instead of two.** Three frames stacked vertically, graded as one image so the
|
||||
frames cannot drift apart in colour, and `x_crowd2`/`x_crowd_c2`/`x_crowd_h2` are deleted.
|
||||
- **`TUNE.standBack` 0.22** — the whole stand, on every court, pushed back before anything else is
|
||||
added. One knob, applied in the one place both the cached backdrop and the live raisers read.
|
||||
|
||||
## THE STAND STOPS WOBBLING, AND STARTS BEING A CROWD (2026-08-21)
|
||||
|
||||
*"the crowd spritesheet could use some love (resolution and movement wise)... also the crowd wobbles
|
||||
|
||||
Reference in new issue
Block a user