New /art-dev skill (SKILL.md + blender-cookbook + style-and-practices refs) driving LANTERN Blender art work: Auto (headless) for simple changes, the hybrid nudge-and-bake loop for precision/aesthetics, game-camera verification, Blender-beginner coaching. Session log covers the A0 style-proof asset set + the Bathynaut refinement. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6.5 KiB
Style essentials + Blender best-practices (LANTERN art-dev)
The binding style lives in Art_Direction_Lantern (constitution) + Lantern_Art_Pipeline_Recipes (manual). This file is the operative subset to hold in-head during a session, plus the Blender-beginner coaching the operator needs. When this and the art docs disagree, the docs win.
The five rules that shape every asset
- One material, color by UV placement. Never texture/unwrap per asset. Model → place each face's UV onto a palette-atlas colour band (
Closest-filtered) → flat colour. Three shader roles only: Lit-Palette (statics), Emissive-Gloam (glows), Skinned-Palette (creatures/suits, deformation-aware). Batching + coherence + zero texture skill = the solo-dev factory. - Faceted low-poly, silhouette-first. Flat shading (
face.smooth=False). The read is the shape + light, not detail — "a readable blob with a great light beats a detailed model nobody can see." - Budgets (hard): props ≤ ~800 tris · creatures ≤ ~3k · hero/boss/suit-frame ≤ ~6k. Report tris every time; over-budget → decimate or drop parts (e.g. body OR armour, not both).
- The palette IS the ontology: warm gold/amber = true light (ours) · cold corpse-green/blue = gloam (the deep's counterfeit) · lure-red = bait · white-hot = conversion. Pick an asset's emissive hue for what it is (diver beacon = warm; wisp/gloam-enemy = cold green; ambient flora = cold teal; lure = red).
- The readability law: value-first (carry every warm/cold read by luminance + shape + flicker-cadence, not hue alone — steady = true, flicker = false; this is the colorblind answer). Reads at 200 px. A capture grade (lifted/saturated) for shots; the murk grade is darker.
Rig families (skinned assets — clips are made per FAMILY, not per creature)
| Family | Body plan | Members | Base to kitbash |
|---|---|---|---|
| Drifter | spine-chain swimmer | Wisp-Choir motes, lure-fish, serpents | procedural blobs + tail beads (no humanoid rig) |
| Crawler | legged/scuttling | Grindylow, kappa-kin, Tenders | (quadruped — separate rig) |
| Strider | biped-ish | Drowner, Wrecker, suit-frames | Synty humanoid (SM_Chr_* in the combined FBX) |
Suit-frames = kitbash on the Synty humanoid (helmet/tank/plate swaps over the proven rig); a custom silhouette sculpt is a later upgrade, not a blocker.
Assets built so far (in <repo>/ArtSource/Blender/, the style-proof set)
Prop_CargoCrate (92 tris, statics/palette proof) · Prop_GlowFlora (380, teal ambient) · Creature_WispMote (110, gloam-green Drifter) · Creature_Drowner (2742, Synty-crew Strider kitbash — gloam skin, hunched, bone-parented glowing eyes) · Suit_Bathynaut_Kitbash (8.4k ⚠ over hero budget — body+armour+kit; game-ready pass must pick body-or-armour + decimate). Concepts: suit kit + wisp not rig-bound; drowner posed not animated. Pending: the in-engine Unity bake + the 3 master ShaderGraphs (esp. Emissive-Gloam's flicker param).
Coaching a Blender beginner (the operator)
On every handoff, give a short numbered, literal step list — only the keys they need for that step — and one line on why (the best practice). The vocabulary:
| Do this | How (tell them exactly) |
|---|---|
| Orbit the view | middle-mouse drag (or numpad 4/6/8/2) |
| Zoom | scroll (or Ctrl+MMB drag) |
| Pan | Shift+MMB drag |
| Frame selected | Numpad . (or View ▸ Frame Selected) |
| Front / side / top view | Numpad 1 / 3 / 7 |
| Select an object | left-click it; Shift+click to add to selection |
| Move (grab) | G, move mouse, left-click to confirm, Esc/right-click to cancel |
| Move on one axis | G then X/Y/Z (e.g. G Z = up/down only) |
| Scale / Rotate | S / R (same confirm/cancel; add an axis letter to constrain) |
| Save | Ctrl S |
- Hand the operator only intuitive direct-manipulation (grab/scale/rotate a selected object onto a target). Keep the fiddly/risky ops (mode switches, modifiers, bmesh, export settings, materials) headless on my side.
- When one axis is hard to see in a single view (depth), tell them to ignore it — "place it in this front view, I'll snap the depth after" (raycast/shrinkwrap).
- Explain the why briefly so they learn: flat shading = the low-poly look; UVs onto a band (not unwrapped) = the shared-material rule; apply transforms before export = correct scale in Unity; under the tri budget = it stays cheap in the dark.
- If a request would break a rule (e.g. "paint a texture", "make it super smooth/high-poly"), say so plainly and offer the palette-correct / budget-correct way.
Best-practice do / don't
Do: faceted flat shading · UVs placed on atlas cells · metric units, 1 u = 1 m · feet at z=0, origin sensible · apply rotation/scale before export · pack textures before saving the .blend · one shared material per asset · report tris vs budget · verify with a hi-res render under murk, judging silhouette + value + 200px · also render from the game camera (top-down ARPG, Pitch 45°/FOV 55°), both facings — put detail + emissive accents on TOP-facing surfaces (crown/shoulders/back-pack), not the face the camera never sees · keep each asset a separate master .blend under ArtSource/Blender/.
Don't: per-asset texture/unwrap · smooth-shade the low-poly forms · exceed the tri budget silently (log the upgrade if you ship a placeholder) · overwrite a Synty pack FBX (GUID refs — new files only) · write into Assets/ while a Unity session may be live · trust a dark screenshot (check material values) · trust WorldRenderBounds/bone reads for a skinned/posed mesh (they return the bind AABB — use the operator's eyes) · leave emission at strength 4–6 on AgX (whites out — Standard + saturated color, ~1.5–3).
The pipeline into Unity (hand off to /dots-dev)
Statics: model → export .glb → collider policy (cosmetic = strip colliders/no ghost; blocking = Environment collider baked into the gameplay subscene, mesh Read/Write on) → assign the shared M_Lit_Palette → bake into subscene → verify baked CollisionWorld + a Play screenshot. Skinned: Humanoid rig → per-action clips (Key All Bones, bake-to-pose) → FBX → Rukhanka ingest (CreateFromThisModel) → Skinned-Palette → prefab via EnemyRigTools (ownerless interpolated ghost; server strips Rukhanka). Full checklists + gotchas → Lantern_Art_Pipeline_Recipes + CLAUDE.md (Animation / Art-import sections).