Commit Graph

5 Commits

Author SHA1 Message Date
type-two
b0188a41f0 to3d: use live trellis2_mlx operator (trellis_mac has no worker); 2400s farm wait; factory v5 retries
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 23:14:22 +10:00
type-two
9c51ed1b58 object3d gen template for rigid props + batch factory runner
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 21:55:13 +10:00
type-two
7c5fc53224 Registry writer: make the four non-file-drop consumers one-click, and keep 3GOD as a depot
Most GODVERSE consumers do not scan a directory — they load from a literal array in source
(djsim/procity PED_NAMES, thriftgod HERO_FLOOR) or a JSON manifest, so a dropped file does
nothing until its NAME is in that list. tools/registry.py makes that edit, and the export hub
now offers it instead of only reporting the file:line.

Paranoid by construction, because the targets are live shipping games:
· dry-run by default; write:true is required to touch source
· idempotent — an existing entry is a no-op, verified against a real djsim ped
· backs up to <file>.bak-<stamp> before every write
· refuses if the anchor matches anything other than exactly once, rather than guessing which
  of several arrays was meant
· handles djsim keeping TWO live copies of PED_NAMES (rigs.js owns the street, index.html has
  a second) — updating one and not the other is a silent half-fix
· works locally and over ssh, since djsim lives on ultra

Bug I introduced and caught while testing: the first implementation inserted after the opening
bracket, i.e. PREPENDED. procity's loadPedFleet fills fixed slots BY PED_NAMES INDEX, so that
silently reassigns every existing character — and my own note on that target said "appending is
safe, reordering is not" three lines above the code that did it. Now scans to the matching
close bracket (string-aware) and appends. Verified: leading entries byte-identical, new name at
the tail, then reverted from backup with git clean.

Also corrected procity's path — its rigs.js is under web/js/citizens/, not crowd/, and declares
`export const`; the two games diverged despite sharing the loadPedFleet shape.

On 3GOD: NOT retired. It looked like a spent planning experiment, but thriftgod fetches its
props from it at runtime in production (index.html:1176 DEPOT = 'https://digalot.fyi/3god') and
procity does the same — 773 live assets. It is two things bolted together: a dumb asset CDN
(/a, /dl, /t, /api/list) which stays, and an authoring UI (upload/tag/thumb/fetch/meta) which
wardrobegod now supersedes. Absorb the bench, keep the depot, publish into it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 21:55:04 +10:00
type-two
cfca6708ab Phase 2: reskin engine — dress the nude TRELLIS bodies without fitting anything
Every anatomy body is an independent TRELLIS reconstruction: no shared topology, no vertex
correspondence, its own UV atlas. That kills garment portability — a fitted mesh can't move
between bodies. Reskin sidesteps the whole problem by repainting the atlas the body already
has, so it works on unstructured meshes and needs no rig.

Chain (/api/reskin), all local except one farm call:
  render_plates.py  -> bind-pose front/back ortho plates, EEVEE, 1024, transparent
  mflux_image_edit  -> "put <garment> from image 2 onto the person in image 1", per plate
  align_plate.py    -> re-fit the edited figure to the original bbox. The edit model redraws
                       at its own scale/offset, and the projection bake assumes the original
                       framing, so skipping this makes the body sample background.
  bake_skin.py      -> Cycles DIFFUSE projection onto the mesh's real UVs, front/back split
                       on normal.Y
Costume swapping in the browser is just a material.map change, so pre-baked outfits toggle
instantly with no re-bake; the bare map is retained so it's reversible.

Fixed a real defect in the inherited baker: planar front/back projection has no idea a head
is round, so side-facing skull polygons sampled whatever front-plate pixel sat at their x/z
and painted a ghost second face down the side of the head (clearly visible on phrtt2). Since
this tier repaints CLOTHES, the bake now keeps the body's own texture above a neck-height
cutoff (default 0.87 of body height, -1 to disable), sampling it through the mesh's real UVs.

Verified end-to-end on phrtt2 (1 mesh / 1 UVMap / 1 material / 4,364 tris — the reskin class):
farm try-on produced a convincing corduroy jacket holding the exact T-pose, and the bake put
it on the model. Known ceiling, unchanged and by design: the silhouette does not move, so this
sells tight and printed garments and reads wrong for a heavy coat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 16:22:38 +10:00
type-two
294af7cf1d Phase 3: the 2D paper-doll tier — 392 garments you can actually change
The flat cut-outs were the cheapest content on the board and the only tier with a shipping
consumer, but wardrobegod couldn't show one: scan() filtered PNGs out of garments/ (fixed in
Phase 0) and there was no compositor, no slots, no preview. Now there is a working dress-up.

· library/doll/ seeded with 90sDJsim's 441 shipped sprites (165 top, 110 bottom, 60 shoes,
  57 hat, base body) — an instant starter wardrobe rather than a cold start.
· tools/doll.py wraps djsim's compositor. It deliberately does NOT import doll_composite:
  that module pulls numpy at import time for a keyer and an HSV recolour we never use (the
  farm's RMBG-2.0 does our keying), and numpy isn't installable here under PEP 668. Instead
  the measured anchors are parsed out of its source with ast, so there is still exactly one
  source of truth and they cannot drift; place() is a pure-PIL port.
· slugify() reproduces djsim's item_art() _art_slug character for character, verified against
  it. That equality IS the drop-in contract — a near-miss silently falls back to generic slot
  art instead of erroring, so it's the kind of bug you'd ship without noticing.
· /api/doll/gen runs the proven pipeline: flux_local on SOLID GREEN -> farm RMBG-2.0 ->
  staged to 704x1408. Green is not a preference: grey and checkerboard backgrounds eat
  garments in the key, and flux can't spell, so no text ever goes in the prompt.
· /api/doll/compose composes server-side with PIL, so the browser preview and the exported
  PNG are the same bytes rather than two renderers that drift.
· /api/doll/export writes into a LIVE game directory, so it defaults to a dry run and refuses
  any stem without _i_ — overwriting a generic slot fallback would restyle every unarted item
  in a shipping game.
· UI: a doll 2D tab with per-slot pickers, randomise, strip, and export.

Verified: composed a dressed doll from real sprites (correct base->bottom->shoes->top->hat
order), catalogue reports 392 layers, export dry-run and the generic-art guard both behave.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 16:07:13 +10:00