From a3f928322232b624f60e56874897fe7744147248 Mon Sep 17 00:00:00 2001 From: Eva Date: Wed, 22 Jul 2026 00:58:33 +0700 Subject: [PATCH 1/2] =?UTF-8?q?feat(assets):=20BG3-style=20demo=20asset=20?= =?UTF-8?q?library=20=E2=80=94=2068=20Tripo3D=20assets=20+=20registry=20ro?= =?UTF-8?q?ws=20(#1628)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 68/68 generated (33 rigged: 12 BG3-class party, 6 NPCs, 13 creatures incl. octopod/avian/quadruped, 2 bosses; 35 static town/dungeon props), 655 MB on LEXAR - Tripo balance 4835 -> 215 (95.5% spent per owner directive; reserve kept for regens) - tools/asset_library_batch.py: checkpointed two-stage (gen/rig) queue driver, balance floor - data/asset-registry/registry.json: +68 exact-resolve rows (verified via viewer/asset_registry.py) - TRIPO_PIPELINE.md: bulk-run cost rates; avian rigs have NO retarget presets (probed); rig_type 'others' fix = regen with explicit body-plan phrasing - Binaries stay off-git per registry convention; box deploy is the follow-up --- .claude/skills/asset-gen/TRIPO_PIPELINE.md | 11 + data/asset-registry/registry.json | 682 ++++++++++++++++++++- docs/asset-library/BG3-DEMO-LIBRARY.md | 106 ++++ tools/asset_library_batch.py | 312 ++++++++++ 4 files changed, 1110 insertions(+), 1 deletion(-) create mode 100644 docs/asset-library/BG3-DEMO-LIBRARY.md create mode 100644 tools/asset_library_batch.py diff --git a/.claude/skills/asset-gen/TRIPO_PIPELINE.md b/.claude/skills/asset-gen/TRIPO_PIPELINE.md index 2afcfef5..1ad369e6 100644 --- a/.claude/skills/asset-gen/TRIPO_PIPELINE.md +++ b/.claude/skills/asset-gen/TRIPO_PIPELINE.md @@ -80,6 +80,17 @@ tripo_gen.py text ... --dry-run # plan + est credits, no API call ## Credits / timing (measured) - Full humanoid gen→rig→1 retarget ≈ **~100 credits, ~3 min**. rig-check is free. The whole humanoid+creature validation run cost **215 credits**. +- **Bulk-library measured rates (2026-07-21, 68-asset run, issue #1628):** P1 lowpoly gen ~40 cr / + ~75 s; biped rig+walk/idle ~45 cr / ~50 s; 4-clip biped total ~105 cr / ~3.5 min; v3.1 boss gen + ~45 cr but SLOW (~4–5 min — split gen and rig stages across shell-timeout boundaries); static + P1 prop ~40 cr. Failed retarget submits error in ~1 s and charge nothing. +- **AVIAN rigs have NO working retarget presets (2026-07-21, probed exhaustively):** `walk`, `idle`, + `fly`, `flying`, `fly_forward`, `flap`, `soar`, `glide`, `hover` all fail error 1004 on an avian + rig. Quadruped/hexapod/octopod get `walk` only (`idle` unsupported). Plan avian units as + rigged-but-clipless (static/perched) or hand-animate later. +- rig-check can return `riggable:true, rig_type:"others"` (a brain-on-legs devourer did) — the rig + then aborts. Fix: REGENERATE with explicit body-plan phrasing ("quadruped, on all fours") — the + regen rigged cleanly. ~40 cr cheaper than fighting the rigger. ## Unity consumption (critical — see also the Unity section of `SKILL.md`) - Import the rigged/animated FBX as **`animationType = Generic`, NOT Humanoid.** Tripo's bone names diff --git a/data/asset-registry/registry.json b/data/asset-registry/registry.json index dc11a1ef..26590933 100644 --- a/data/asset-registry/registry.json +++ b/data/asset-registry/registry.json @@ -230,6 +230,686 @@ "critic_score": 0.0, "default_used": false, "humanoid": false + }, + "pc_fighter_human": { + "kind": "character", + "model_ref": "Assets/cast/pc_fighter_human/pc_fighter_human.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a human male fighter, plate armor, longsword and kite shield, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=f271a665-41a0-42d7-8133-8b80a89f874b rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_fighter_human/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_wolf": { + "kind": "monster", + "model_ref": "Assets/cast/cre_wolf/cre_wolf.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a dire wolf, on all fours, hackles raised, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8d7e936b-597e-46dc-bbca-e82266b55e0b rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_wolf/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_tavern_table": { + "kind": "prop", + "model_ref": "Assets/props/prop_tavern_table/prop_tavern_table.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a sturdy wooden tavern table, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=095f6cbd-ef4a-4653-9266-2232840ed5eb rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_tavern_table/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_wizard_elf": { + "kind": "character", + "model_ref": "Assets/cast/pc_wizard_elf/pc_wizard_elf.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a high elf male wizard, long robe, gnarled staff, spellbook at hip, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=a1d52876-5aa3-4c97-8298-3e7eb7284532 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_wizard_elf/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_cleric_drow": { + "kind": "character", + "model_ref": "Assets/cast/pc_cleric_drow/pc_cleric_drow.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a drow female cleric, chainmail, mace and round shield, holy symbol, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=daf15db5-ad7d-417c-a737-92bdd20ddf16 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_cleric_drow/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_rogue_tiefling": { + "kind": "character", + "model_ref": "Assets/cast/pc_rogue_tiefling/pc_rogue_tiefling.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a tiefling male rogue, dark leather armor, dual daggers, hood, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8871e693-a4de-42ca-8c76-76f26dcaa067 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_rogue_tiefling/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_ranger_elf": { + "kind": "character", + "model_ref": "Assets/cast/pc_ranger_elf/pc_ranger_elf.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wood elf female ranger, hooded cloak, longbow, quiver, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=0418c785-0707-47ac-9c4b-4d469581985c rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_ranger_elf/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_barbarian_halforc": { + "kind": "character", + "model_ref": "Assets/cast/pc_barbarian_halforc/pc_barbarian_halforc.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a half-orc male barbarian, fur and hide, greataxe, bare chest, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=4435744e-4400-4bbc-9e78-65d0fa863bd9 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_barbarian_halforc/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_paladin_dragonborn": { + "kind": "character", + "model_ref": "Assets/cast/pc_paladin_dragonborn/pc_paladin_dragonborn.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a dragonborn male paladin, ornate heavy armor, warhammer, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=936d632b-d32d-47dc-8a22-b96d965883b1 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_paladin_dragonborn/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_warlock_human": { + "kind": "character", + "model_ref": "Assets/cast/pc_warlock_human/pc_warlock_human.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a human female warlock, dark tattered robes, eldritch staff, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=6193831f-6aed-436b-9d92-96b772ce6de2 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_warlock_human/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_sorcerer_tiefling": { + "kind": "character", + "model_ref": "Assets/cast/pc_sorcerer_tiefling/pc_sorcerer_tiefling.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a tiefling female sorcerer, draconic scale accents, flowing robe, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=38e94e5c-00be-46bf-8996-a99d3c30b579 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_sorcerer_tiefling/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_bard_gnome": { + "kind": "character", + "model_ref": "Assets/cast/pc_bard_gnome/pc_bard_gnome.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a gnome male bard, colorful doublet, lute on back, rapier, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=70d7d24b-a417-480a-862d-91dc7a811d83 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_bard_gnome/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_druid_elf": { + "kind": "character", + "model_ref": "Assets/cast/pc_druid_elf/pc_druid_elf.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a elf female druid, leaf-and-bark garb, wooden staff, antler circlet, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=925bc27d-b735-4a26-80d7-621083659ad4 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_druid_elf/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "pc_monk_githyanki": { + "kind": "character", + "model_ref": "Assets/cast/pc_monk_githyanki/pc_monk_githyanki.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a githyanki male monk, wrapped forearms, simple gi, bald head, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=11f44b0e-c8fc-407d-889f-b2b96fc6f508 rig_task=None. Clips: idle, run, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/pc_monk_githyanki/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "npc_blacksmith": { + "kind": "character", + "model_ref": "Assets/cast/npc_blacksmith/npc_blacksmith.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a burly human male blacksmith, leather apron, smithing hammer, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=27de6f81-3e03-4d0a-ad3a-bdddf7a56f33 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/npc_blacksmith/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "npc_merchant": { + "kind": "character", + "model_ref": "Assets/cast/npc_merchant/npc_merchant.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stout human male merchant, fine tunic, coin purse, scroll, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=ae57de30-f4a9-45a6-927d-d53ae21201aa rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/npc_merchant/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "npc_guard": { + "kind": "character", + "model_ref": "Assets/cast/npc_guard/npc_guard.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a human male town guard, chain shirt, spear, kettle helm, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=24a1568e-2829-4b2a-8c6d-fd20af90db0c rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/npc_guard/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "npc_beggar": { + "kind": "character", + "model_ref": "Assets/cast/npc_beggar/npc_beggar.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a elderly human female beggar, ragged shawl, walking stick, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=7bb7b533-7aa4-4093-823c-683c7568766a rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/npc_beggar/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_owlbear": { + "kind": "monster", + "model_ref": "Assets/cast/cre_owlbear/cre_owlbear.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a owlbear, bear body with owl head and feathers, on all fours, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=ff118edf-58b6-46d5-ac80-71afc696b663 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_owlbear/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_giant_spider": { + "kind": "monster", + "model_ref": "Assets/cast/cre_giant_spider/cre_giant_spider.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a giant spider, eight long legs, venomous fangs, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=71e45de6-a061-44c9-ab7f-99f1840d3a4d rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_giant_spider/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_raven": { + "kind": "monster", + "model_ref": "Assets/cast/cre_raven/cre_raven.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a giant raven, wings spread wide, perched, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=c1e37e87-e2c2-46b5-bfc6-c1f0a157bb18 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_raven/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_goblin": { + "kind": "monster", + "model_ref": "Assets/cast/cre_goblin/cre_goblin.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a goblin warrior, green skin, scavenged armor, scimitar, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=6b828a60-52b4-4175-a875-49efcc5a5d72 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_goblin/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_skeleton": { + "kind": "monster", + "model_ref": "Assets/cast/cre_skeleton/cre_skeleton.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a animated skeleton warrior, rusted sword and battered shield, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=4b826f9d-5901-4d2b-ad5a-7062e674d1ea rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_skeleton/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_imp": { + "kind": "monster", + "model_ref": "Assets/cast/cre_imp/cre_imp.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a small winged imp, leathery wings, barbed tail, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=342adc62-131c-4902-83c1-4f3ec924d79d rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_imp/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "boss_young_red_dragon": { + "kind": "monster", + "model_ref": "Assets/cast/boss_young_red_dragon/boss_young_red_dragon.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a young red dragon, massive gargantuan boss, four legs, folded wings, horns, crimson scales, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready, isolated on plain background'. gen_task=2809fc1a-ae48-4ee8-a3cb-bf7a91002418 rig_task=None. Clips: idle, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/boss_young_red_dragon/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_wooden_chair": { + "kind": "prop", + "model_ref": "Assets/props/prop_wooden_chair/prop_wooden_chair.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a simple wooden tavern chair, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=26aa41de-5a72-4b84-945e-26bf79deae34 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_wooden_chair/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_barrel": { + "kind": "prop", + "model_ref": "Assets/props/prop_barrel/prop_barrel.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden barrel with iron hoops, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=23596364-42f0-41ca-8f79-915c3c0a0187 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_barrel/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_crate": { + "kind": "prop", + "model_ref": "Assets/props/prop_crate/prop_crate.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden shipping crate, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=46b33200-fe9f-499d-905a-2aae1771e0dd rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_crate/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_market_stall": { + "kind": "prop", + "model_ref": "Assets/props/prop_market_stall/prop_market_stall.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden market stall with canvas awning, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=3a5bf2cb-1dde-4b7e-89d2-e0253b446bc4 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_market_stall/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_well": { + "kind": "prop", + "model_ref": "Assets/props/prop_well/prop_well.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone water well with wooden bucket and crank, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=27674d13-ecb6-4029-8e10-7fc6aabc14ef rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_well/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_lantern_post": { + "kind": "prop", + "model_ref": "Assets/props/prop_lantern_post/prop_lantern_post.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron street lantern post, warm glow, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=5e24dd6a-824a-460d-af1b-6181819911e1 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_lantern_post/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_hand_cart": { + "kind": "prop", + "model_ref": "Assets/props/prop_hand_cart/prop_hand_cart.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden two-wheel hand cart, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=d2b2ca80-f953-4dff-9008-241dc312e4da rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_hand_cart/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_signpost": { + "kind": "prop", + "model_ref": "Assets/props/prop_signpost/prop_signpost.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden signpost with hanging tavern sign, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=c024d005-ab4e-406d-954b-0fdd02cc4c82 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_signpost/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_anvil": { + "kind": "prop", + "model_ref": "Assets/props/prop_anvil/prop_anvil.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a blacksmith anvil on a tree stump, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8b9f6ff3-4874-4d09-8be5-5daf7a951239 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_anvil/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_fountain": { + "kind": "prop", + "model_ref": "Assets/props/prop_fountain/prop_fountain.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone town fountain with tiered basin, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=90bee4bb-bbe0-435a-917c-69ea6c51c0bf rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_fountain/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_bench": { + "kind": "prop", + "model_ref": "Assets/props/prop_bench/prop_bench.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden park bench, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=238f7a93-3cf5-4829-b4b8-15127baa250f rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bench/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_treasure_chest": { + "kind": "prop", + "model_ref": "Assets/props/prop_treasure_chest/prop_treasure_chest.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ornate wooden treasure chest with iron bands, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=94b09304-1427-480c-95b2-49967a76a583 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_treasure_chest/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_sarcophagus": { + "kind": "prop", + "model_ref": "Assets/props/prop_sarcophagus/prop_sarcophagus.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ancient stone sarcophagus with carved lid, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=a3a4a8cb-7e0b-40b7-9847-0b57a13e8b00 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_sarcophagus/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_iron_gate": { + "kind": "prop", + "model_ref": "Assets/props/prop_iron_gate/prop_iron_gate.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wrought iron dungeon gate, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=656c9a28-67b8-447a-a651-4ebae8498c77 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_iron_gate/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_torch_sconce": { + "kind": "prop", + "model_ref": "Assets/props/prop_torch_sconce/prop_torch_sconce.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wall-mounted iron torch sconce with flame, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=c3d015a2-e825-42ca-8996-02c291e7c9f1 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_torch_sconce/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_stone_pillar": { + "kind": "prop", + "model_ref": "Assets/props/prop_stone_pillar/prop_stone_pillar.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ancient carved stone pillar, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8c9f15b2-ce51-4b2e-9f39-97edfd306ccc rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_stone_pillar/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_rubble_pile": { + "kind": "prop", + "model_ref": "Assets/props/prop_rubble_pile/prop_rubble_pile.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a pile of broken stone rubble, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=f7bab24a-354e-4557-8aa9-cf84b120b250 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_rubble_pile/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_altar": { + "kind": "prop", + "model_ref": "Assets/props/prop_altar/prop_altar.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a dark stone ritual altar with carved runes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=034f2d32-85cd-4b35-8bdc-e8e893280972 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_altar/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_brazier": { + "kind": "prop", + "model_ref": "Assets/props/prop_brazier/prop_brazier.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron brazier with burning coals, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=40f67396-d849-4ee0-b6e0-acb22191c013 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_brazier/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_wooden_door": { + "kind": "prop", + "model_ref": "Assets/props/prop_wooden_door/prop_wooden_door.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a heavy wooden dungeon door with iron hinges, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=b5929568-0387-4a6a-9fdb-cb8a54edd2b6 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_wooden_door/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_gargoyle_statue": { + "kind": "prop", + "model_ref": "Assets/props/prop_gargoyle_statue/prop_gargoyle_statue.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a crouching stone gargoyle statue, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=d47f5dec-8912-44b2-8738-5029172e3011 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_gargoyle_statue/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_bookshelf": { + "kind": "prop", + "model_ref": "Assets/props/prop_bookshelf/prop_bookshelf.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a tall wooden bookshelf filled with old tomes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8c1fadb4-6e53-4585-a82e-eb4aa1f788d8 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bookshelf/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_intellect_devourer": { + "kind": "monster", + "model_ref": "Assets/cast/cre_intellect_devourer/cre_intellect_devourer.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a intellect devourer monster, a walking brain creature on four clawed beast legs, quadruped, on all fours, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=eb852c53-a976-4734-9a04-2cf767b2b8a8 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_intellect_devourer/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_throne": { + "kind": "prop", + "model_ref": "Assets/props/prop_throne/prop_throne.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a imposing stone throne on a small dais, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=497b0674-8893-4f6f-b21e-a12b0fa3ed53 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_throne/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_portcullis": { + "kind": "prop", + "model_ref": "Assets/props/prop_portcullis/prop_portcullis.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron portcullis gate, half-raised, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=6fb4800a-e97a-4e3f-afb4-ffcfc99fefc0 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_portcullis/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "boss_ogre_chieftain": { + "kind": "monster", + "model_ref": "Assets/cast/boss_ogre_chieftain/boss_ogre_chieftain.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'an ogre chieftain, huge hulking boss, crude spiked club, fur loincloth, bone jewelry, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready, isolated on plain background'. gen_task=92653178-7303-48c0-b63d-0369b7a48abb rig_task=None. Clips: idle, slash, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/boss_ogre_chieftain/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_zombie": { + "kind": "monster", + "model_ref": "Assets/cast/cre_zombie/cre_zombie.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a shambling zombie, rotting clothes, arms hanging low, biped, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=330a4f2b-205c-4a1d-b8e0-1b56ff103683 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_zombie/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_giant_rat": { + "kind": "monster", + "model_ref": "Assets/cast/cre_giant_rat/cre_giant_rat.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a giant rat, dog-sized, mangy fur, on all fours, long tail, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=5cb65d54-10a6-497d-a0cc-c006d9d5d5f8 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_giant_rat/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_mimic": { + "kind": "prop", + "model_ref": "Assets/props/cre_mimic/cre_mimic.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a mimic monster, a treasure chest with teeth and a long tongue, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=488bac50-2279-4a2a-a3f2-6a666486c5a2 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_mimic/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "npc_noble": { + "kind": "character", + "model_ref": "Assets/cast/npc_noble/npc_noble.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a haughty human male noble, velvet doublet, rapier, feathered hat, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=ed5cb1a3-96d4-40f2-aad5-753fbe24ce49 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/npc_noble/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "npc_priest": { + "kind": "character", + "model_ref": "Assets/cast/npc_priest/npc_priest.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a human male priest, white and gold robes, holy symbol, staff, A-pose, full body, feet on ground, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=3c787e66-13ef-401f-8565-b7c815d3740c rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/npc_priest/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_weapon_rack": { + "kind": "prop", + "model_ref": "Assets/props/prop_weapon_rack/prop_weapon_rack.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden weapon rack with swords and axes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=48404ae4-5455-46a6-9860-bf5d7aeb1a07 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_weapon_rack/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_armor_stand": { + "kind": "prop", + "model_ref": "Assets/props/prop_armor_stand/prop_armor_stand.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a armor stand displaying a suit of chainmail, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=cb4af21a-e1d0-43dc-9b60-bd76a547ad01 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_armor_stand/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_stocks": { + "kind": "prop", + "model_ref": "Assets/props/prop_stocks/prop_stocks.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden pillory stocks, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=e40c6efa-84cd-498a-92f9-825c2844769a rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_stocks/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_candelabra": { + "kind": "prop", + "model_ref": "Assets/props/prop_candelabra/prop_candelabra.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a tall iron candelabra with five lit candles, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=2235b3b7-2d19-4395-93fa-40ccc87fc3d9 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_candelabra/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_standing_torch": { + "kind": "prop", + "model_ref": "Assets/props/prop_standing_torch/prop_standing_torch.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a standing iron torch with flame, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=79212960-4b1b-4492-a0d7-f2f3657539d3 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_standing_torch/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_bed": { + "kind": "prop", + "model_ref": "Assets/props/prop_bed/prop_bed.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a simple wooden bed with wool blanket, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=cc489c35-fccb-41de-bfdd-36c66cb2878c rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bed/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_gnoll": { + "kind": "monster", + "model_ref": "Assets/cast/cre_gnoll/cre_gnoll.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a gnoll, hyena-headed humanoid, scavenged leather armor, spear, biped, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=bd4f04b0-3b60-407e-a0f5-8a162507bee9 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_gnoll/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_harpy": { + "kind": "monster", + "model_ref": "Assets/cast/cre_harpy/cre_harpy.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a harpy, winged bird-woman, talons, wings spread, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=a07fdc14-f2fa-4bee-8fdf-ce62acd09781 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_harpy/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "cre_doppelganger": { + "kind": "monster", + "model_ref": "Assets/cast/cre_doppelganger/cre_doppelganger.fbx", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a doppelganger, pale featureless humanoid, smooth blank face, biped, full body, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=d542b747-cebd-4882-befc-e8659b9c2f11 rig_task=None. Clips: idle, walk. Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_doppelganger/ (deploy rigged.fbx to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_campfire": { + "kind": "prop", + "model_ref": "Assets/props/prop_campfire/prop_campfire.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone-ringed campfire with burning logs, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=7e117646-bbbb-4eca-b2fe-6bb213e9b69f rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_campfire/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_dungeon_stairs": { + "kind": "prop", + "model_ref": "Assets/props/prop_dungeon_stairs/prop_dungeon_stairs.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a worn stone dungeon stairs descending, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=3d6ee0ef-1c5f-4adf-81ac-3607c6bfef61 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_dungeon_stairs/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false + }, + "prop_barricade": { + "kind": "prop", + "model_ref": "Assets/props/prop_barricade/prop_barricade.glb", + "albedo_ref": null, + "anim_ref": null, + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a makeshift wooden barricade with spikes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=71215094-1c25-4460-a358-05a96d288c09 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_barricade/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "version": "1.0.0", + "critic_score": 0.0, + "default_used": false } } -} +} \ No newline at end of file diff --git a/docs/asset-library/BG3-DEMO-LIBRARY.md b/docs/asset-library/BG3-DEMO-LIBRARY.md new file mode 100644 index 00000000..faa18a98 --- /dev/null +++ b/docs/asset-library/BG3-DEMO-LIBRARY.md @@ -0,0 +1,106 @@ +# BG3-Style Demo Asset Library (Tripo3D bulk generation) + +> Owner-directed 2026-07-21: "design up and go until all tokens used up — sample demo +> town/dungeon/creatures/characters + a larger 4x-square boss." Parallel graphics lane; +> does NOT displace active charter #1386 (Act II close-out). + +## Budget (live-verified 2026-07-21) + +- Tripo3D balance at start: **4,835 credits** (`GET /v2/openapi/user/balance`). + (Owner believed ~41k — dashboard-vs-API discrepancy; API is source of truth.) +- Measured costs (`.claude/skills/asset-gen/TRIPO_PIPELINE.md` + `--dry-run`): + P1 lowpoly gen ~20 cr · v3.1 gen ~40 cr · full humanoid gen→rig→1 retarget ≈ ~100 cr, + each extra retarget ~10–20 cr · rig-check free. +- Plan: ~3,550 cr roster + ~1,285 cr (27%) retry/variant reserve. Hard stop at balance < 100. + +## Style contract (pinned across every prompt) + +`stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly` +— original phrasing only (Copyright Guard: never name BG/PoE/Disco as a style source). +Characters: `A-pose, full body, feet on ground`. Model: `P1-20260311` (game/low-poly, +best for characters) for everything except the boss, which gets `v3.1-20260211` for detail. +Output: rigged **FBX** (`spec=mixamo` biped / `tripo` creatures) → Unity import as +`animationType=Generic` (NEVER Humanoid — silently drops clips). + +## Wave 1 — Party: 12 BG3 classes in signature races (biped; walk idle run slash; ~130 cr ea) + +| asset_id | prompt core | +|---|---| +| pc_fighter_human | human male fighter, plate armor, longsword and kite shield | +| pc_wizard_elf | high elf male wizard, long robe, gnarled staff, spellbook at hip | +| pc_cleric_drow | drow female cleric, chainmail, mace and round shield, holy symbol | +| pc_rogue_tiefling | tiefling male rogue, dark leather armor, dual daggers, hood | +| pc_ranger_elf | wood elf female ranger, hooded cloak, longbow, quiver | +| pc_barbarian_halforc | half-orc male barbarian, fur and hide, greataxe, bare chest | +| pc_paladin_dragonborn | dragonborn male paladin, ornate heavy armor, warhammer | +| pc_warlock_human | human female warlock, dark tattered robes, eldritch staff | +| pc_sorcerer_tiefling | tiefling female sorcerer, draconic scale accents, flowing robe | +| pc_bard_gnome | gnome male bard, colorful doublet, lute on back, rapier | +| pc_druid_elf | elf female druid, leaf-and-bark garb, wooden staff, antler circlet | +| pc_monk_githyanki | githyanki male monk, wrapped forearms, simple gi, bald | + +## Wave 2 — Town NPCs (biped; walk idle; ~110 cr ea) + +| asset_id | prompt core | +|---|---| +| npc_blacksmith | burly human male blacksmith, leather apron, smithing hammer | +| npc_merchant | stout human male merchant, fine tunic, coin purse, scroll | +| npc_guard | human male town guard, chain shirt, spear, kettle helm | +| npc_beggar | elderly human female beggar, ragged shawl, walking stick | + +## Wave 3 — Creatures (Tripo-only rig types; walk idle; ~100–130 cr ea) + +| asset_id | prompt core | expected rig_type | +|---|---|---| +| cre_wolf | dire wolf, on all fours, hackles raised | quadruped | +| cre_owlbear | owlbear, bear body owl head, on all fours | quadruped | +| cre_giant_spider | giant spider, eight legs, venomous fangs | octopod | +| cre_intellect_devourer | intellect devourer, walking brain on four clawed legs | quadruped | +| cre_raven | giant raven, wings spread, perched | avian (the "air" unit) | +| cre_goblin | goblin warrior, green skin, scavenged armor, scimitar | biped | +| cre_skeleton | animated skeleton warrior, rusted sword and shield | biped | +| cre_imp | small winged imp, leathery wings, barbed tail | biped | + +## Wave 4 — Boss (4×4 squares = Gargantuan; v3.1 detail; walk idle slash; ~150–200 cr) + +| asset_id | prompt core | +|---|---| +| boss_young_red_dragon | young red dragon, massive, wings folded, four legs, horns, scales, gargantuan boss | + +## Wave 5 — Props: town + dungeon demo set (static P1 lowpoly, no rig; ~20 cr ea) + +Town: prop_tavern_table, prop_wooden_chair, prop_barrel, prop_crate, prop_market_stall, +prop_well, prop_lantern_post, prop_hand_cart, prop_signpost, prop_anvil, prop_fountain, +prop_bench. + +Dungeon: prop_treasure_chest, prop_sarcophagus, prop_iron_gate, prop_torch_sconce, +prop_stone_pillar, prop_rubble_pile, prop_altar, prop_brazier, prop_wooden_door, +prop_gargoyle_statue, prop_bookshelf, prop_throne, prop_portcullis. + +(25 props ≈ 500 cr.) + +## Ops +- Driver: `tools/asset_library_batch.py` — queue-driven, checkpointing, resumable, + stops at balance < 100; one JSONL manifest row per item (task ids, files, credits). +- Binaries (gitignored class): `/Volumes/LEXAR/Codex/worldos-asset-library//` + (GLB+FBX+albedo). Box deploy to `Assets/cast|props//` is a separate step (LFS + blocked; LEXAR tarball is the save story). +- Registry: rows appended to `data/asset-registry/registry.json` after generation with + `gen_recipe` = exact prompt + Tripo task ids (regenerable). +- Known limits (live-tested facts): output URLs expire ~5 min (wrapper downloads + immediately); retarget = ONE preset per call; creatures support fewer clips + (per-clip failures non-fatal); FBX imports untextured → assign albedo separately. + +## Outcome (2026-07-21, issue #1628) + +- **68/68 assets generated, zero permanent failures.** 33 rigged (12 party, 6 NPCs, 13 creatures, + 2 bosses) + 35 static props. 655 MB on LEXAR (`/Volumes/LEXAR/Codex/worldos-asset-library/`). +- **Credits: 4,835 → 215** (95.5% spent; 215 held as integration-regen reserve above the 100 floor). +- Added waves 6–7 during the run (ogre 2nd boss, zombie/giant_rat/mimic/gnoll/harpy/doppelganger, + noble/priest, 9 more props) to honor the owner's "use the tokens up" directive. +- Intellect devourer regen'd once (rig-check `rig_type:"others"` → quadruped-phrased prompt fixed it). +- Avian rigs (raven, harpy) ship rigged-but-clipless: NO avian retarget presets exist on Tripo + rigging v2.5 (probed 2026-07-21, recorded in TRIPO_PIPELINE.md). Quadruped/octopod = walk only. +- All 68 registered in `data/asset-registry/registry.json` (exact-resolve verified via + `viewer/asset_registry.py`). Binaries stay off-git per the registry convention; box deploy of + `rigged.fbx`/`model.glb` → the registry's `Assets/cast|props//` paths is the follow-up step. diff --git a/tools/asset_library_batch.py b/tools/asset_library_batch.py new file mode 100644 index 00000000..a3c84b24 --- /dev/null +++ b/tools/asset_library_batch.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python3 +"""BG3-style demo asset library batch driver (issue #1628). + +Queue-driven Tripo3D bulk generation. Checkpointed + resumable: +- done items recorded in /manifest.jsonl (one row per completed asset) +- re-running skips done items; the tripo_gen.py wrapper itself skips regen + when model.glb already exists in the item's out dir +- hard stop when Tripo balance < BALANCE_FLOOR +- --max-seconds bounds each invocation (caller re-invokes to continue) + +Spec: docs/asset-library/BG3-DEMO-LIBRARY.md +""" +import json +import os +import subprocess +import sys +import time +import urllib.request + +ROOT = "/Volumes/LEXAR/Codex/worldos-asset-library" +WRAPPER = "extensions/renderers/godot/tools/tripo_gen.py" +KEY_PATH = os.path.expanduser("~/.worldos/tripo3d.key") +BALANCE_FLOOR = 100 +MANIFEST = os.path.join(ROOT, "manifest.jsonl") + +STYLE = "stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly" +POSE = "A-pose, full body, feet on ground" + + +def pc(asset_id, core): + return {"id": asset_id, "kind": "character", "wave": 1, "rig": True, + "animations": ["walk", "idle", "run", "slash"], + "prompt": "a %s, %s, %s, %s" % (core, POSE, STYLE, "isolated on plain background")} + + +def npc(asset_id, core): + return {"id": asset_id, "kind": "character", "wave": 2, "rig": True, + "animations": ["walk", "idle"], + "prompt": "a %s, %s, %s, %s" % (core, POSE, STYLE, "isolated on plain background")} + + +def creature(asset_id, core): + return {"id": asset_id, "kind": "monster", "wave": 3, "rig": True, + "animations": ["walk", "idle"], + "prompt": "a %s, %s, %s, %s" % (core, "full body", STYLE, "isolated on plain background")} + + +def prop(asset_id, core): + return {"id": asset_id, "kind": "prop", "wave": 5, "rig": False, + "animations": [], + "prompt": "a %s, %s, %s" % (core, STYLE, "isolated on plain background")} + + +QUEUE = [ + # ---- probe (first 3: one of each pipeline shape) ---- + pc("pc_fighter_human", "human male fighter, plate armor, longsword and kite shield"), + creature("cre_wolf", "dire wolf, on all fours, hackles raised"), + prop("prop_tavern_table", "sturdy wooden tavern table"), + # ---- wave 1: party (12 BG3 classes in signature races) ---- + pc("pc_wizard_elf", "high elf male wizard, long robe, gnarled staff, spellbook at hip"), + pc("pc_cleric_drow", "drow female cleric, chainmail, mace and round shield, holy symbol"), + pc("pc_rogue_tiefling", "tiefling male rogue, dark leather armor, dual daggers, hood"), + pc("pc_ranger_elf", "wood elf female ranger, hooded cloak, longbow, quiver"), + pc("pc_barbarian_halforc", "half-orc male barbarian, fur and hide, greataxe, bare chest"), + pc("pc_paladin_dragonborn", "dragonborn male paladin, ornate heavy armor, warhammer"), + pc("pc_warlock_human", "human female warlock, dark tattered robes, eldritch staff"), + pc("pc_sorcerer_tiefling", "tiefling female sorcerer, draconic scale accents, flowing robe"), + pc("pc_bard_gnome", "gnome male bard, colorful doublet, lute on back, rapier"), + pc("pc_druid_elf", "elf female druid, leaf-and-bark garb, wooden staff, antler circlet"), + pc("pc_monk_githyanki", "githyanki male monk, wrapped forearms, simple gi, bald head"), + # ---- wave 2: town NPCs ---- + npc("npc_blacksmith", "burly human male blacksmith, leather apron, smithing hammer"), + npc("npc_merchant", "stout human male merchant, fine tunic, coin purse, scroll"), + npc("npc_guard", "human male town guard, chain shirt, spear, kettle helm"), + npc("npc_beggar", "elderly human female beggar, ragged shawl, walking stick"), + # ---- wave 3: creatures (Tripo-only rig types) ---- + creature("cre_owlbear", "owlbear, bear body with owl head and feathers, on all fours"), + creature("cre_giant_spider", "giant spider, eight long legs, venomous fangs"), + creature("cre_intellect_devourer", "intellect devourer monster, a walking brain creature on four clawed beast legs, quadruped, on all fours"), + creature("cre_raven", "giant raven, wings spread wide, perched"), + creature("cre_goblin", "goblin warrior, green skin, scavenged armor, scimitar"), + creature("cre_skeleton", "animated skeleton warrior, rusted sword and battered shield"), + creature("cre_imp", "small winged imp, leathery wings, barbed tail"), + # ---- wave 4: boss (4x4 squares, Gargantuan; v3.1 detail) ---- + {"id": "boss_young_red_dragon", "kind": "monster", "wave": 4, "rig": True, + "animations": ["walk", "idle", "slash"], "model": "v3.1-20260211", + "prompt": "a young red dragon, massive gargantuan boss, four legs, folded wings, horns, " + "crimson scales, full body, stylized hand-painted dark fantasy RPG, muted earthy " + "palette, game-ready, isolated on plain background"}, + # ---- wave 5: props — town ---- + prop("prop_wooden_chair", "simple wooden tavern chair"), + prop("prop_barrel", "wooden barrel with iron hoops"), + prop("prop_crate", "wooden shipping crate"), + prop("prop_market_stall", "wooden market stall with canvas awning"), + prop("prop_well", "stone water well with wooden bucket and crank"), + prop("prop_lantern_post", "iron street lantern post, warm glow"), + prop("prop_hand_cart", "wooden two-wheel hand cart"), + prop("prop_signpost", "wooden signpost with hanging tavern sign"), + prop("prop_anvil", "blacksmith anvil on a tree stump"), + prop("prop_fountain", "stone town fountain with tiered basin"), + prop("prop_bench", "wooden park bench"), + # ---- wave 5: props — dungeon ---- + prop("prop_treasure_chest", "ornate wooden treasure chest with iron bands"), + prop("prop_sarcophagus", "ancient stone sarcophagus with carved lid"), + prop("prop_iron_gate", "wrought iron dungeon gate"), + prop("prop_torch_sconce", "wall-mounted iron torch sconce with flame"), + prop("prop_stone_pillar", "ancient carved stone pillar"), + prop("prop_rubble_pile", "pile of broken stone rubble"), + prop("prop_altar", "dark stone ritual altar with carved runes"), + prop("prop_brazier", "iron brazier with burning coals"), + prop("prop_wooden_door", "heavy wooden dungeon door with iron hinges"), + prop("prop_gargoyle_statue", "crouching stone gargoyle statue"), + prop("prop_bookshelf", "tall wooden bookshelf filled with old tomes"), + prop("prop_throne", "imposing stone throne on a small dais"), + prop("prop_portcullis", "iron portcullis gate, half-raised"), + # ---- wave 6: demo-filler extras (spend-down of remaining balance) ---- + {"id": "boss_ogre_chieftain", "kind": "monster", "wave": 6, "rig": True, + "animations": ["walk", "idle", "slash"], "model": "v3.1-20260211", + "prompt": "an ogre chieftain, huge hulking boss, crude spiked club, fur loincloth, bone " + "jewelry, A-pose, full body, feet on ground, stylized hand-painted dark fantasy " + "RPG, muted earthy palette, game-ready, isolated on plain background"}, + creature("cre_zombie", "shambling zombie, rotting clothes, arms hanging low, biped"), + creature("cre_giant_rat", "giant rat, dog-sized, mangy fur, on all fours, long tail"), + prop("cre_mimic", "mimic monster, a treasure chest with teeth and a long tongue"), + npc("npc_noble", "haughty human male noble, velvet doublet, rapier, feathered hat"), + npc("npc_priest", "human male priest, white and gold robes, holy symbol, staff"), + prop("prop_weapon_rack", "wooden weapon rack with swords and axes"), + prop("prop_armor_stand", "armor stand displaying a suit of chainmail"), + prop("prop_stocks", "wooden pillory stocks"), + prop("prop_candelabra", "tall iron candelabra with five lit candles"), + prop("prop_standing_torch", "standing iron torch with flame"), + prop("prop_bed", "simple wooden bed with wool blanket"), + # ---- wave 7: final spend-down to the balance floor ---- + creature("cre_gnoll", "gnoll, hyena-headed humanoid, scavenged leather armor, spear, biped"), + creature("cre_harpy", "harpy, winged bird-woman, talons, wings spread"), + creature("cre_doppelganger", "doppelganger, pale featureless humanoid, smooth blank face, biped"), + prop("prop_campfire", "stone-ringed campfire with burning logs"), + prop("prop_dungeon_stairs", "worn stone dungeon stairs descending"), + prop("prop_barricade", "makeshift wooden barricade with spikes"), +] + + +def get_key(): + with open(KEY_PATH) as f: + return f.read().strip() + + +def balance(key): + req = urllib.request.Request( + "https://api.tripo3d.ai/v2/openapi/user/balance", + headers={"Authorization": "Bearer " + key}) + with urllib.request.urlopen(req, timeout=30) as r: + return json.load(r)["data"]["balance"] + + +def done_ids(): + ids = set() + if os.path.exists(MANIFEST): + with open(MANIFEST) as f: + for line in f: + line = line.strip() + if line: + ids.add(json.loads(line)["id"]) + return ids + + +def _read_meta(out_dir): + meta_path = os.path.join(out_dir, "metadata.json") + if os.path.exists(meta_path): + with open(meta_path) as f: + return json.load(f) + return {} + + +def _is_complete(item, out_dir): + meta = _read_meta(out_dir) + if not os.path.exists(os.path.join(out_dir, "model.glb")): + return False + if not item["rig"]: + return True + return bool(meta.get("animation_files")) + + +def _run(cmd): + t0 = time.time() + proc = subprocess.run(cmd, capture_output=True, text=True) + dur = round(time.time() - t0, 1) + if proc.returncode != 0: + tail = "\n".join((proc.stdout + proc.stderr).strip().splitlines()[-8:]) + return False, dur, tail + return True, dur, "" + + +def run_item(item, key, budget_left): + """Two-stage so each subprocess fits the 300s shell timeout: + stage A = text generation only (writes model.glb + metadata.json with gen task id) + stage B = rig --task (rigged.fbx + anim_*.fbx) + Returns a status dict; 'staged' means progress made, re-invoke to continue. + """ + out_dir = os.path.join(ROOT, item["id"]) + os.makedirs(out_dir, exist_ok=True) + meta = _read_meta(out_dir) + + if not os.path.exists(os.path.join(out_dir, "model.glb")): + cmd = [sys.executable, WRAPPER, "text", "--prompt", item["prompt"], + "--out", out_dir, "--timeout", "240"] + if item.get("model") != "v3.1-20260211": + cmd.append("--lowpoly") + ok, dur, tail = _run(cmd) + if not ok: + return {"id": item["id"], "status": "failed", "stage": "gen", + "dur_s": dur, "tail": tail} + meta = _read_meta(out_dir) + print("[batch] gen stage done (%ss)" % dur) + if not item["rig"]: + return _finish(item, out_dir, meta, dur) + if time.time() > budget_left: + return {"id": item["id"], "status": "staged", "stage": "gen", "dur_s": dur} + + if item["rig"]: + gen_task = meta.get("generation_task_id") + if not gen_task: + return {"id": item["id"], "status": "failed", "stage": "rig", + "dur_s": 0, "tail": "model.glb exists but no generation_task_id in metadata.json"} + cmd = [sys.executable, WRAPPER, "rig", "--task", gen_task, + "--out", out_dir, "--out-format", "fbx", "--timeout", "240", + "--animations"] + item["animations"] + ok, dur, tail = _run(cmd) + if not ok: + return {"id": item["id"], "status": "failed", "stage": "rig", + "dur_s": dur, "tail": tail} + print("[batch] rig stage done (%ss)" % dur) + return _finish(item, out_dir, _read_meta(out_dir), dur) + + return _finish(item, out_dir, meta, 0) + + +def _finish(item, out_dir, meta, dur): + files = {} + for fn in sorted(os.listdir(out_dir)): + if fn.startswith(("model.", "rigged.", "anim_")): + files[fn] = os.path.getsize(os.path.join(out_dir, fn)) + row = {"id": item["id"], "kind": item["kind"], "wave": item["wave"], + "status": "done", "dur_s": dur, "prompt": item["prompt"], + "files": files, "ts": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "gen_task_id": meta.get("generation_task_id"), + "rig_task_id": (meta.get("rig") or {}).get("task_id"), + "clips": sorted((meta.get("animation_files") or {}).keys())} + with open(MANIFEST, "a") as f: + f.write(json.dumps(row) + "\n") + return row + + +def main(): + max_seconds = 280.0 + limit = 0 + args = sys.argv[1:] + while args: + a = args.pop(0) + if a == "--max-seconds": + max_seconds = float(args.pop(0)) + elif a == "--limit": + limit = int(args.pop(0)) + os.makedirs(ROOT, exist_ok=True) + key = get_key() + done = done_ids() + skip_file = os.path.join(ROOT, "skip.txt") + if os.path.exists(skip_file): + with open(skip_file) as f: + done |= {ln.strip() for ln in f if ln.strip()} + start = time.time() + bal = balance(key) + print("[batch] balance=%d done=%d queue=%d" % (bal, len(done), len(QUEUE))) + ran = 0 + for item in QUEUE: + out_dir = os.path.join(ROOT, item["id"]) + if item["id"] in done or (os.path.isdir(out_dir) and _is_complete(item, out_dir)): + continue + if limit and ran >= limit: + break + if time.time() - start > max_seconds: + print("[batch] time budget reached; re-invoke to continue") + break + if bal < BALANCE_FLOOR: + print("[batch] balance floor hit (%d); stopping" % bal) + break + print("[batch] -> %s (%s, wave %d)" % (item["id"], item["kind"], item["wave"])) + sys.stdout.flush() + row = run_item(item, key, start + max_seconds) + if row["status"] == "staged": + print("[batch] STAGED %s — %s done; re-invoke to continue" % + (row["id"], row["stage"])) + break + ran += 1 + if row["status"] == "done": + total = sum(row["files"].values()) + print("[batch] OK %s — %d files, %.1f MB, %ss" % + (row["id"], len(row["files"]), total / 1e6, row["dur_s"])) + else: + print("[batch] FAIL %s (%s) — %ss\n%s" % + (item["id"], row.get("stage"), row["dur_s"], row["tail"])) + try: + bal = balance(key) + print("[batch] balance=%d" % bal) + except Exception as e: + print("[batch] balance check failed: %s" % e) + sys.stdout.flush() + print("[batch] invocation done (ran %d this call)" % ran) + + +if __name__ == "__main__": + main() From b7928bcf501e6621ed050ea73ef0b0a110a03fc8 Mon Sep 17 00:00:00 2001 From: Eva Date: Wed, 22 Jul 2026 10:55:21 +0700 Subject: [PATCH 2/2] =?UTF-8?q?feat(assets):=20#1628=20GEX44=20deploy=20pa?= =?UTF-8?q?ckage=20=E2=80=94=20TripoLibraryImport.cs=20+=20deploy=20runboo?= =?UTF-8?q?k;=20prop=20registry=20refs=20.glb->.fbx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TripoLibraryImport.cs: one-click importer config for all 68 assets (Generic/NoAvatar — NEVER Humanoid, drops Tripo clips; clip naming + walk/idle/run loop; _mat.mat albedo materials so the renderer can bind textures at spawn) - docs/asset-library/DEPLOY-GEX44.md: scp/untar/import/verify runbook for the box - 35 prop registry model_refs .glb->.fbx (Mac-side Blender convert; stock Unity has no glTF importer) --- data/asset-registry/registry.json | 140 +++++++++--------- docs/asset-library/DEPLOY-GEX44.md | 58 ++++++++ .../unity/scripts/TripoLibraryImport.cs | 113 ++++++++++++++ 3 files changed, 241 insertions(+), 70 deletions(-) create mode 100644 docs/asset-library/DEPLOY-GEX44.md create mode 100644 extensions/renderers/unity/scripts/TripoLibraryImport.cs diff --git a/data/asset-registry/registry.json b/data/asset-registry/registry.json index 26590933..af8c5a6c 100644 --- a/data/asset-registry/registry.json +++ b/data/asset-registry/registry.json @@ -253,10 +253,10 @@ }, "prop_tavern_table": { "kind": "prop", - "model_ref": "Assets/props/prop_tavern_table/prop_tavern_table.glb", + "model_ref": "Assets/props/prop_tavern_table/prop_tavern_table.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a sturdy wooden tavern table, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=095f6cbd-ef4a-4653-9266-2232840ed5eb rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_tavern_table/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a sturdy wooden tavern table, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=095f6cbd-ef4a-4653-9266-2232840ed5eb rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_tavern_table/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false @@ -483,220 +483,220 @@ }, "prop_wooden_chair": { "kind": "prop", - "model_ref": "Assets/props/prop_wooden_chair/prop_wooden_chair.glb", + "model_ref": "Assets/props/prop_wooden_chair/prop_wooden_chair.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a simple wooden tavern chair, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=26aa41de-5a72-4b84-945e-26bf79deae34 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_wooden_chair/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a simple wooden tavern chair, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=26aa41de-5a72-4b84-945e-26bf79deae34 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_wooden_chair/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_barrel": { "kind": "prop", - "model_ref": "Assets/props/prop_barrel/prop_barrel.glb", + "model_ref": "Assets/props/prop_barrel/prop_barrel.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden barrel with iron hoops, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=23596364-42f0-41ca-8f79-915c3c0a0187 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_barrel/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden barrel with iron hoops, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=23596364-42f0-41ca-8f79-915c3c0a0187 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_barrel/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_crate": { "kind": "prop", - "model_ref": "Assets/props/prop_crate/prop_crate.glb", + "model_ref": "Assets/props/prop_crate/prop_crate.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden shipping crate, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=46b33200-fe9f-499d-905a-2aae1771e0dd rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_crate/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden shipping crate, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=46b33200-fe9f-499d-905a-2aae1771e0dd rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_crate/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_market_stall": { "kind": "prop", - "model_ref": "Assets/props/prop_market_stall/prop_market_stall.glb", + "model_ref": "Assets/props/prop_market_stall/prop_market_stall.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden market stall with canvas awning, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=3a5bf2cb-1dde-4b7e-89d2-e0253b446bc4 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_market_stall/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden market stall with canvas awning, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=3a5bf2cb-1dde-4b7e-89d2-e0253b446bc4 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_market_stall/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_well": { "kind": "prop", - "model_ref": "Assets/props/prop_well/prop_well.glb", + "model_ref": "Assets/props/prop_well/prop_well.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone water well with wooden bucket and crank, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=27674d13-ecb6-4029-8e10-7fc6aabc14ef rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_well/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone water well with wooden bucket and crank, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=27674d13-ecb6-4029-8e10-7fc6aabc14ef rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_well/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_lantern_post": { "kind": "prop", - "model_ref": "Assets/props/prop_lantern_post/prop_lantern_post.glb", + "model_ref": "Assets/props/prop_lantern_post/prop_lantern_post.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron street lantern post, warm glow, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=5e24dd6a-824a-460d-af1b-6181819911e1 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_lantern_post/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron street lantern post, warm glow, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=5e24dd6a-824a-460d-af1b-6181819911e1 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_lantern_post/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_hand_cart": { "kind": "prop", - "model_ref": "Assets/props/prop_hand_cart/prop_hand_cart.glb", + "model_ref": "Assets/props/prop_hand_cart/prop_hand_cart.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden two-wheel hand cart, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=d2b2ca80-f953-4dff-9008-241dc312e4da rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_hand_cart/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden two-wheel hand cart, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=d2b2ca80-f953-4dff-9008-241dc312e4da rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_hand_cart/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_signpost": { "kind": "prop", - "model_ref": "Assets/props/prop_signpost/prop_signpost.glb", + "model_ref": "Assets/props/prop_signpost/prop_signpost.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden signpost with hanging tavern sign, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=c024d005-ab4e-406d-954b-0fdd02cc4c82 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_signpost/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden signpost with hanging tavern sign, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=c024d005-ab4e-406d-954b-0fdd02cc4c82 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_signpost/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_anvil": { "kind": "prop", - "model_ref": "Assets/props/prop_anvil/prop_anvil.glb", + "model_ref": "Assets/props/prop_anvil/prop_anvil.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a blacksmith anvil on a tree stump, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8b9f6ff3-4874-4d09-8be5-5daf7a951239 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_anvil/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a blacksmith anvil on a tree stump, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8b9f6ff3-4874-4d09-8be5-5daf7a951239 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_anvil/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_fountain": { "kind": "prop", - "model_ref": "Assets/props/prop_fountain/prop_fountain.glb", + "model_ref": "Assets/props/prop_fountain/prop_fountain.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone town fountain with tiered basin, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=90bee4bb-bbe0-435a-917c-69ea6c51c0bf rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_fountain/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone town fountain with tiered basin, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=90bee4bb-bbe0-435a-917c-69ea6c51c0bf rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_fountain/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_bench": { "kind": "prop", - "model_ref": "Assets/props/prop_bench/prop_bench.glb", + "model_ref": "Assets/props/prop_bench/prop_bench.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden park bench, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=238f7a93-3cf5-4829-b4b8-15127baa250f rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bench/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden park bench, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=238f7a93-3cf5-4829-b4b8-15127baa250f rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bench/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_treasure_chest": { "kind": "prop", - "model_ref": "Assets/props/prop_treasure_chest/prop_treasure_chest.glb", + "model_ref": "Assets/props/prop_treasure_chest/prop_treasure_chest.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ornate wooden treasure chest with iron bands, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=94b09304-1427-480c-95b2-49967a76a583 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_treasure_chest/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ornate wooden treasure chest with iron bands, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=94b09304-1427-480c-95b2-49967a76a583 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_treasure_chest/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_sarcophagus": { "kind": "prop", - "model_ref": "Assets/props/prop_sarcophagus/prop_sarcophagus.glb", + "model_ref": "Assets/props/prop_sarcophagus/prop_sarcophagus.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ancient stone sarcophagus with carved lid, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=a3a4a8cb-7e0b-40b7-9847-0b57a13e8b00 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_sarcophagus/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ancient stone sarcophagus with carved lid, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=a3a4a8cb-7e0b-40b7-9847-0b57a13e8b00 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_sarcophagus/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_iron_gate": { "kind": "prop", - "model_ref": "Assets/props/prop_iron_gate/prop_iron_gate.glb", + "model_ref": "Assets/props/prop_iron_gate/prop_iron_gate.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wrought iron dungeon gate, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=656c9a28-67b8-447a-a651-4ebae8498c77 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_iron_gate/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wrought iron dungeon gate, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=656c9a28-67b8-447a-a651-4ebae8498c77 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_iron_gate/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_torch_sconce": { "kind": "prop", - "model_ref": "Assets/props/prop_torch_sconce/prop_torch_sconce.glb", + "model_ref": "Assets/props/prop_torch_sconce/prop_torch_sconce.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wall-mounted iron torch sconce with flame, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=c3d015a2-e825-42ca-8996-02c291e7c9f1 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_torch_sconce/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wall-mounted iron torch sconce with flame, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=c3d015a2-e825-42ca-8996-02c291e7c9f1 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_torch_sconce/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_stone_pillar": { "kind": "prop", - "model_ref": "Assets/props/prop_stone_pillar/prop_stone_pillar.glb", + "model_ref": "Assets/props/prop_stone_pillar/prop_stone_pillar.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ancient carved stone pillar, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8c9f15b2-ce51-4b2e-9f39-97edfd306ccc rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_stone_pillar/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a ancient carved stone pillar, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8c9f15b2-ce51-4b2e-9f39-97edfd306ccc rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_stone_pillar/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_rubble_pile": { "kind": "prop", - "model_ref": "Assets/props/prop_rubble_pile/prop_rubble_pile.glb", + "model_ref": "Assets/props/prop_rubble_pile/prop_rubble_pile.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a pile of broken stone rubble, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=f7bab24a-354e-4557-8aa9-cf84b120b250 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_rubble_pile/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a pile of broken stone rubble, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=f7bab24a-354e-4557-8aa9-cf84b120b250 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_rubble_pile/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_altar": { "kind": "prop", - "model_ref": "Assets/props/prop_altar/prop_altar.glb", + "model_ref": "Assets/props/prop_altar/prop_altar.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a dark stone ritual altar with carved runes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=034f2d32-85cd-4b35-8bdc-e8e893280972 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_altar/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a dark stone ritual altar with carved runes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=034f2d32-85cd-4b35-8bdc-e8e893280972 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_altar/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_brazier": { "kind": "prop", - "model_ref": "Assets/props/prop_brazier/prop_brazier.glb", + "model_ref": "Assets/props/prop_brazier/prop_brazier.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron brazier with burning coals, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=40f67396-d849-4ee0-b6e0-acb22191c013 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_brazier/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron brazier with burning coals, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=40f67396-d849-4ee0-b6e0-acb22191c013 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_brazier/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_wooden_door": { "kind": "prop", - "model_ref": "Assets/props/prop_wooden_door/prop_wooden_door.glb", + "model_ref": "Assets/props/prop_wooden_door/prop_wooden_door.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a heavy wooden dungeon door with iron hinges, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=b5929568-0387-4a6a-9fdb-cb8a54edd2b6 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_wooden_door/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a heavy wooden dungeon door with iron hinges, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=b5929568-0387-4a6a-9fdb-cb8a54edd2b6 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_wooden_door/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_gargoyle_statue": { "kind": "prop", - "model_ref": "Assets/props/prop_gargoyle_statue/prop_gargoyle_statue.glb", + "model_ref": "Assets/props/prop_gargoyle_statue/prop_gargoyle_statue.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a crouching stone gargoyle statue, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=d47f5dec-8912-44b2-8738-5029172e3011 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_gargoyle_statue/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a crouching stone gargoyle statue, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=d47f5dec-8912-44b2-8738-5029172e3011 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_gargoyle_statue/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_bookshelf": { "kind": "prop", - "model_ref": "Assets/props/prop_bookshelf/prop_bookshelf.glb", + "model_ref": "Assets/props/prop_bookshelf/prop_bookshelf.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a tall wooden bookshelf filled with old tomes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8c1fadb4-6e53-4585-a82e-eb4aa1f788d8 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bookshelf/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a tall wooden bookshelf filled with old tomes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=8c1fadb4-6e53-4585-a82e-eb4aa1f788d8 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bookshelf/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false @@ -713,20 +713,20 @@ }, "prop_throne": { "kind": "prop", - "model_ref": "Assets/props/prop_throne/prop_throne.glb", + "model_ref": "Assets/props/prop_throne/prop_throne.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a imposing stone throne on a small dais, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=497b0674-8893-4f6f-b21e-a12b0fa3ed53 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_throne/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a imposing stone throne on a small dais, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=497b0674-8893-4f6f-b21e-a12b0fa3ed53 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_throne/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_portcullis": { "kind": "prop", - "model_ref": "Assets/props/prop_portcullis/prop_portcullis.glb", + "model_ref": "Assets/props/prop_portcullis/prop_portcullis.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron portcullis gate, half-raised, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=6fb4800a-e97a-4e3f-afb4-ffcfc99fefc0 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_portcullis/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a iron portcullis gate, half-raised, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=6fb4800a-e97a-4e3f-afb4-ffcfc99fefc0 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_portcullis/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false @@ -763,10 +763,10 @@ }, "cre_mimic": { "kind": "prop", - "model_ref": "Assets/props/cre_mimic/cre_mimic.glb", + "model_ref": "Assets/props/cre_mimic/cre_mimic.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a mimic monster, a treasure chest with teeth and a long tongue, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=488bac50-2279-4a2a-a3f2-6a666486c5a2 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_mimic/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a mimic monster, a treasure chest with teeth and a long tongue, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=488bac50-2279-4a2a-a3f2-6a666486c5a2 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/cre_mimic/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false @@ -793,60 +793,60 @@ }, "prop_weapon_rack": { "kind": "prop", - "model_ref": "Assets/props/prop_weapon_rack/prop_weapon_rack.glb", + "model_ref": "Assets/props/prop_weapon_rack/prop_weapon_rack.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden weapon rack with swords and axes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=48404ae4-5455-46a6-9860-bf5d7aeb1a07 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_weapon_rack/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden weapon rack with swords and axes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=48404ae4-5455-46a6-9860-bf5d7aeb1a07 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_weapon_rack/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_armor_stand": { "kind": "prop", - "model_ref": "Assets/props/prop_armor_stand/prop_armor_stand.glb", + "model_ref": "Assets/props/prop_armor_stand/prop_armor_stand.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a armor stand displaying a suit of chainmail, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=cb4af21a-e1d0-43dc-9b60-bd76a547ad01 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_armor_stand/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a armor stand displaying a suit of chainmail, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=cb4af21a-e1d0-43dc-9b60-bd76a547ad01 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_armor_stand/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_stocks": { "kind": "prop", - "model_ref": "Assets/props/prop_stocks/prop_stocks.glb", + "model_ref": "Assets/props/prop_stocks/prop_stocks.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden pillory stocks, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=e40c6efa-84cd-498a-92f9-825c2844769a rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_stocks/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a wooden pillory stocks, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=e40c6efa-84cd-498a-92f9-825c2844769a rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_stocks/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_candelabra": { "kind": "prop", - "model_ref": "Assets/props/prop_candelabra/prop_candelabra.glb", + "model_ref": "Assets/props/prop_candelabra/prop_candelabra.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a tall iron candelabra with five lit candles, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=2235b3b7-2d19-4395-93fa-40ccc87fc3d9 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_candelabra/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a tall iron candelabra with five lit candles, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=2235b3b7-2d19-4395-93fa-40ccc87fc3d9 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_candelabra/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_standing_torch": { "kind": "prop", - "model_ref": "Assets/props/prop_standing_torch/prop_standing_torch.glb", + "model_ref": "Assets/props/prop_standing_torch/prop_standing_torch.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a standing iron torch with flame, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=79212960-4b1b-4492-a0d7-f2f3657539d3 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_standing_torch/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a standing iron torch with flame, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=79212960-4b1b-4492-a0d7-f2f3657539d3 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_standing_torch/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_bed": { "kind": "prop", - "model_ref": "Assets/props/prop_bed/prop_bed.glb", + "model_ref": "Assets/props/prop_bed/prop_bed.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a simple wooden bed with wool blanket, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=cc489c35-fccb-41de-bfdd-36c66cb2878c rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bed/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a simple wooden bed with wool blanket, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=cc489c35-fccb-41de-bfdd-36c66cb2878c rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_bed/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false @@ -883,30 +883,30 @@ }, "prop_campfire": { "kind": "prop", - "model_ref": "Assets/props/prop_campfire/prop_campfire.glb", + "model_ref": "Assets/props/prop_campfire/prop_campfire.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone-ringed campfire with burning logs, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=7e117646-bbbb-4eca-b2fe-6bb213e9b69f rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_campfire/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a stone-ringed campfire with burning logs, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=7e117646-bbbb-4eca-b2fe-6bb213e9b69f rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_campfire/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_dungeon_stairs": { "kind": "prop", - "model_ref": "Assets/props/prop_dungeon_stairs/prop_dungeon_stairs.glb", + "model_ref": "Assets/props/prop_dungeon_stairs/prop_dungeon_stairs.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a worn stone dungeon stairs descending, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=3d6ee0ef-1c5f-4adf-81ac-3607c6bfef61 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_dungeon_stairs/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a worn stone dungeon stairs descending, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=3d6ee0ef-1c5f-4adf-81ac-3607c6bfef61 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_dungeon_stairs/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false }, "prop_barricade": { "kind": "prop", - "model_ref": "Assets/props/prop_barricade/prop_barricade.glb", + "model_ref": "Assets/props/prop_barricade/prop_barricade.fbx", "albedo_ref": null, "anim_ref": null, - "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a makeshift wooden barricade with spikes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=71215094-1c25-4460-a358-05a96d288c09 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_barricade/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid).", + "gen_recipe": "#1628 Tripo3D bulk demo library (2026-07-21). Prompt: 'a makeshift wooden barricade with spikes, stylized hand-painted dark fantasy RPG, muted earthy palette, game-ready low poly, isolated on plain background'. gen_task=71215094-1c25-4460-a358-05a96d288c09 rig_task=None. Clips: none (avian: no working presets 2026-07-21). Local binaries: /Volumes/LEXAR/Codex/worldos-asset-library/prop_barricade/ (deploy model.glb to this path; FBX imports untextured -> assign albedo separately; import animationType=Generic NEVER Humanoid). NOTE: model_ref updated .glb->.fbx (Mac-side Blender convert for the box; source glb in the deploy tarball).", "version": "1.0.0", "critic_score": 0.0, "default_used": false diff --git a/docs/asset-library/DEPLOY-GEX44.md b/docs/asset-library/DEPLOY-GEX44.md new file mode 100644 index 00000000..b3fdeee8 --- /dev/null +++ b/docs/asset-library/DEPLOY-GEX44.md @@ -0,0 +1,58 @@ +# #1628 BG3-Style Demo Asset Library — GEX44 Deploy Package + +**68 Tripo3D assets** (33 rigged + animated, 35 static props) for the WorldOS PoE2-style demo: +12 BG3-class party members in signature races, 6 town NPCs, 13 creatures, 2 bosses +(young red dragon 4×4 Gargantuan + ogre chieftain), 35 town/dungeon props. +Source issue: electricsheephq/WorldOS#1628 · code branch: `codex/1628-bg3-demo-asset-library` (PR #1635). + +## Package layout (this tarball) + +``` +Assets/cast// 33 rigged assets: .fbx (rigged), anim_.fbx, albedo.jpg|png, _mat (made on box) +Assets/props// 35 static props: .fbx (Blender-converted Mac-side), albedo.jpg|png (+ source .glb) +TripoLibraryImport.cs Unity editor script — configures all 68 importers in one menu click +deploy_manifest.json asset_id -> kind / unity_dir / model / clips / albedo +generation_manifest.jsonl full Tripo provenance: prompts, gen/rig task ids, per-file bytes +``` + +## Deploy on GEX44 (`evaos-gpu-gex44-1`, Unity project `/home/unity/worldos-unity`) + +1. **Copy + untar** into the Unity project root (paths in the tarball already mirror `Assets/`): + ``` + scp -o ControlPath=/tmp/gex44-cm.sock worldos-asset-library-deploy.tar.gz root@:/tmp/ + ssh -o ControlPath=/tmp/gex44-cm.sock root@ \ + 'tar xzf /tmp/worldos-asset-library-deploy.tar.gz -C /home/unity/worldos-unity && \ + chown -R unity:unity /home/unity/worldos-unity/Assets/cast /home/unity/worldos-unity/Assets/props' + ``` + (ControlMaster socket per WorldOS-GUI-RUNBOOK §GPU-VM lane; host in `~/.openclaw/secrets/gex44.env`.) +2. **Install the import script**: copy `TripoLibraryImport.cs` to + `/home/unity/worldos-unity/Assets/Editor/` (any Editor folder), `chown unity:unity`. +3. **In the Editor** (launch via `/home/unity/launch_editor.sh`, DISPLAY=:0): + menu **Tools → WorldOS → Tripo Library → Configure #1628 library**. + Expect one log line: `[TripoLib] configured 68 models, ~70 clips, 68 albedo materials`. +4. **Registry is already wired**: PR #1635 adds all 68 rows to `data/asset-registry/registry.json` + (exact-resolve verified). The renderer resolves `asset_id` → these paths; bind `_mat.mat` + (or `albedo.jpg` directly) at spawn — Tripo FBX imports untextured by design. + +## Hard-won constraints (do NOT rediscover) + +- **Generic, never Humanoid**: Tripo bone names don't map to Unity's Humanoid avatar; a Humanoid + import **silently drops all clips**. The import script enforces `Generic/NoAvatar`. +- **FBX imports untextured**: albedo was pre-extracted from each source GLB Mac-side + (`extract_glb_albedo.py`); the UVs match the rigged FBX because both derive from the same GLB. +- **Clip coverage by rig type**: bipeds walk/idle/run/slash (party) or walk/idle (NPCs); + quadruped/hexapod/octopod **walk only**; **avian (raven, harpy) rigged but CLIPLESS** — Tripo + has zero working avian retarget presets (probed exhaustively 2026-07-21, error 1004). + Use avian units perched/static or hand-animate later. +- **Props are FBX** (converted Mac-side via Blender — the box has none); source `.glb` included + as fallback if the project has glTFast. +- The two v3.1 bosses are heavy (dragon 178 MB, ogre 324 MB on disk) — first import will take minutes. + +## Verification gate (post-deploy) + +1. Import log line above (counts match). +2. Pick `pc_fighter_human`: Animation window shows Idle/Walk/Run/Slash takes; drag into a test + scene, assign `pc_fighter_human_mat` — textured, T-pose-free (bind pose reads correctly). +3. `boss_young_red_dragon` walk clip plays on its Generic rig. +4. `viewer/asset_registry.py` resolve check (Mac-side): `pc_fighter_human`/`prop_throne` resolve + `via exact` (already verified pre-handoff). diff --git a/extensions/renderers/unity/scripts/TripoLibraryImport.cs b/extensions/renderers/unity/scripts/TripoLibraryImport.cs new file mode 100644 index 00000000..57129bc2 --- /dev/null +++ b/extensions/renderers/unity/scripts/TripoLibraryImport.cs @@ -0,0 +1,113 @@ +using UnityEngine; +using UnityEditor; +using System.IO; + +/// +/// TripoLibraryImport — one-shot importer configuration for the #1628 BG3-style demo asset +/// library (68 Tripo3D assets: 33 rigged cast/monsters + 35 static props). +/// +/// CRITICAL Tripo-vs-Meshy difference (verified 2026-06-28, TRIPO_PIPELINE.md): Tripo bone +/// names (tripo::Spine_0, ...) do NOT auto-map to Unity's Humanoid avatar — a Humanoid import +/// SILENTLY DROPS the animation clips (clipAnims=0). So unlike CharsV3Import (Meshy, Humanoid), +/// everything here imports as **Generic / NoAvatar**, which preserves the embedded takes. +/// +/// What it does per asset under Assets/cast// and Assets/props//: +/// .fbx -> Generic, importAnimation on, materials InPrefab +/// anim_.fbx -> Generic + the single take renamed to ; Walk/Idle/Run loop +/// albedo.jpg/png -> a saved Material asset (_mat.mat, Standard shader, _MainTex = albedo) +/// so the renderer/registry can bind it at runtime (Tripo FBX imports +/// UNTEXTURED — the albedo lives in the source GLB and was pre-extracted +/// Mac-side via extract_glb_albedo.py). +/// +/// Idempotent: safe to re-run; it only rewrites importer settings and material assets. +/// +public static class TripoLibraryImport +{ + [MenuItem("Tools/WorldOS/Tripo Library/Configure #1628 library (Generic + clips + albedo mats)")] + public static void Configure() + { + int models = 0, clips = 0, mats = 0; + foreach (var root in new[] { "Assets/cast", "Assets/props" }) + { + if (!Directory.Exists(root)) { Debug.LogWarning("[TripoLib] missing " + root); continue; } + foreach (var dir in Directory.GetDirectories(root)) + { + string id = Path.GetFileName(dir); + string model = Path.Combine(dir, id + ".fbx"); + if (File.Exists(model)) { ConfigureModel(model); models++; } + foreach (var anim in Directory.GetFiles(dir, "anim_*.fbx")) + { + string clip = Path.GetFileNameWithoutExtension(anim).Substring("anim_".Length); + ConfigureClip(anim, clip, IsLoop(clip)); + clips++; + } + mats += EnsureAlbedoMaterial(dir, id) ? 1 : 0; + } + } + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + Debug.Log(string.Format("[TripoLib] configured {0} models, {1} clips, {2} albedo materials", models, clips, mats)); + } + + static bool IsLoop(string clip) + { + var c = clip.ToLowerInvariant(); + return c == "walk" || c == "idle" || c == "run"; + } + + static void ConfigureModel(string path) + { + var imp = AssetImporter.GetAtPath(path) as ModelImporter; + if (imp == null) { Debug.LogWarning("[TripoLib] not a model: " + path); return; } + imp.animationType = ModelImporterAnimationType.Generic; // NEVER Humanoid — drops Tripo clips + imp.avatarSetup = ModelImporterAvatarSetup.NoAvatar; + imp.importAnimation = true; + imp.importBlendShapes = false; + imp.materialImportMode = ModelImporterMaterialImportMode.ImportStandard; + imp.materialLocation = ModelImporterMaterialLocation.InPrefab; + imp.SaveAndReimport(); + } + + static void ConfigureClip(string path, string clipName, bool loop) + { + var imp = AssetImporter.GetAtPath(path) as ModelImporter; + if (imp == null) { Debug.LogWarning("[TripoLib] not a model: " + path); return; } + imp.animationType = ModelImporterAnimationType.Generic; + imp.avatarSetup = ModelImporterAvatarSetup.NoAvatar; + imp.importAnimation = true; + var takes = imp.defaultClipAnimations; + if (takes != null && takes.Length > 0) + { + for (int i = 0; i < takes.Length; i++) + { + takes[i].name = clipName; + takes[i].loopTime = loop; + } + imp.clipAnimations = takes; + } + imp.SaveAndReimport(); + } + + static bool EnsureAlbedoMaterial(string dir, string id) + { + string texPath = null; + foreach (var ext in new[] { "albedo.jpg", "albedo.png" }) + { + var p = Path.Combine(dir, ext); + if (File.Exists(p)) { texPath = p; break; } + } + if (texPath == null) return false; + string matPath = Path.Combine(dir, id + "_mat.mat"); + var tex = AssetDatabase.LoadAssetAtPath(texPath); + if (tex == null) return false; + var mat = AssetDatabase.LoadAssetAtPath(matPath); + if (mat == null) + { + mat = new Material(Shader.Find("Standard")); + AssetDatabase.CreateAsset(mat, matPath); + } + mat.mainTexture = tex; + EditorUtility.SetDirty(mat); + return true; + } +}