From 6cc9799536901397da8c705c9e8c0adc3172d1bb Mon Sep 17 00:00:00 2001 From: Oliver Rieger Date: Fri, 14 Aug 2026 08:57:25 +0200 Subject: [PATCH] Route by job, not by file size: the tool table fresh sessions needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Oliver's concern, after the un-chunking: a fresh session walked straight into _regen.py and diagnosed from there, twice — first the legacy prompts, then the model's rolls — while the real bug sat in the cutter, provable by putting any fam_ sheet next to the sprite cut from it. The family-pipeline section already demoted _regen.py, but 270 lines below the "Asset pipeline" heading, and the session memory that routed the last investigation pointed at _regen by name. So the routing is now the FIRST thing under "## Asset pipeline": a which-tool-for-which-job table that names _famroll -> _zsheet for families, marks _regen.py as the single-sheet remaster tool it still is (bosses, players, crowd, weapons — those jobs keep it alive, so it stays), and states the diagnostic rule that would have saved two days: when installed art looks worse than the _refcheck sheet it came from, the suspect is the CUT, and a re-cut is free. _regen.py's own header says the same, for whoever opens it first anyway. The "Only ink votes" lesson joins the family-pipeline section with the numbers: 0.0% of ink blocks uniform at b=11 against 99.2% of empty ones is how a detector proven on single-row sheets quietly broke on 9-row geometry — the threshold never changed, the data under it did. Co-Authored-By: Claude Fable 5 --- PROJECT.md | 41 +++++++++++++++++++++++++++++++++++++++++ assets/_regen.py | 6 ++++++ index.html | 2 +- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/PROJECT.md b/PROJECT.md index f98d1c7..7da9aca 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -1606,6 +1606,25 @@ Clear the intro first: `document.getElementById('intro')?.remove()`. - **Never trust a single sample.** aiFlub is 9%; a 20/24 run is normal noise. Use 150. ## Asset pipeline + +**WHICH TOOL FOR WHICH JOB — read this before opening any `_*.py` (2026-08-14).** A fresh session +reaches for `_regen.py` first, because it is the biggest file and the oldest name — and for most jobs +it is the WRONG tool, superseded by the reference-sheet flow. Route by job: + +| The job | The tool | +|---|---| +| A whole opponent family (31 sprites, one character) | `_famroll.py` -> `_zsheet.py` — see "THE ZOMBIE FAMILY PIPELINE" below. **Never `_regen.py`**: nine separate rolls is nine chances for the character to drift, which is why the family pipeline exists. | +| Rebuild the pose reference | `_famref.py` — composed from disk, no API call, gated. | +| Player/opponent run cycles | `_runroll.py`. | +| A stride twin (legs frozen) | `_stride.py`. | +| 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`. | + +**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 +"Only ink votes" below). Seven families shipped pixelated for two days because every fresh look +started from "the generator drew it badly" instead of diffing sheet against sprite. + 1. `generate-image` skill (needs `OPENROUTER_API_KEY` in the gitignored repo `.env`; run with the scratchpad venv python — system python lacks `requests`). Passing the existing sheet as `--input` (edit mode) nails the style and is how every matching sheet here was made. @@ -1921,6 +1940,28 @@ uv run --with pillow --with numpy python assets/_zsheet.py assets/_refcheck/fam_ `uv run --with …` is how these run: this machine's python has no PIL or numpy of its own, and the previous session's interpreter was a uv ephemeral env. `SPLAT_PY` still overrides for `_regen.py`. +### Only ink votes: how seven fine families shipped pixelated (2026-08-14) + +`_fine.block_size()` finds the generator's art-pixel grid by scoring b×b blocks for uniformity — and +it scored ALL of them. `key()` zeroes the background, a zeroed block is uniform at every b, and on a +9-row family sheet the background is ~85% of the figure bounding box, so the background ALONE cleared +the 0.82 bar at any block size tried. Measured on `fam_ru.png`: 0.0% of ink blocks uniform at b=11, +99.2% of empty ones, overall 0.821 — detected block 11, and `_zsheet` then honestly snapped 428 px +figures down to 39 art px and scaled them back up. The pixelation was manufactured in the cut; every +sheet the model returned was fine. br survived at 0.775 only because its ink coverage runs four +points higher, and the whole per-family chunkiness ranking (br fine … ch/ru/sh/st at 6 px blocks) was +ink-coverage noise around one threshold. Background-only blocks get no vote now, and all eleven +families were re-cut from the sheets already in `_refcheck/` — no new rolls, no tokens. + +Two rules fall out of it: +- **A detector proven in one geometry is unproven in another.** `block_size` was validated on + single-row `_regen` sheets where figures fill the bounding box; the 9-row family sheet silently + inverted its ink/background ratio. The threshold never changed — the data under it did. +- **Diff the artifact against its source before blaming the source.** The chunky sprite and the fine + sheet it was cut from sat side by side on disk for two days. One `Read` of each would have located + the bug immediately; instead the first two theories (legacy `_regen` prompts, model roll variance) + both blamed generation. Oliver's screenshot pair settled it in one glance. + **A frozen stride pair in the master blocks the whole pipeline, by design.** `_famref.py` refuses to write the sheet if any of the three stride pairs has legs that barely move — because the model copies what it is shown, so a frozen pair in the reference is a frozen pair in every family drawn off it. diff --git a/assets/_regen.py b/assets/_regen.py index 25a8447..2981609 100644 --- a/assets/_regen.py +++ b/assets/_regen.py @@ -1,5 +1,11 @@ # _regen.py — redraw a batch of sprites at real pixel-art resolution, end to end. # +# ROUTING — CHECK BEFORE USING. This is the SINGLE-SHEET remaster tool (boss roster, players, crowd, +# weapons — anything without a family). A whole opponent family is NEVER built here: that is +# _famroll.py -> _zsheet.py (PROJECT.md, "THE ZOMBIE FAMILY PIPELINE"), because nine separate rolls +# is nine chances for the character to drift, and it took every one of them. See PROJECT.md +# "WHICH TOOL FOR WHICH JOB" for the full routing table. +# # python3 assets/_regen.py shambler_a # one batch # python3 assets/_regen.py --list # what batches exist # python3 assets/_regen.py --all # everything not already done diff --git a/index.html b/index.html index d35cc31..078f770 100644 --- a/index.html +++ b/index.html @@ -431,6 +431,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') { - +