Files
heros_web/docs/unit-sprite-handpaint-pipeline-guide.md

6.1 KiB

Hand-Painted Sprite Pipeline Guide

This guide captures the current approved/pending workflow so future unit work stays consistent.

Current Gate

  • Review state manifest: unit-sprite-rework-manifest.json.
  • Do not produce the next unit until unit-shu-infantry v3 is approved.
  • Do not commit, push, or deploy while a sample is pending approval.
  • Current pending sample: docs/unit-sprite-shu-infantry-v3-approval-packet.md.
  • Current visual approval board: docs/unit-sprite-current-approval-board.png.
  • Next prepared target after approval: docs/unit-sprite-batch2-shu-spearman-spec.md.

Source Image Contract

Generate each unit as a 6 column x 2 row contact sheet on a flat #ff00ff background.

Required 12 cells:

  1. front idle
  2. front walk step
  3. east walk side
  4. back walk
  5. west walk side
  6. attack windup
  7. attack strike 1
  8. attack strike 2
  9. command gesture
  10. item/strategy gesture
  11. hurt recoil
  12. victory pose

The source image must have:

  • full-body figures, no cropping
  • stable scale across cells
  • no labels, UI, grid lines, watermark, or checker background
  • weapon/class silhouette visible at 50px
  • enough padding that weapon tips can be contained in 313px frames

Sheet Assembly Contract

The generated source is converted into:

  • Base sheet: 5008x1252, 4 rows x 16 frames
  • Action sheet: 11268x1252, 4 rows x 36 frames
  • Frame size: 313x313
  • Direction rows: south, east, north, west
  • Base columns: 8 idle + 8 walk per direction
  • Action groups: attack 10, strategy 8, item 8, hurt 4, celebrate 6

The current reference implementation is scripts/assemble-handpaint-shu-infantry-quality-sample.py.

Default execution regenerates the pending Shu infantry v3 sample:

python scripts\assemble-handpaint-shu-infantry-quality-sample.py

After unit-shu-infantry v3 is approved, reuse the same assembler for the next unit by changing only the source, stem, titles, labels, and output prefix. Example for the prepared Shu spearman target:

python scripts\assemble-handpaint-shu-infantry-quality-sample.py `
  --source docs\handpaint-batch2-shu-spearman-source-v1.png `
  --stem unit-shu-spearman `
  --work-dir tmp\handpaint-shu-spearman `
  --output-prefix handpaint-batch2-shu-spearman `
  --contact-title "Shu Spearman Hand-Painted Sample" `
  --before-title "Shu Spearman Previous / Hand-Painted Sample" `
  --before-scale-label "Previous / new at battle scale" `
  --report-title "Shu Spearman Hand-Painted Sample" `
  --sample-label "shu spear" `
  --compare-stems unit-liu-bei,unit-guan-yu,unit-zhang-fei,unit-shu-infantry,unit-shu-spearman `
  --compare-labels liu-bei,guan-yu,zhang-fei,shu-infantry,shu-spearman

Extraction Rules

  • Remove chroma-key background.
  • Despill magenta edge color.
  • Convert body pixels to fully opaque alpha.
  • Keep detached effects only for explicitly reviewed action frames.
  • Idle/walk frames should keep only the main connected body component.
  • Mirror east-facing poses for west only when the generated west pose is not reliable.
  • Keep feet/bottom alignment stable.

Required Commands

After assembling a unit:

python scripts\audit-unit-sprite-sheets.py
python scripts\render-unit-sprite-review-boards.py
python scripts\check-unit-sprite-art-quality.py
python scripts\check-unit-sprite-approval-gate.py --mode sample
python scripts\write-unit-sprite-next-steps.py
python scripts\check-unit-sprite-workflow-consistency.py
python -m py_compile scripts\audit-unit-sprite-sheets.py scripts\render-unit-sprite-review-boards.py scripts\assemble-handpaint-shu-infantry-quality-sample.py
pnpm build

Then verify in a PC browser preview and confirm console errors are 0.

For pending sample approval, open the local battle with a debug-only sprite preview:

http://127.0.0.1:4173/heros_web/?debug&debugSpritePreview=unit-shu-infantry&v=shu-infantry-debug-preview

The debugSpritePreview panel renders the requested unit at 72px, 50px, and one action frame inside the real battle scene. It is only shown when debug tools are enabled and does not appear during normal play.

Visual Review

Always inspect:

  • per-unit contact sheet
  • animation GIF
  • previous/new comparison
  • 50px/72px scale comparison
  • battle map composite
  • debug sprite preview battle screenshot, when reviewing a pending sample
  • current approval board, docs/unit-sprite-current-approval-board.png
  • relevant batch inventory board, for example docs/unit-sprite-review-batch2-shu.png

The current approval board is the primary artifact for judging whether a pending sample is good enough. Batch inventory boards are secondary; they include old queued assets by design and must not be read as completed deliverables.

The audit distinguishes technical validity from art approval:

  • approved-baseline: approved hand-painted reference units.
  • pending-approval: a prepared sample that must not be expanded, committed, pushed, or deployed yet.
  • queued-rework: units still waiting for hand-painted rework, even if their sheet dimensions are technically valid.

These stages are loaded from unit-sprite-rework-manifest.json. Technical audit results and art approval must remain separate.

Use python scripts\check-unit-sprite-approval-gate.py --mode sample while a sample is awaiting approval. Use --mode release only after approval and manifest promotion; release mode intentionally fails while pendingApproval is non-empty.

After explicit user approval, promote the approved pending sample with the helper script instead of editing the manifest by hand:

python scripts\promote-unit-sprite-approval.py --unit unit-shu-infantry --expected-version v3
python scripts\audit-unit-sprite-sheets.py
python scripts\render-unit-sprite-review-boards.py
python scripts\check-unit-sprite-approval-gate.py --mode release

Acceptance Bar

A unit can move to approval only when:

  • it is visibly stronger than the old placeholder
  • it reads at 50px without rings/badges/glows
  • it has no ghostly transparency
  • it has no detached idle/walk fragments
  • it passes the audit script as ok
  • it passes scripts/check-unit-sprite-art-quality.py
  • it matches the approved hand-painted style direction