c78768cbdf
Bank the Mark-V lessons: when scripted primitives can't nail an iconic organic shape, generate with Hyper3D Rodin then CONFORM - watertight clean-decimate (weld+recalc first, gentle collapse, 0 boundary edges = hole detector), drop the baked photoreal texture for the shared flat palette, flat-shade, ontology-tie emissives, and don't skin a meter-scale generated mesh onto a cm-scale rig (~100x shrink). Added the generate path to the Build phase + a keystone clause (strip a kitbash/gen mesh's own texture). Also fixed a duplicate section number (12 -> 13). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
105 lines
16 KiB
Markdown
105 lines
16 KiB
Markdown
---
|
||
name: art-dev
|
||
description: Drives a LANTERN art-asset session in Blender (blendermcp) — create a new asset or modify an existing one, staged so a Blender-BEGINNER operator can jump in. Use when the operator types /art-dev or opens art work ("refine the player helmet by doing X", "make a new enemy", "model/kitbash/retexture Y", "fix the eyes on Z"). Does simple changes fully headless; drops into a hybrid nudge-and-bake feedback loop (operator drives, I bake back) for anything needing precision or aesthetic judgment.
|
||
---
|
||
|
||
# /art-dev — LANTERN Art-Asset Session Orchestrator (Blender)
|
||
|
||
Drives a **Blender 5.1 (blendermcp)** art session for the LANTERN art track — modeling, kitbashing, retexturing, posing, and staging assets. **The style is binding and lives elsewhere:** [[Art_Direction_Lantern]] (the constitution) + [[Lantern_Art_Pipeline_Recipes]] (the operating manual) are authoritative; `CLAUDE.md` owns repo conventions (asmdefs, the Unity bake rules, memory layers, git). This skill carries the **process** those don't: how to take an art goal → a staged, reproducible Blender result, working *with* a Blender-beginner operator.
|
||
|
||
The spine: **size by complexity → ground → agree the change → setup scene → BUILD (do-it-all headless, or the nudge-and-bake loop) → verify by render → export/save → (Unity bake) → doc/memory bookend → offer asset commit.**
|
||
|
||
## Non-negotiables (every track)
|
||
|
||
1. **The material keystone ★ — no per-asset texturing, ever.** Every asset shares the ONE palette atlas (`Assets/_Project/Art/Palette/PaletteAtlas.png`) + emissive materials; color = *placing* a face's UV onto a colour band, never unwrap/paint. Three shader roles only: Lit-Palette (statics), Emissive-Gloam (glows — hue/flicker = gameplay info), Skinned-Palette (creatures/suits). This is the solo-dev keystone — deviating breaks batching, coherence, and the whole factory. **A kitbashed or AI-generated mesh arrives with its OWN baked texture — that clash IS the keystone violation; strip it and re-material to the shared palette + flat-shade before it ships** (§14). Detail → [[Art_Direction_Lantern]] + `references/style-and-practices.md`.
|
||
2. **Poly budgets + the readability law ★.** props ≤ ~800 tris · creatures ≤ ~3k · hero/boss/suit ≤ ~6k. Value-first (every warm/cold read carried by luminance + shape + flicker-cadence, not hue alone); reads at 200 px; silhouette-first. Report the tri count on every asset.
|
||
3. **The palette ontology ★.** warm gold/amber = true light (ours) · cold corpse-green/blue = gloam (counterfeit) · lure-red = bait · white-hot = conversion. Steady = true, flicker = false. Pick emissive hues to match what the asset *is*.
|
||
4. **Nudge-and-bake for precision ★.** Never script fine placement/pose/aesthetics blind (a script can't see painted/low-poly features + judges via a low-res grab). Stage + hand off to the operator's live GUI, then **bake the result back into a reproducible form** (bone-local offsets, saved transforms). See *The nudge-and-bake loop* below + [[blender-hybrid-nudge-and-bake]].
|
||
5. **Beginner-coach ★.** The operator is a **Blender beginner.** Every handoff spells out exact keys/clicks (select, `G`/`S`/`R`, orbit = MMB-drag, zoom = scroll, save) and the *why* (the best practice). Teach proactively; never assume Blender fluency. Wrong-but-confident Blender advice wastes their time — verify an operator's-eyes step rather than guess.
|
||
6. **Reproducible + source-art home.** All work persists as a per-asset master `.blend` in `<repo>/ArtSource/Blender/` (OUTSIDE `Assets/` so a live Unity session never auto-imports it), textures **packed** (`File > Pack All`). The script/steps are the source of truth — bake operator nudges back into them.
|
||
7. **Verify by render, not blind orbit.** Judge with a high-res EEVEE **render-to-file** (Read the PNG) under the murk + capture grade; check material *values*, not just a dark screenshot. The ~800px viewport grab is a quick check only (and returns BLACK when the window isn't drawing — `area.tag_redraw()` + re-capture, or ask the operator to focus Blender).
|
||
8. **Asset commits gated; docs commits standing.** New `.blend`/`.glb`/imported assets: **offer** + propose grouping; commit only on explicit "commit". Docs-only (vault / CLAUDE.md / this skill) auto-commit at session end in a `Docs:` group + auto-push `main`→`gitea` (standing auth 2026-07-07); `origin` only when asked.
|
||
9. **Path-portable skill.** No machine-specific absolute paths in this skill/refs. Blender's Python runs outside the harness, so runtime code sets `PROJ = r"<absolute repo root>"` (resolved at runtime) and derives every path from it.
|
||
|
||
## When to use / not use
|
||
|
||
**Use** for any LANTERN visual asset: model a prop/creature/suit, kitbash off a Synty base (licensed to modify), retexture to the palette, pose, add accents (eyes/lamps/kelp), assemble a style-proof composition, or refine an existing `.blend`.
|
||
|
||
**Don't use** for: the **in-engine Unity bake/shader authoring** as the primary job (that's DOTS/editor work — `/dots-dev`; this skill *hands off* to it); pure design/fiction questions (answer directly); non-art tasks.
|
||
|
||
## Size by complexity — do this first (NOT by time)
|
||
|
||
| Track | When | Path |
|
||
|---|---|---|
|
||
| **Auto** | deterministic, no feature-alignment or taste call: resize/rescale, recolour to a band, add a bolt/greeble ring, boolean, duplicate, batch-rename, export | I do it **end-to-end** headless → render → leave it staged & editable → report. |
|
||
| **Guided** | needs precision (align to a painted/modeled feature), aesthetic judgment (silhouette read, "does this look right"), or pose polish | I do the bulk, then **the nudge-and-bake loop** — stage, operator drives, I bake back, iterate. |
|
||
| **New-asset** | a brand-new model/creature/suit from scratch or a Synty kitbash | full spine; the kitbash/model/UV/rig steps are Auto, the placement/pose/silhouette calls are Guided. |
|
||
|
||
Push to do as much as possible in **Auto**; hand off only what genuinely needs eyes-on. Unsure which → one `AskUserQuestion` ("shall I just make the change, or stage it for you to place?"). **Always leave the scene editable** (named objects, relevant pieces selected, a good camera) even in Auto — the operator may want to jump in.
|
||
|
||
## The spine
|
||
|
||
### Phase 0 — Pre-flight
|
||
1. **Blender live?** `get_scene_info` (needs `user_prompt`). No response → blendermcp addon not connected (socket 9876) / window hidden — surface, ask the operator to open Blender + check the BlenderMCP panel. **Blender is 5.1 here** (EEVEE Next; some 4.x APIs differ).
|
||
2. **Which asset / .blend?** New → a fresh per-asset scene. Existing → `open_mainfile` the master `.blend` from `<repo>/ArtSource/Blender/`. Never clobber another asset's scene — one `.blend` per asset.
|
||
3. **Intake gate.** Vague goal ("make it cooler") → one `AskUserQuestion` bundling the real forks (what silhouette / which base / warm-or-cold). A concrete goal ("add a porthole grille to the helmet") → skip.
|
||
|
||
### Phase 1 — Ground (read-only)
|
||
Scan the art canon before touching geometry: [[Art_Direction_Lantern]] + [[Lantern_Art_Pipeline_Recipes]] (budgets, shaders, rig families, ontology), the target's fiction (Grep the vault for the creature/prop name — build *on-fiction*), the palette atlas band layout (`references/style-and-practices.md`), and the machine gotchas ([[blender-mcp-and-unity-mcp-v10]] = FBX-import workaround + ArtSource home; [[blender-hybrid-nudge-and-bake]] = the loop). For an existing asset, `get_scene_info` + `get_object_info` to map what's there. Synthesize a **≤200-word plan** (below).
|
||
|
||
### Phase 2 — Agree the change
|
||
State a short plan: what changes, which track (Auto/Guided), the target budget/silhouette, warm/cold intent, and — for Guided — exactly **which step you'll hand to the operator** and which you'll do. Present forks with a recommendation. For a substantial *new* asset, this is a light gate; for a tweak, a one-liner. Don't over-ceremony a small change.
|
||
|
||
### Phase 3 — Setup scene (standing tooling)
|
||
Establish the LANTERN working scene (snippets → `references/blender-cookbook.md`): metric units (1 u = 1 m); the murk world + warm-key/gloam-fill lights + the capture grade; the palette atlas material (`Closest` filter) + emissive materials; a **fixed render camera** + named views for consistent framing; `view_transform='Standard'` for judging hue (AgX desaturates bright emission to white). These are pure wins — set them even in Auto.
|
||
|
||
### Phase 4 — Build
|
||
- **Model/kitbash (Auto):** primitives via `bmesh.ops`; faceted (flat shading); UVs *placed* on atlas cells (never unwrap); Synty base import via the **5.1 window-override + `ignore_leaf_bones=True, automatic_bone_orientation=False`** workaround; normalize to metres/feet-at-floor. Report tris vs budget.
|
||
- **AI-generate an iconic shape (Auto, last resort):** when scripted primitives can't nail an *iconic organic hard-surface* form (a Mark-V helmet, an ornate horn) and hand attempts read as golf-ball/egg/blob, **generate the base with Hyper3D Rodin** then **conform it** — it arrives as raw photoreal high-poly meter-scale clay that clashes with the flat low-poly body. The conform pass IS the work: clean-decimate to budget (watertight — weld+recalc FIRST, gentle collapse, 0 boundary edges), **drop the baked texture for the shared palette**, flat-shade, ontology-tie any emissive, and (rigid accessory) don't skin a generated mesh onto a cm-scale rig (~100× shrink → invisible). Full recipe → `references/blender-cookbook.md` §14.
|
||
- **Precision / pose / silhouette (Guided) → the nudge-and-bake loop** (next section).
|
||
- Iterate: for Guided, the operator can request modifications ("bigger", "move it", "add another there", "stage the vent for me") — treat each as a mini Auto or a new stage. Keep going until they're happy.
|
||
|
||
### Phase 5 — Verify
|
||
High-res EEVEE **render-to-file** → Read the PNG (murk + capture grade); judge silhouette + value + ontology at full size AND ~200px. **Render from the GAME CAMERA too, not only a hero 3/4 ★** — this is a top-down ARPG (Pitch 45° / FOV 55°, rig values in `references/blender-cookbook.md` §9), and detail belongs where the camera actually looks: top-facing surfaces (crown, shoulders, back-pack) read; the face/underside barely does. Check **both facings** (front + back-away). Check material *values* if anything looks off (a dark render hides bugs). Report tri count. For skinned meshes, `WorldRenderBounds`/bone reads return the bind AABB not the deformed pose — use the operator's eyes.
|
||
|
||
### Phase 6 — Export / save
|
||
Save the master `.blend` to `<repo>/ArtSource/Blender/<Type>_<Name>.blend`, **Pack All** first (a Synty `.psd` pack-warn is harmless). Export a `.glb` (statics) / per-action FBX (skinned) per the recipes with correct scale settings — only when an export is actually wanted (concept assets can stay `.blend`-only). **Never write into `Assets/`** while a Unity session may be live.
|
||
|
||
### Phase 7 — Unity bake (optional, hand off)
|
||
The real A0/game path is the in-engine bake (collider policy, assign the shared material, subscene, Rukhanka for skinned). If the editor is busy/another agent holds it → **stay read-only on Unity**, note the bake as the pending follow-up. Otherwise hand to `/dots-dev` (statics recipe / skinned recipe in [[Lantern_Art_Pipeline_Recipes]]).
|
||
|
||
### Phase 8 — Doc + memory bookend
|
||
Session log → `Docs/Vault/07_Sessions/<year>/<YYYY-MM-DD>_<Topic>.md`; a new reusable gotcha/technique → update [[blender-mcp-and-unity-mcp-v10]] or [[blender-hybrid-nudge-and-bake]]; a new reusable placement offset / rig fact → bake it into `references/blender-cookbook.md` so the next asset starts correct. CLAUDE.md self-maintenance if a rule changed (40 KB budget — archive, don't delete).
|
||
|
||
### Phase 9 — Report + offer commit
|
||
Summary; what changed (repo-relative paths); tris vs budget; render verdict; what's staged/editable for the operator; the pending Unity bake. **Commit docs + push gitea** (standing); **offer** asset commits — keep each asset with its `.meta`/sidecar, stage explicit paths, never `git add -A`.
|
||
|
||
## The nudge-and-bake loop (the heart of Guided)
|
||
|
||
The operator has a **live Blender GUI** — use it for the last 20% (precision + taste) a script can't do. Three steps, iterated:
|
||
|
||
1. **I stage (headless):** build/position the pieces at a best guess; **name** them clearly; give them a temp **bright emissive marker** material so they're unmistakable; float them clearly in view (in front of the target, not buried); **select** them (active = the first); set flat `MATERIAL` shading so the *target* feature (painted eyes, panel line) is visible; frame the area; screenshot the start state. Then hand off with **exact beginner steps**.
|
||
2. **Operator drives (GUI):** they nudge/scale/rotate onto the target while watching full-framerate. Tell them which axis to ignore when tooling can fix it ("place it in this front view — don't worry about depth, I'll snap it"). They can also request changes ("make it bigger", "add another", "stage the next piece"). Wait for "done".
|
||
3. **I bake back (headless):** read the objects' `matrix_world`; snap the hard-to-see axis with a **raycast or shrinkwrap** to the surface; restore the real palette/emissive material; **parent to the driving bone** (`CHILD_OF`, `inverse_matrix=(arm.matrix_world @ pb[bone].matrix).inverted()`) so it rides the rig; and **express the placement as a bone-local offset** (`(arm.matrix_world @ pb[bone].matrix).inverted() @ world_pos`) — the reusable value so the NEXT asset on that rig starts correct with no re-nudge. Symmetrize L/R for the default. Save. Confirm with a render.
|
||
|
||
Code for every step → `references/blender-cookbook.md`. Alternatives when nudging is awkward: the **empty-marker handshake** (operator drops empties, I snap geo to them) and **shrinkwrap** (auto-conform to a surface).
|
||
|
||
## Beginner-coach rules
|
||
|
||
- On any handoff, give a **numbered, literal** step list: how to select (left-click; Shift-click to add), grab (`G`, move mouse, left-click to confirm, `Esc`/right-click to cancel), constrain to an axis (`G` then `X`/`Y`/`Z`), scale (`S`), rotate (`R`), orbit (middle-mouse drag / numpad), zoom (scroll), frame selected (`Numpad .`), and **save** (`Ctrl S`) — only the ones they need for that step.
|
||
- Explain the **why / best practice** briefly (flat shading for the low-poly look; UVs onto a band not unwrapped; apply transforms before export; keep under the tri budget; one shared material).
|
||
- Prefer letting me do the risky/fiddly Blender ops (mode switches, modifiers, export settings) headless; hand the operator only intuitive direct-manipulation.
|
||
- If an operator request would break a non-negotiable (e.g. "just paint a texture on it"), say so and offer the palette-correct way.
|
||
|
||
## Operator gates (same as the project standard)
|
||
Present forks don't auto-decide · no time/effort estimates · never silently defer/descope · tuning-defaults autonomy (sensible defaults + let them tune) · aggressive-cleanup only on explicit opt-in.
|
||
|
||
## Boundaries
|
||
**Stop and consult:** intake too thin · goal contradicts the style bible / a locked decision · a silhouette/identity call with no clear best answer · a precision step that needs the operator's eyes · a destructive op (overwrite/delete an existing `.blend` or Synty source) outside the agreed change · Unity mutation while another agent may hold the editor (stay read-only).
|
||
**May loop without consulting (≤3):** setup/export/render retries · an axis-probe → pose fix → re-render · a black-viewport `tag_redraw` re-capture.
|
||
**Never:** overwrite a Synty pack source (GUID refs) — new files under `ArtSource/`/`Assets/_Project/Art/`; per-asset texturing / unwrapping; write to `Assets/` during a live Unity session; hardcode a machine path into the committed skill.
|
||
|
||
## References (load on demand)
|
||
- [`references/blender-cookbook.md`](references/blender-cookbook.md) — copy-paste-ready blendermcp code: scene/lights/camera setup, palette + emissive materials, atlas band map + cell-UV, faceted-primitive + UV-placement helper, the 5.1 Synty-FBX import workaround, normalize scale/feet, pose-bone axis-probe + set, the full nudge-and-bake stage + bake-back (raycast depth-snap, Child-Of parent, bone-local offset), shrinkwrap, high-res render-to-file (+ black-viewport fix), export (glb/FBX) + save/pack.
|
||
- [`references/style-and-practices.md`](references/style-and-practices.md) — the binding style essentials (palette ontology, readability law, budgets, the 3 shader roles), the palette atlas band layout, the rig families, and the Blender-beginner cheat-sheet + best-practice do/don't.
|