destroyulator/LANES/LANE2-asset-pipeline-fracture.md
Monster Robot Party c03bb85c9f Add parallel-lane execution specs for Opus 4.8
LANES/PLAN.md         — verdict, GODVERSE pipeline architecture, shared contracts, 3GOD security note
LANES/LANE1-*.md      — Godot: grab/slide/smash record ritual + find-the-misfiled-disc mode (owns game/)
LANES/LANE2-*.md      — meshgod cell-fracture stage + Destroyulator prop batch -> 3GOD (owns ~/meshgod)
LANES/LANE3-*.md      — thriftgod-based web smash toy, Rapier physics, 3GOD props (owns web/)
LANES/KICKOFF.md      — per-lane opening prompts + collision-safety rules

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 16:47:47 +10:00

75 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LANE 2 — Asset pipeline: cell-fracture stage + Destroyulator prop batch
**Owns:** `~/Documents/meshgod` (SEPARATE repo — not the destroyulator monorepo).
**For:** an Opus 4.8 session. **Runs on:** M3 Ultra; Blender at `/Applications/Blender.app`.
## Objective
Give the meshgod factory a **fracture stage** so props arrive pre-shattered for smashing,
then batch-generate Destroyulator's workplace props and push them to 3GOD. This upgrades
Lanes 1 & 3 from "single-box smashable" to real shard-by-shard destruction.
## What already exists (read first)
- `meshgod/finish.py` + `scripts/finish_glb.py` — the **headless-Blender subprocess pattern
to copy**: launches `/Applications/Blender.app` `--background --python <script> -- <args>`,
parses a `FINISH_RESULT:{json}` line from stdout. Finishing does join→solidify (watertight!)
→decimate→brighten→normalize→export GLB.
- `meshgod/batch.py` — resumable manifest runner (`python3 -m meshgod.batch manifest <f.json>
--out <dir>`, content-hashed IDs, checkpoints, `--workers`).
- `meshgod/pipeline.py`, `config.py` — the OpenRouter→fal.ai→finish flow. **Cost is real**
(~$0.100.55/asset); fal key in gitignored `open.txt`. Check remaining credit before a big batch.
- 3GOD push: `MESHGOD/scripts/test_3god_push.py` (on M1) guards the depot auth/slug contract;
find/mirror the actual push helper meshgod uses to POST a finished GLB to digalot.fyi/3god.
## Deliverables
### 1. `meshgod/scripts/fracture_glb.py` — headless Blender cell-fracture
Mirror `finish_glb.py`'s structure exactly (arg parsing, `FRACTURE_RESULT:{json}` stdout line).
- Input: a finished watertight GLB + `--chunks N` (default 12) + `--out <path>`.
- Enable the **Cell Fracture** addon (`bpy.ops.preferences.addon_enable(module="object_fracture_cell")`)
and run `bpy.ops.object.add_fracture_cell_objects(source_limit=N, ...)` on the imported mesh.
(Blender 5.1 — verify the addon module name; if renamed/removed, fall back to a Voronoi
geometry-nodes or `boolean`-based split, but Cell Fracture is preferred.)
- Each chunk: recenter its origin to its own bounds center (so it can become a rigid body),
keep the parent's material.
- Export **all chunks as a single `<name>.fractured.glb`** whose root's direct children are the
chunk meshes named `chunk_00…chunk_NN` (SHARED-CONTRACT #2 in PLAN.md). Report chunk count +
whether any chunk is non-manifold.
### 2. `meshgod/fracture.py` (module) + CLI
`python3 -m meshgod.fracture <in.glb> --chunks 12 --out <out.fractured.glb>` — thin wrapper
that subprocess-launches the script (same pattern as `finish.py`). Optionally add a
`--fracture` flag to `batch.py` so a manifest entry can request `"fracture": {"chunks": 12}`
and get both `<name>.glb` + `<name>.fractured.glb` out.
### 3. `meshgod/manifests/destroyulator.json` — the prop batch
Workplace hero props, real-metre `height_m` + tri budgets. Include at least:
office **printer** (the boss!), office desk, monitor/CRT, desk phone, filing cabinet,
water cooler, office chair, ceiling fluorescent light, coffee mug, potted plant, wall clock,
cardboard box; record-store extras: turntable, amp/speaker, cash register, wall shelf.
Each entry: `{name, prompt, height_m, tris, fracture:{chunks}}`. ~16 assets ≈ $38, ~30 min.
**Confirm the fal budget covers it before running; if low, do the top 6 first.**
### 4. Push finished + fractured GLBs to 3GOD
Use meshgod's existing depot-push path. Land both the intact and `.fractured.glb` on the
digalot.fyi/3god shelf so Lanes 1 & 3 can pull them by slug.
## Acceptance
- `fracture_glb.py` on one finished GLB (e.g. `outputs/robot_game.glb`) yields a
`.fractured.glb` with ≥8 chunk children named `chunk_*`; verify by loading it in Blender
headless and printing child count + names.
- The manifest runs (or a 2-asset subset does) end-to-end: intact + fractured GLBs on disk,
watertight, correct scale, pushed to 3GOD (`GET /api/list` shows the new slugs).
## Gotchas
- Cell Fracture needs the mesh to be a single manifold object; run it AFTER finish's solidify.
- fal costs money per asset and the key is shared/rotating — read `open.txt`, don't hardcode,
and cap batch size to the remaining credit.
- Keep chunk counts modest (816). Hundreds of chunks tank the consuming physics engines.
## Definition of done
Fracture stage works and is documented; `destroyulator.json` (or its top-6 subset) generated,
finished, fractured, and pushed to 3GOD; committed + pushed to meshgod's own remote.
Post the list of produced slugs so Lanes 1 & 3 can consume them.