Files
security-game/.agents/skills/gig-line-blender-asset-contract/references/asset-contract.md
T
zwitschi 724e8b183f
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped
Add tracked AI skills for Blender assets and release QA
2026-11-03 19:53:32 +01:00

5.7 KiB
Raw Blame History

Asset Contract Reference

This is a working summary. The authoritative sources remain docs/blender-assets.md, docs/asset-tooling.md, ADR-0013, the tests in src/test/tests/ and the constants in tools/blender_assets.py / tools/npc_pipeline.py.

Library inventory

  • Character variants (8): npc_casual, npc_jacket, npc_coat, npc_vest, npc_dress, npc_hoodie, npc_firefighter, npc_guard.
  • Frozen fallback: npc_base / assets/models/generated/npc_base.glb.
  • Gear: 18 attach-space pieces covering head, back, chest and hand items.
  • Library props: 20 Blender-authored props plus 6 generated props.
  • Venues: procedural venues in src/game/world_builder.gd; Blender venue geometry follows the same budgets and collision/provenance rules.

Skeleton and geometry

The contract skeleton has 13 bones:

Head, Spine, Neck,
HipL, HipR,
KneeL, KneeR,
ShoulderL, ShoulderR,
ElbowL, ElbowR,
HandL, HandR

Requirements:

  • npc_base mesh node exists and is skinned under Rig.
  • Limb node names stay stable for NpcAvatar and tests.
  • Front is Blender −Y / Godot +Z.
  • Feet are grounded at approximately y = 0; no floating origin.
  • Units are metres; character height is approximately 1.8 m.
  • No zero-area/duplicate degenerate faces in the exported mesh.
  • Every character has UVs in [0,1] unless a planned UDIM/atlas change is explicitly accepted.

Material slots

Exactly these five tint slots:

skin, cloth, pants, accessory, hair
  • Neutral albedo is authored in Blender; runtime tinting is authoritative.
  • Slot names are contract values; do not rename or add a sixth slot casually.
  • The procedural fallback (NpcAvatar._build_body) must keep working when the GLB is missing.

Budgets

Asset Limit
Library character 8,000 triangles / 8,000 glTF vertices
npc_base fallback 6,000 triangles / 4,000 vertices
Gear piece 1,500 triangles
Prop 4,000 triangles
Library prop/venue total must stay inside the venue tests and library budget

CHAR_MAX_TRIS, CHAR_MAX_VERTS, GEAR_MAX_TRIS, PROP_MAX_TRIS and related constants live in tools/blender_assets.py. The budget is per character, not an average. Measure after every mesh change. Do not lower the cap to make a diff pass.

Gear and hand items

  • Gear is authored in the attach-point space documented by GEAR / GEAR_ATTACH / ATTACH_BLENDER.
  • blender_assets.py fit measures gear boxes against the character's head band, clothing radius and back clearance.
  • Runtime offsets are intentional:
    • NpcAvatar.GEAR_OFFSETS = {"lanyard": Vector3(0,0,0.04), "firefighter_helmet": Vector3(0,0.03,0)}
    • NpcAvatar.HAND_ITEM_FORWARD = Vector3(0,0,0.04)
  • An offset is not an authored-asset change; do not bake it into the GLB without a separate contract decision.
  • Open-palm grip (no finger-curl rig) is the accepted stylized limit.

Textures and AO

  • NPC maps are 256² albedo + normal + packed ORM.
  • TEX_SIZE = 256 in tools/npc_pipeline.py.
  • Fabric UV scale is Materials.NPC_FABRIC_UV_SCALE = Vector3(4,4,1).
  • Cloth/pants skip the per-character baked AO; skin/hair/gear keep it. This avoids the large blotchy magnification that appeared at 256².
  • Gear/props may have their own AO maps; tools/bake_ao.py writes <name>_ao.png next to the GLB and Godot wires it into the AO channel.
  • Never overwrite an existing committed image; use a new -vN candidate and promote only after review.
  • Run python3 tools/asset_pipeline.py audit <path> and the relevant npc_pipeline.py audit before committing map changes.

File map

Path Role
tools/blender_assets.py Catalogue, builders, audit/fit/inspect/texels/sheet.
tools/npc_pipeline.py npc_base builder, texture preparation and audit.
tools/bake_ao.py Blender AO bake into <name>_ao.png.
tools/npc_proportions.py Exported-GLB proportion audit (no Blender).
tools/npc_baseline.py Contact sheets/comparisons (no Blender).
assets/models/blender/manifest.json Generated asset manifest.
assets/models/blender/**/*.glb Committed library assets.
assets/models/generated/npc_base.glb Frozen NPC fallback.
assets/textures/npc/*_{albedo,normal,orm}.png Committed NPC maps.
src/test/capture_npc_baseline.gd 48-frame neutral baseline.
src/test/capture_npc_review.gd 96-frame final-context review.

Provenance and source rules

  • Procedural Blender assets are project-owned.
  • External/CC assets need ADR-0015 clearance: CC0 preferred, CC-BY only with attribution in CREDITS.md; no service assets with redistribution limits.
  • Editable .blend files under assets/models/blender_src/ are gitignored; only exported .glb, AO maps, manifests and committed preview sheets ship.
  • AI-generated source images are development inputs, not shipped assets. Keep raw generations under gitignored paths until picked, checked and credited.
  • Do not copy a downloaded/Street View/AI reference into a committed asset without the licence and provenance review.

Verification invariants

The asset pass is not complete unless:

  1. python3 tools/blender_assets.py audit exits 0.
  2. python3 tools/blender_assets.py fit exits 0 and the report is reviewed.
  3. python3 tools/npc_proportions.py report passes the stylized guide.
  4. python3 tools/npc_pipeline.py audit passes when the base/textures changed.
  5. The 48-frame baseline and 96-frame final-context review are captured, with no blank frames.
  6. The 24-NPC budget smoke is inside its frame budget.
  7. The full Godot suite and Python tooling tests pass.
  8. No runtime contract, renderer or dependency changed except the rebuilt assets and their generated metadata.