Oliver: "look at the headless men — the trouser color changed." He was right and
every number in kit() said he was not. Brightness sat at 85 against the healthy
frame's 89, comfortably inside tolerance, while the shorts' blue-minus-red
walked from a warm charcoal -8.7 to a cold +0.2 across the wound stages. All
three existing measures are greyscale or red-channel; none of them can see a
grey going blue, which is most of what "the colour changed" ever means here.
Fourth number: the shorts' hue. It immediately fails the headless men AND finds
a second drift in the wounded women that the brightness test had passed.
The tolerance default went to four entries deliberately — kit_off zips got/ref/
tol, so a three-long tuple would have SKIPPED the new check rather than failed
it. That is the same shape of silent no-op as the read-only floodfill.
Also: DAMAGE NOW ACCUMULATES. Stage 2 said only "headless", so the arm torn off
at stage 1 came back — in a mode where the score IS the body, taking a point off
it made the body look healthier. Stage 2 is now headless AND still one-armed.
And the stride rule got its counterweight: "copy it exactly, only the legs
change" has a second failure mode where the model copies it exactly INCLUDING
the legs and returns the same picture twice (upper 0.017, legs 0.022 — a body
sliding along with frozen feet, the very thing being fixed). Both halves are
stated now: identical above the hips, obviously different below.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Oliver, on the sprites, again: "when people on a tennis court walk or run their
legs move... this pattern is almost always failing." It has failed repeatedly
because NOTHING IN THE PIPELINE MEASURED IT. Frame count, magenta background,
clipped edges and detail density all pass cleanly on two unrelated
illustrations of the same character, which is exactly what the generator
produces when asked for "the same frame with the other leg forward".
Three numbers per declared pair, silhouette only, on the feet-aligned centred
overlay drawStatic actually draws:
HGT height ratio — off 1.00 means the body grows and shrinks once per step
TOP difference ABOVE the hip — near zero for a real pair: same man, same camera
LEG difference BELOW it — this is the step
Calibrated on the pairs that read (brute wound lurch 1.00/0.000/0.638, shambler
1.00/0.070/0.520) against the ones that do not (TOP 0.47-0.85, or LEG 0.09).
Opt-in per batch via `stride: [[i, j]]`, because the player's four-frame RUN
sits at TOP 0.23 and is right — a run swings the arms too.
`--audit` runs the same gate over the sprites ALREADY INSTALLED and exits
non-zero on a failure: a gate that only fires on new rolls says nothing about
the art already in the game, which is where this was noticed. Five of the six
racket pairs fail it today.
And the kit gate, which already existed and was never switched on here: Oliver
spotted the headless men's trousers had changed colour. Measured — the headless
set's near-white fraction DOUBLES (9.5 -> 19.5) where losing a head only
accounts for ~1.3 of that, and the wounded swing drifted the other way (shorts
60.5 against its own stage's 85). palette_ref + a per-batch tolerance now catch
all three drifted sets and pass the one that looked right.
Fixed while in there, mine from the last commit: the wounded stride stepped off
walkT, a wall clock, while the healthy one steps off ground covered — the exact
foot-slide this project banned for the heavy bodies.
No art regenerated yet: the gate and the audit come first, so a re-roll can be
told from a lucky one.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every roll drifts the palette and nothing measured it: a white headband on six
frames, pale grey shorts on the toss twice, brick-red shirts and brown shoes on
the swing all sailed past --tries. check: "same"/"loose" skips colour_match, and
colour_match is a global mean/sd fit far too weak to pull brick-red back to red
— a nearest-colour palette lock is worse still, it drags the duller reds into
the racket's browns.
So _regen.py measures three numbers and a batch opts in with palette_ref:
redness (r minus mean(g,b) over saturated warm pixels — brightness alone cannot
tell brick-red from red), shorts brightness (charcoal 61 vs the drift's 83), and
the near-white fraction that is the shoes and socks (brown drops it to 0.9%,
pale shorts push it to 7.9%, correct frames sit at 2.8%). Frames known to be
right cluster tightly on all three; every drifted frame fell outside on at least
one. It rejected five bad rolls in a row, then passed a good one.
The swing also kept re-inheriting its own drift: ref_sheet is built from
[lead] + the sprites being replaced, so it was showing the generator the very
brick-red frame it was about to overwrite. Copying a canonical frame over the
targets first breaks the loop — it passed on the next roll.
Swing is now a real backswing and follow-through (silhouettes differ by 1.0,
racket low behind vs up over the shoulder), both at full standing height, and
the toss and smash wear charcoal shorts again.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>