ip-dressup

Community@yizhizhi/ip-dressup
Community skill — not reviewed. It was shared by 吱吱 and has not been checked by Neta. Read SKILL.md below before letting an agent use it.
Use it in Cohub

Paste this into your agent's chat — it fetches the skill and follows it.

Use the skill: ip-dressup. Run `npx -y @neta-art/neta-search-cli@latest skills use @yizhizhi/ip-dressup --via site` and follow what it prints. Read its complete output, redirecting it to a temporary file first if necessary, and resolve relative paths from the skill directory it prints.
Install from a terminal
npx -y @neta-art/neta-search-cli@latest skills use @yizhizhi/ip-dressup
Summary

Build a dress-up mini-game web Work styled after any IP (a world's setting, characters, places and pictures) — mobile portrait first, with a desktop / landscape layout. Up to three modes share one shell: object dressing (a 3D item you can spin and open — ball, bottle, box, medal, sword, crown, wand…), character outfits (2.5D layered portrait) and room decorating (one-point-perspective room, optional pets that live in it). The shell copies the IP's official UI, ships 11 languages, original music, autosave, currency / quests / shop / try-on and a shareable certificate card. Use when the user wants a dress-up, outfit, makeover, room-decorating or "customise the item" game for their world or a known IP. Not for a chat roleplay, a single picture or a journal app (that is ip-journal). Triggers - dress-up game, outfit game, makeover game, decorate my room game, wardrobe game, 换装小游戏, 装扮小游戏, 给某 IP 做换装, 布置房间, 捏魔杖, 做一个装扮游戏, 着せ替えゲーム.

SKILL.md
# IP dress-up mini-game

The user ends up with one published web Work: a small game that looks like it came from the IP itself — its official site's buttons and frames, its fonts, its palette, its music — where they sort into a faction, dress up an item / a character / a room, try it out, and save a certificate card. The engine never changes; each IP is a **world pack** (content, assets, skin, music, fonts).

Read this file fully before generating anything or writing files. Resolve relative paths from this skill's directory (`$SK` below).

## Language

Reply in the user's language, whatever language this file is in. This holds for every message of the run, above all the final handover; translate what the scripts print, don't paste it. Text the user sees in the deliverable — Work title, game title, buttons, labels, quiz, certificate — follows the user's language: the game ships 11 languages (en, zh, zh-TW, ja, ko, fr, de, es, it, pt, ru), follows the device language and falls back to English; write the Work title in the user's language. Text the user typed (names) stays as they wrote it.

## When to use / when not

Use when the user wants a dress-up / outfit / makeover / room-decorating / item-customising game for a world or IP. Not for: a chat roleplay, one illustration, a character card, a journal or scrapbook app (ip-journal), a general game with levels and combat — say this skill makes a dress-up mini-game and stop.

## Inputs

| Item | Required | Counts as given when |
|---|---|---|
| The IP / world | yes | The chat runs in a world that has `world/WORLD.md` (that world is the IP), or the user names an IP. "Something fun" with no world and no IP does not count. |
| Which modes (object / character / space) | no — default: choose 1–3 from the world per `docs/01-brief-and-modes.md` and state the choice in one line | The user names a mode ("an outfit game" = character, "decorate the dorm" = space, "make a wand" = object). |
| Reference images / official site | no — default: search the official site and game UI yourself (`docs/02-official-ui.md`) | |
| Shop owner, currency, factions, certificate wording | no — default: map from the world (`docs/01`) | |

If a required item is missing, ask for it once, in one message, before building — then stop. If every required item is given, do not ask anything and do not wait for a go-ahead: build through to delivery. If a choice is risky (e.g. which mode is most iconic), state the default you take and continue in the same turn.

## Directory

```
SKILL.md                 this file: contract, steps, hard rules
docs/                    detail for each step (read the one a step names; 14/15/16 = validation logs for Love and Deepspace, Pokémon, the web layout)
engine/                  the shared engine — never put IP text, art or colours in it
  index.html  engine/{engine.js,engine.css,wide.css,audio.js,economy.js,pets.js,store.js}  engine/renderers/{obj3d,rod3d,doll25d,room25d}.js  vendor/three
templates/objects/       obj3d templates (ball, bottle, box, medal, sword, ring, crown, lantern, mug, slab, shield)
tools/                   generation, layer cutting, full-body outfit fix, room measuring, slicing, fonts, i18n, assembly, screenshots, self-checks
scripts/verify.mjs       the self-check the review gate reads (writes verify-report.json)
worlds/<sample>/         three finished sample world packs (harry-potter: all three modes + pets; love-deepspace: character + space; pokemon: character + obj3d ball + space)
```

A world pack (what you build for the user's IP) has `BRIEF.md`, `research/NOTES.md`, `content/config.js` (+ `content/i18n/<lang>.json`), `glossary.json`, `theme.css`, `songs.js`, `fonts.json`, `assets/`, `gen/` — see `docs/05-content-pack.md`.

## Steps

Working folders: `$RUN=_runs/ip-dressup/<slug>/` under the workspace root; the world pack is `$W=$RUN/world`, the assembled site `$SITE=$RUN/site`. Never write into this skill's own folder (`worlds/` are read-only samples) and never move or delete `$RUN` afterwards. Start a new pack by copying the sample closest in tone (`cp -r $SK/worlds/<sample>/content $SK/worlds/<sample>/theme.css … $W/`) and replacing everything IP-specific.

1. **Read the world** — `world/WORLD.md` (visualStyle), characters, places, lore; with Neta tools also `neta atom list` / `neta atom get <id>`. Copy what you use into `$W/input/world/` (read-only). → `$W/BRIEF.md` §0 (`docs/01`).
2. **Generation probe** — generate the IP's 3–5 most iconic things (signature creature / object / place) once at low quality to see what copyright moderation refuses. → BRIEF §0.5. Refused things are replaced by names, colours, original symbols or scenes — never by rewording the prompt to sneak past it.
3. **Pick modes and map the concepts** (factions, reveal, shop owner, try-out actions, certificate, currency). → BRIEF §1–2 (`docs/01`).
4. **References + official UI, measured** — official pages, in-game UI, key art; read computed styles; decide dark or light shell; compare fonts glyph by glyph. → `$W/research/NOTES.md`, `$W/theme.css`, `$W/fonts.json` (`docs/02`, `docs/03`).
5. **Assets** (all generation through `$SK/tools/gen.py`, which retries and falls back to another image model):
   - object: pick a template from `templates/objects`, only seamless materials / sticker sheets are generated (`docs/06`);
   - character: base figure → "add only this one item" edits → semantic mattes → layers (`tools/char_build.py`; full-body outfits then `tools/fullbody_fix.py`) (`docs/07`);
   - space: empty room → `tools/room_measure.py` → big-item edits → layers (`tools/room_layers.py`, `tools/room_items.py`) (`docs/08`); pets `docs/09`.
   → `$W/assets/`.
6. **Content pack** — `$W/content/config.js`, every string as `T(en, zh)` (`docs/05`).
7. **Music** — summarise the IP's soundtrack style only, write an original WebAudio score → `$W/songs.js` (`docs/10`).
8. **Languages** — `python3 $SK/tools/i18n_pack.py $W --forbid "<names from the sample pack you copied>"` → `$W/content/i18n/` (official names per language from `$W/glossary.json`, `docs/11`).
9. **Assemble + fonts** — `$SK/tools/assemble.sh $W $SITE` (runs `check_assets.js`); then `FONT_OUT=$W/assets/fonts python3 $SK/tools/build_fonts.py $SITE <font source dir> $W/fonts.json` and assemble again (`docs/03`).
10. **Check** — serve `$SITE` (`python3 -m http.server`), then:
    - `node $SK/scripts/verify.mjs $SITE` — passes when the site has every asset it references, all 11 languages, every mode's UI text, ≤ 1000 files and no engine file changed; it also runs `tools/web_check.sh` on every mode at 1440×900 and 390×844 when a browser is available. It writes `$SITE/verify-report.json`. Fix every FAIL and rerun; do not deliver while it fails.
    - `tools/flow.sh` full-flow screenshots at 390×844 and 1440×900, and look at every screen against `docs/12-checklist.md` (faces not covered, every full-body outfit zoomed at neck / armpits / cuffs, pets at real-world size next to furniture).

## Deliver

One route: a **web Work** (the assembled static site).

- With Neta tools (`/mods/neta` exists): `node /mods/neta/neta work init web works/webs/<slug> --title "<game title in the user's language>"` → `node /mods/neta/neta work publish web works/webs/<slug> --from $SITE --title "<same title>"`.
- Without them (a plain Cohub space): `cohub public upload $SITE <slug>-vN` (new path every version, `docs/13-deploy.md`) and hand over the `…/index.html` link it prints.
- Before handing over, check the core content is in it: every chosen mode opens (`?m=<mode id>`), the quiz reaches a result, the workshop shows options with thumbnails, the try-out and the certificate render.

Then, as the last step — the run is not delivered until it is done:

11. **Hand over with a card.** One `interaction-components` link card on its own line, target `{ "type": "work", "workId": "<id>" }`, the id taken from the publish output (fallback: `cohubWorkId` in `works/webs/<slug>/meta.json`). Never a made-up id, a folder or a `world-file` link to `index.html`. Then one or two lines on what is inside (the modes, how to switch with `?m=`), in the user's language, and say plainly what you could not check (headless browsers show ~3 fps and no sound — ask the user to check smoothness and music on a real device).

## Out of scope

- Do not change world settings (WORLD.md config, visual style, slug) or delete files that existed before the run.
- Do not modify memory, character cards, installed scripts (including this skill's own files and sample worlds), existing Works or roleplays.
- Make only the one game Work; do not act on your own next-step suggestions.
- No backend features in the static Work: AI furniture (`tools/ai_server.py`) and cloud save stay hidden unless the user asks and a backend exists (`docs/13`).
- No official logos, crests or the original protagonists' faces; no prompts reworded to get around a refusal.

## When to stop

- No world and no IP named: ask which IP, once, then stop.
- Asked for something this skill does not make (a roleplay, a single picture, a journal app, a level-based game): say this skill makes a dress-up mini-game and stop.
- A generation is refused by moderation: replace that thing by name / colour / original symbol (hard rule 11) and continue; do not stop the run for it.

## Hard rules (each comes from explicit user feedback — breaking one means rework)

**Product**
1. **Mobile portrait first, and the web must work well** (`docs/16`): narrow / portrait = phone layout; wide (≥ 900 px and landscape) = stage left, panel right, mode nav centred in the header, pop-ups start below the header, a ✕ close button and "scroll / right-drag / double-click" hints with a mouse (`ui.xxxDesk`). Wide positions live only in `engine/wide.css`. No dialogue or hint may cover something interactive or a character's face.
2. 1–3 modes per IP; with one mode there is no bottom nav. Don't force a mode the IP doesn't have (no pets if nobody owns one) — but never drop the IP's most iconic object for technical reasons: objects can be any shape (`docs/06`, obj3d); if image generation can't draw it, see if it can be modelled procedurally.
3. **Every mode autosaves** and resumes; "start over" asks twice and clears only that mode. Several IPs on one domain are separated by `meta.saveNs`.
4. With a currency there is a **visible quest list**, a daily login and achievements; expensive items are **tried on before buying**, and the buy pop-up shows only the item itself (no head). Claiming feels good: a bubble next to it, a smooth arc into the wallet, the number ticking up.

**Visual**
5. **UI copies the official site, measured**: computed styles, colour statistics, side-by-side screenshots; buttons, badges, dividers, hover and entrance motion all from the same system. Official art is reference only — redraw with the same structure. A light IP can't be a recoloured dark skin: change the shape language too (`docs/02`).
6. **Everything visible follows the IP**: icon frames, selected states, certificate colours, night tint, particle colours, instrumentation, shop owner — nothing left over from the previous IP.
7. **Fonts**: pick substitutes glyph by glyph; every visible string uses a bundled font (system fonts measure differently and break centring); **one font family and one language per screen**.
8. **Pixel-level spacing and centring**: pill and icon buttons off by ≤ 0.5 px (measured on 3× screenshots); no hard-coded pixel offsets — use the runtime `inkFit()`.
9. **No cheap motion**: never slide a flat image as "animation"; no non-rigid warping of a portrait; summoning = particles sampled from the outline converging; flight paths are smooth arcs.
10. **Full-body outfits never show the clothes underneath**: zoom on neck, armpits, cuffs, wrists of every gown / dress; fix with `tools/fullbody_fix.py` (`docs/07`). Pets and furniture are **real-world size** (a cat ≈ 0.3 m, `petScale: 1`), never enlarged "to be visible" (`docs/09`).
11. Things placed on / next to a character follow its real outline, not fixed offsets; floating objects get a ground cue (shadow / glow / drop line).
12. Original work: characters don't resemble real actors; don't draw the original protagonists' faces (use names, colours, keepsakes, scenes); no official logos or crests; the page says it is a fan prototype. **What moderation refuses is replaced, not reworded** — a descriptive "yellow electric mouse" is still a knock-off.

**Engineering**
13. No IP text, art or colours in the engine; a new ability is a **config option** (keeping Harry Potter's old behaviour), never `if (IP === …)`.
14. Measure interaction-triggered work with `performance.now()`; optimise anything over 16 ms.
15. Test languages by **switching**, not by opening in that language; every UI change is clip-checked in phone + short-window sizes × 11 languages (`tools/audit.sh`).
16. **Run `tools/web_check.sh` on every screen** (phone + wide): buttons alone on a row are centred, every button on the top layer is clickable (a transparent overlay or a class-name clash makes buttons dead), every ✕ really closes with a real click. Watch CSS specificity: `.kind-space.has-nav .sheet` beating `.sheet.in` kept the panel from ever sliding in — screenshot every mode of every world pack after a change.
17. **Screenshot your own change before handing over**; say honestly what a headless browser cannot show (smoothness, sound).

## References — read when the step names them

| File | Read when |
|---|---|
| `docs/01-brief-and-modes.md` | steps 1–3: brief template, generation probe, choosing modes, concept mapping |
| `docs/02-official-ui.md` | step 4: measuring the official site, dark vs light shell |
| `docs/03-fonts.md` | steps 4 and 9: choosing, downloading and subsetting fonts |
| `docs/04-assets.md` | step 5: `gen.py`, sprite sheets, image-service pitfalls, copyright |
| `docs/05-content-pack.md` | step 6: the full `window.GAME` shape |
| `docs/06-object.md` / `07-character.md` / `08-space.md` / `09-life-economy.md` | step 5 for each mode; pets and economy |
| `docs/10-motion-audio.md` | step 7 and any motion work |
| `docs/11-i18n.md` | step 8 |
| `docs/12-checklist.md` | step 10, every time |
| `docs/13-deploy.md` | Deliver, and environment recovery after a sandbox reset |
| `docs/14`–`16` | when building a light-shell IP (14), a "creature is the IP" world (15), or touching the wide layout (16) |

## Known limits

- Pet life is not config-driven yet: `pets.js` gaits are written for owl / cat / toad / rat and `tools/pet_poses.py` for Harry Potter's six pets.
- AI furniture and cloud save need a backend; they are hidden in a static Work.
- Thin chains and wire frames that are barely brighter than skin get lost in mattes (`docs/07`).
- obj3d builds procedural parts only; organic shapes (plush toys, animal-shaped mugs, clothes) need 2.5D layers or a 3D generator (untested).

## Gotchas

- `assemble.sh` wipes its output folder: never point it at `works/webs/<slug>` (it would delete `meta.json`); assemble into `$SITE` and publish with `--from`.
- Image service: 1024×1024 sometimes comes back 1254×1254 — resize rooms back to spec before measuring; transparent requests sometimes come back opaque grey — trust mattes, not alpha (`docs/04`).
- High generation concurrency triggers "add credits / billing" errors although single calls work: keep `GEN_PAR` at 2–3.
- Full-body outfit layers cut only the outfit; the school uniform of the base figure shows at neck and cuffs, and the wand hand (cut from the base figure) brings its old cuff along — `tools/fullbody_fix.py` handles all three.
- `petScale` above 1 made a cat taller than an armchair seat; small pets stay tappable through `Life.tap`'s minimum hit size, not by scaling.
- In the wide layout pop-ups (z 42–44) sit under the header (z 45): they must start below it or long quest lists lose their top.