Create Codex Pet
Create visual work with $imagegen. Use the bundled scripts only for deterministic extraction, assembly, previewing, cleanup, and validation.
Resolve resources
Resolve paths relative to this SKILL.md:
- plugin root:
../.. - scripts:
../../scripts - specifications:
../../references
Require Python 3.9 or newer and Pillow. Before acting, read:
../../references/codex-pet-contract.md../../references/animation-rows.md../../references/qa-rubric.md
Inputs
Accept one or more photos plus optional name, description, personality, style, and motion preferences. Infer omitted metadata conservatively.
Write a short identity lock before generation:
- species or character type
- body proportions and scale
- face, eyes, ears, coat, markings, and palette
- distinctive physical traits
- rendering style and lighting
- personality expressed through motion
Treat the photos and identity lock as authoritative. Preserve breed traits and physical proportions; do not beautify the subject into a generic pet.
Workflow
1. Prepare
Create an isolated run directory:
python3 ../../scripts/prepare_pet_run.py \
--pet-name "<name>" \
--description "<short description>" \
--reference /absolute/path/to/photo.png \
--pet-notes "<identity lock and personality>" \
--style-preset auto \
--output-dir /absolute/path/to/run
Inspect imagegen-jobs.json. A visual job is ready only after every depends_on job is complete.
2. Establish identity
Use $imagegen to generate one centered, full-body canonical reference from all defining photos. Use a flat removable chroma background, with no scenery, text, cast shadow, or detached effects.
Copy the selected result to the job's decoded output and to references/canonical-base.png. Do not mark a job complete until the selected image exists at its decoded path.
3. Generate standard rows
Generate one complete horizontal strip per state. Attach the canonical base and the state layout guide to every request. Keep the same face, proportions, markings, material, scale, and baseline.
Generate idle and running-right first. Generate independent remaining rows concurrently when possible. Mirror running-left only when markings, lighting, props, and identity remain correct.
For each completed strip, immediately run:
python3 ../../scripts/extract_strip_frames.py \
--decoded-dir /absolute/path/to/run/decoded \
--output-dir /absolute/path/to/run/frames \
--states "<state>" \
--method auto
python3 ../../scripts/inspect_frames.py \
--frames-root /absolute/path/to/run/frames \
--json-out /absolute/path/to/run/qa/rows/<state>.json \
--states "<state>" \
--require-components
Repair only the failed row. Use stable-slots only when the source strip is well-spaced and per-frame extraction caused visible scale or baseline popping.
4. Review motion before look directions
After rows 0–8 pass, compose the standard atlas, contact sheet, and timing-accurate GIFs:
python3 ../../scripts/compose_atlas.py \
--frames-root /absolute/path/to/run/frames \
--output /absolute/path/to/run/final/spritesheet.png \
--webp-output /absolute/path/to/run/final/spritesheet.webp
python3 ../../scripts/make_contact_sheet.py \
/absolute/path/to/run/final/spritesheet.webp \
--output /absolute/path/to/run/qa/contact-sheet.png
python3 ../../scripts/render_animation_previews.py \
--frames-root /absolute/path/to/run/frames \
--output-dir /absolute/path/to/run/qa/previews
Inspect the contact sheet and every preview. Reject identity drift, unnatural anatomy, clipping, overlap, incorrect direction, static loops, scale pops, baseline jumps, or a first-to-last snap.
5. Generate look directions
Generate and approve a four-pose cardinal strip in this order: up, screen-right, down, screen-left. Then generate row 9 as one coherent eight-pose family and row 10 as one coherent eight-pose family. Never generate or repair an isolated final look cell.
Use the fixed clockwise order from animation-rows.md. Keep the body anchored and express gaze through natural eyes, eyelids, head, ears, neck, and subtle upper-body follow-through. Cardinals must be unmistakable at actual display size.
Assemble rows 9–10 with assemble_extended_atlas.py, create the direction QA sheet, and measure continuity. A direction repair replaces its complete eight-frame row.
6. Finalize and package
Run the single chroma despill pass, then validate:
python3 ../../scripts/despill_chroma_edges.py \
/absolute/path/to/run/final/spritesheet-extended.png \
--output /absolute/path/to/run/final/spritesheet-extended.png \
--webp-output /absolute/path/to/run/final/spritesheet-extended.webp \
--chroma-key "<run chroma key>" \
--json-out /absolute/path/to/run/qa/chroma-despill.json
python3 ../../scripts/validate_atlas.py \
/absolute/path/to/run/final/spritesheet-extended.webp \
--json-out /absolute/path/to/run/final/validation.json \
--chroma-key "<run chroma key>" \
--require-v2
Package only a passing atlas:
<pet-id>/
├── pet.json
└── spritesheet.webp
Set spriteVersionNumber to 2. Preserve the run's contact sheet, animation previews, direction sheet, validation JSON, and final spritesheet as the review record.
Non-negotiable rules
- Generate visual content with
$imagegen, never procedural drawing. - Generate complete row strips, never ask an image model for a finished atlas.
- Keep every pet inside a
192x208cell and the final atlas at1536x2288. - Use exact frame counts and app timings from
animation-rows.md. - Preserve the same individual animal or character across all rows.
- Repair the smallest valid scope: one standard row or one complete look row.
- Do not package until deterministic validation and normal-size visual review both pass.