Skip to content

feat: creature studio — 3D item pipeline + equipment rendering#327

Merged
mokn merged 12 commits intodevfrom
feat/creature-studio
Apr 8, 2026
Merged

feat: creature studio — 3D item pipeline + equipment rendering#327
mokn merged 12 commits intodevfrom
feat/creature-studio

Conversation

@mokn
Copy link
Copy Markdown
Collaborator

@mokn mokn commented Apr 8, 2026

Summary

  • Creature editing CLI (creature-edit.mjs) — GLB surgery: repose bones, scale, rename bones, add sockets, optimize
  • UniRig auto-rigging via Replicate API for quadrupeds/fantasy creatures that fail Meshy's rigger
  • Blender headless animation script for non-humanoid rigs (quadruped walk/idle/attack cycles)
  • Block + dodge combat animations — new clips on all rig types, wired into BattleSceneCanvas
  • Rotatable ASCII character viewer on Character page — drag to rotate, idle animation, all output is ASCII
  • 3D item model pipeline (item-forge.mjs) — generates all 43 items via Meshy, rarity-aware toon materials
  • Equipment rendering — items load as GLBs, attach to character bone sockets, render as projectiles in combat
  • Weapon preloading — equipped items preloaded on battle screen mount so 3D models are ready before first attack
  • Graceful 2D fallback — if item manifest is empty or GLB not loaded, existing canvas weapon drawings are used (zero visual regression)

All 3D rendering is invisible plumbing — players only see ASCII art. Three.js renders offscreen.

What's safe to test now

The client-side item manifest is currently empty, so all weapons will use existing 2D fallbacks. Once the item forge batch completes (~43 items generating via Meshy), we'll deploy the GLBs and manifest in a follow-up commit. The character viewer rotation and block/dodge animations are testable now.

Test plan

  • Enter combat — verify weapons still render (2D fallback, no regressions)
  • Block/dodge actions show correct animations on both player and monster
  • Character page — drag to rotate character model
  • Character page — verify no console errors from empty item manifest
  • Equip different weapons — verify no crashes or visual glitches

🤖 Generated with Claude Code

mokn and others added 11 commits April 7, 2026 19:31
Phase 0 of Creature Studio pipeline:
- creature-edit.mjs: gltf-transform CLI for post-generation GLB surgery
  (info, repose, scale, rename-bones, add-sockets, strip-animations,
  optimize, rig via UniRig/Replicate)
- Added dodge + walk animation clips to biped, quadruped, serpentine rigs
- BONE_CONVENTIONS.md: standard bone naming + equipment socket spec
- Added @gltf-transform/functions dependency

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Add block and dodge clip normalisation to CLIP_MAP so GLB animations
with names like "guard", "parry", "evade", "roll" map correctly.

Propagate blocked/dodged flags through AttackSignal so BattleSceneCanvas
plays the right defender animation (dodge > block > hit). Skip impact
VFX on dodges since there's no contact.

Replace hardcoded RightHand weapon attachment with attachToSocket() that
searches socket nodes then falls back to Mixamo/UniRig bone name variants
for all 5 standard sockets (hand_R, hand_L, chest, head, back).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
New CharacterViewer component renders the player's GLB model through
the ASCII pipeline with mouse/touch drag rotation. Three.js renders
offscreen — player only sees ASCII art.

Lazy-loaded via React.lazy to avoid adding Three.js to the initial
character page bundle. Shows above the avatar card when the character
has a race-specific model (Human, Elf, Dwarf).

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Fix rig command to use correct Replicate API: version hash
(9ee496ea...), data URI with model/gltf-binary MIME type (preserves
.glb extension detection). Tested successfully on giant-spider.glb —
58s, $0.07, produced 23-bone skeleton with skin weights.

Add animate-creature.py for Blender headless animation generation.
Creates 7 NLA clips (idle, walk, attack, hit, death, block, dodge)
with per-rig-type bone keyframes. Supports biped and quadruped
presets with comprehensive bone name aliasing.

Add .env to .gitignore for Replicate API token.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Fix animation_data_ensure → animation_data_create for Blender 5.x.
Add spider-unirig bone rename map for UniRig's generic bone_N naming.

Full pipeline verified: giant-spider.glb (mesh only) → UniRig rig
(58s, $0.07) → rename bones → Blender animate (7 clips) → optimize
→ add sockets. Output: 7.4 MB GLB with skeleton, animations, and
equipment sockets.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Reads items.json, classifies 43 player items (26 weapons + 17 armor)
by subtype/rarity, generates dark-fantasy 3D models via Meshy with
ART_SYSTEM.md rarity visual treatments, optimizes GLBs, and builds
a manifest.json for client runtime loading.

Commands: list, forge, forge-all, manifest, deploy.
Cost: ~$0.05/item, full batch ~$2.15.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- glbItemLoader.ts: loads item GLBs from manifest.json, renders through
  shared WebGL renderer at projectile positions
- weaponAnimations.ts: drawWeapon() now accepts optional itemName, tries
  3D render first, falls back to existing 2D canvas primitives
- AttackSignal.weaponName threaded through buildBattleSceneSignal →
  useBattleSceneSignals → BattleSceneCanvas → drawWeapon
- TileDetailsPanel: adds weaponNameForItem callback to signal pipeline
- MonsterAsciiRenderer: adds block/dodge to AnimAction type + durations
- glbCreatureLoader: exports getSharedRenderer for item loader reuse

8/8 buildBattleSceneSignal tests pass. Typechecks clean on changed files.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- glbItemLoader: rarity controls color saturation in toon materials
  R0-1 monochrome, R2 muted tint, R3 saturated accent, R4 vivid + emissive
- MonsterAsciiRenderer: block/dodge added to AnimAction + ACTION_DURATION
- item-viewer.html: grid view of all items by rarity with ASCII rendering,
  click-to-inspect with auto-rotation, cell size + filter controls

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Add getItemModel() export to glbItemLoader for bone-socket attachment
- CharacterViewer clones item model and attaches to character hand socket
  via attachToSocket(), handles weapon switching and un-equipping
- Character.tsx passes equipped weapon name to CharacterViewer
- TileDetailsPanel preloads all equipped weapon 3D models on mount so
  they're ready before first attack animation
- 28 tests for glbItemLoader (itemSlug, manifest loading, cache states)
  and weaponAnimations (classifyWeapon, drawWeapon 3D/2D fallback, rotation)

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Hunting Bow was timing out at 5 minutes during the refine step.
Increased pollTask maxWait to 10 minutes and added retry logic in
forgeAll that re-attempts failed items once after the initial pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
blog Ready Ready Preview, Comment Apr 8, 2026 3:22pm
ud Error Error Apr 8, 2026 3:22pm
ud-api Ready Ready Preview, Comment Apr 8, 2026 3:22pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ud-api-beta Ignored Ignored Preview Apr 8, 2026 3:22pm

Request Review

Merged dev's double-strike/combo system and battle feed improvements
with our weapon name threading, block/dodge animations, and equipment
attachment. Both feature sets preserved.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant