Files
Project-M/.claude/skills/art-dev/references/style-and-practices.md
T
kronic 2b78c68424 Docs: /art-dev skill + art-track kickoff session log
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>
2026-07-14 14:40:08 -07:00

6.5 KiB
Raw Blame History

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

  1. 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.
  2. 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."
  3. 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).
  4. 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).
  5. 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 46 on AgX (whites out — Standard + saturated color, ~1.53).

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).