Lesson 249: Blender Hero glTF Export Hash Receipt on BUILD_RECEIPT (2026)
Direct answer: Before July playtest scale promotes fest_public while playtest_invite still runs, file gltf_export_hash_receipt_v1.json proving pinned gltf_export_preset_v1.json, modifier/armature freeze, sha256 on hero_playtest.glb + hero_export_manifest.json, re-export match, engine spot load, and optional cousin fab_8k_throttle_receipt_v1 (Lesson 230) when Fab textures ship—then promote BUILD_RECEIPT gltf_export_hash_ok. Distinct from 230 (8K URI throttle) and Lesson 248 (2D bridge spot).

Why this matters now (July 2027 playtest vs fest_public hero GLB drift)
July 2027 teams hotfix armor UVs on main while playtest-july-rc1 still serves Friday’s .glb. Facilitators report missing pauldrons and wrong material slot 0—engineering proves 8K throttle GREEN but never filed hero export identity. The Blender hero glTF export hash preflight is the ninety-second checklist—249 is the BUILD_RECEIPT milestone for gltf_export_hash per build_label.
Pair Lesson 204 when metallic looks flat despite matching hash, and Lesson 201 when the wrong depot ships the right file.
Beginner path (export → hash → promote)
| Step | Action | Success check |
|---|---|---|
| 1 | Pin gltf_export_preset_v1.json |
G1 pass |
| 2 | Freeze modifiers + export collection | G2 pass |
| 3 | Export GLB + write manifest | Files in art/characters/hero/ |
| 4 | sha256sum bundle + re-export |
G4 match |
| 5 | Godot/Unity stub import spot | G5 pass |
| 6 | File receipt + BUILD_RECEIPT | gltf_export_hash_ok: true |
Time: ~52 minutes first hero pin; ~15 minutes when preset and collection are frozen.
Developer path (gates G1–G6)
| Gate | Check | Fail when |
|---|---|---|
| G1 | Export preset versioned in repo | Ad-hoc glTF settings per branch |
| G2 | Modifier + armature freeze documented | GN eval changes vertex count |
| G3 | sha256 GLB + manifest |
Manifest-only hash |
| G4 | Re-export reproducibility | Second hash differs |
| G5 | Engine spot | Slot 0 / vertex policy mismatch |
| G6 | Receipt + BUILD_RECEIPT | Promote fest with stale GLB |
G1 — cousin receipt crosswalk
| Field | Cousin (230) | This lesson (249) |
|---|---|---|
| Schema | fab_8k_throttle_receipt_v1 |
gltf_export_hash_receipt_v1 |
| Scope | Texture URI ≤ 2048 | Whole hero GLB identity |
| Path | release-evidence/art/FAB_8K_THROTTLE_RECEIPT.json |
release-evidence/art/GLTF_EXPORT_HASH_RECEIPT.json |
Do not embed T1–T6 throttle proof inside 249 JSON—reference cousin when Fab paths present.
gltf_export_hash_receipt_v1.json
{
"schema": "gltf_export_hash_receipt_v1",
"build_label": "playtest-july-2027-rc1",
"character_id": "hero_combat",
"gltf_path": "art/characters/hero/hero_playtest.glb",
"manifest_path": "art/characters/hero/hero_export_manifest.json",
"export_preset": "tools/blender/gltf_export_preset_v1.json",
"sha256_bundle": "sha256:REPLACE_AFTER_COMPUTE",
"reexport_match": true,
"glb_bytes": 2458624,
"cousin_receipts": {
"fab_8k_throttle": "release-evidence/art/FAB_8K_THROTTLE_RECEIPT.json"
},
"engine_spot": {
"engine": "godot_4.5",
"vertex_count_ok": true,
"material_slot_0_ok": true
},
"gates": {
"G1_export_preset": "pass",
"G2_modifier_freeze": "pass",
"G3_sha256_bundle": "pass",
"G4_reexport": "pass",
"G5_engine_spot": "pass",
"G6_build_receipt": "pass"
},
"gltf_export_hash_ok": true,
"playtest_promotion_allowed": true
}
Pin under release-evidence/art/GLTF_EXPORT_HASH_RECEIPT.json.
BUILD_RECEIPT row (G6)
| Column | Pass when |
|---|---|
gltf_export_hash |
gltf_export_hash_ok: true |
fab_8k_throttle |
Cousin Lesson 230 when Fab ORM used |
sprite_bridge_hash_spot |
Lesson 248 2D lane independent |
ALTER TABLE release_publish_gate ADD COLUMN IF NOT EXISTS
gltf_export_hash_blocked BOOLEAN NOT NULL DEFAULT false;
Thursday row review — Hero GLB hash line: playtest hash = fest hash Y/N.
Key takeaways
- 230 throttle ≠ 249 export hash—both required for Fab heroes.
- Hash GLB + manifest together—vertex count drift lives in manifest.
build_labelmust match acrossplaytest_inviteandfest_publichero rows.- Draco preflight is separate—document
dracoin manifest. - Lesson 248 is 2D—do not conflate columns.
playtest_promotion_allowedhere ≠ Q4 capstone 253.- Re-export without manifest bump blocks facilitators silently.
- Cousin 204 fixes metallic channels—not missing armor meshes.
- File receipt before scaling concurrent playtest cohorts.
- Forward: Lesson 250 VO consent metadata (when published).
Common mistakes
- Promoting fest_public with newer
.glbthan playtest receipt. - Hashing
.blendinstead of exported.glb. - Draco on playtest only—WebGL SKU decode fail.
- Skipping cousin 230 when hero uses Fab ORM.
- Merging schemas into
fab_8k_throttle_receipt_v1.
Troubleshooting
| Symptom | Lane |
|---|---|
| Hash differs every export | G2 unstabilized modifiers |
| Godot hang | Lesson 230 |
| Flat metallic | Lesson 204 |
| Wrong combat frames | Lesson 248 |
| Wrong depot | Lesson 201 |
Mini exercise (50 minutes)
- Export with unstabilized modifier—confirm G4 fail.
- Pin G1 + G2; pass re-export match.
- Link cousin
FAB_8K_THROTTLE_RECEIPT.json. - File receipt; block fest promotion until playtest hash matches.
Continuity — Q4 2027 July playtest scale (245–253)
| Lesson | Receipt focus |
|---|---|
| 248 | Aseprite bridge hash spot |
| 249 (this) | Blender hero glTF export hash |
| 250 | Audacity VO consent metadata |
| 253 | Q4 capstone (queued) |
Previous: Lesson 248 — Aseprite sprite bridge hash spot
Next: Lesson 250 — Audacity VO consent metadata
FAQ
Same as Lesson 230?
230 = 8K texture URIs; 249 = hero GLB + manifest sha256 identity.
Same as export hash guide?
Guide = G1–G6 checklist; 249 = BUILD_RECEIPT promotion.
Same as Lesson 204?
204 = ORM channels; 249 = mesh/material export identity.
Need Draco preflight first?
Only if manifest sets draco: true—keep one policy per build_label.
Playtest and fest_public must share hero .glb identity—pin export, hash bundle, engine spot, cousin 230 when needed, then gltf_export_hash_ok on BUILD_RECEIPT.