Commit Graph

12 Commits

Author SHA1 Message Date
m3ultra
12eb571357 Lane E R39 (6/n): THREE GLBs shipped as GLASS, not one — transmissionFactor 1 stripped, published, sha1-verified, and now GATED. Plus the arcade's three meshes.
Lane C measured the bookshelf's transmission halving interior draws (opshop/hall 191->104, book/hall
101->51, dept/hall 116->116 control). The cause, with vendored line numbers: three.module.js:16209
enters renderTransmissionPass(opaqueObjects, ...) whenever currentRenderList.transmissive is
non-empty, and :16433 re-renders the WHOLE OPAQUE LIST into a render target — every opaque draw
issued twice. Trigger is material.transmission > 0 (:6890), set from the glTF at GLTFLoader:1202.
And at 1.0 it is not 'a bit glassy': :494 does totalDiffuse = mix(totalDiffuse, transmitted.rgb,
material.transmission) — the diffuse term is REPLACED by the backdrop.

I SCANNED ALL 103 GLBs. Three carried it:
  procity_fit_bookshelf_01      mtl_10218_Bookshelves_v1     shipped and hurting (C's)
  procity_street_longbench_01   lambert3SG                   NOT WIRED — the 5.86 m arcade bench
                                                             the v9 charter names, on my R38
                                                             recommend list for Lane B
  procity_street_streetlight_01 Streetlight_HighResSG3       NOT WIRED — one per ~18 m of street
The two unwired ones are the worse finding: the street budget is 292/300 with EIGHT draws of margin,
and a pre-pass there costs another ~292, not eight. Armed, not fired.

FIXED SURGICALLY. pipeline/strip_transmission.py rewrites only the JSON chunk and copies BIN through,
printing sha1(BIN) before and after: BIN IDENTICAL on all three, tris/dims/mtl/img/tex unchanged.
KHR_materials_ior deliberately left (ior does not trigger the pre-pass).

PUBLISHED + VERIFIED under John's R22 standing authorization via the passwordless tailnet ingress:
6/6 HTTP 200 off the PUBLIC depot, byte counts exact, sha1 identical, depot copies re-scanned clean.
_published.json 56 -> 59.

GATED, which matters more than the fix: validate_manifest.py now HARD FAILS on transmissionFactor>0
with the three.js line numbers and the fix command in the message; glb_stat.py grew a transmission
column and a loud footer. Nobody looked for three epochs because a bookshelf is obviously not glass.

ALSO: the arcade's three meshes, published and catalogued the same round they were generated —
aframe_board 366 tris (<=16 inst), blade_sign 299 (17 inst), keycutter_sign 498 (1 inst). manifest
furniture 13->16, GLBs 36->39, validate 0 errors 0 warnings. blade_sign ships FLAGGED: its back face
carries TRELLIS-hallucinated art where the concept had no data, which is one more reason the
+0-draw perpendicular-quad answer is the recommendation and this GLB is the fallback.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 21:11:34 +10:00
m3ultra
74d6257940 Lane E R38 s2: the three GLBs PUBLISHED + sha1-verified off the public depot; the magpie is a magpie
A. DEPOT — closed, under John's R22 standing Lane-E authorization (the authority that
   shipped sit.glb in R28 and the nine R36 sweep assets). Pushed via the passwordless
   tailnet ingress: _published.json 53 -> 56, drift check clean. Then verified the way
   this lane verifies — FETCHED BACK OFF THE PUBLIC DEPOT and hashed, not "the upload
   said 200": magpie/paling_fence/water_tank all HTTP 200, byte counts exact, sha1
   identical to local, 3/3. _r38_results.PENDING_PUBLISH.json renamed, build_manifest
   re-run (GLBs 33 -> 36), validate_manifest 0 errors / 0 warnings.

B. THE MAGPIE TINT — done, not offered. The bird shipped as an all-black crow (R38 4d
   traced the loss to trellis2_mlx's PBR bake). "Hand-tint the atlas" is not a paint job:
   the bake is a smart-UV unwrap of ~100 islands and none of them announces itself as a
   nape. So pipeline/tint_atlas.py defines the tint in the MESH's frame and projects it
   through the UVs — rasterize every UV triangle to texel->(position,normal), evaluate
   soft anatomical windows on the positions (white nape behind a black crown, shoulder
   bar on the flanks only so the dorsal midline stays black, rump + tail base stopping
   short of the black terminal band), paint keeping the bake's own luminance as shading,
   then dilate 5 texels into the UV padding so no black fringe survives bilinear/mip.
   3-D masks give one consistent soft edge across every island at once; a 2-D blur could
   not (it would bleed island-to-island through the black background).
   GEOMETRY UNTOUCHED byte for byte: still 894 tris / 1 mtl / 1 img / 512^2 WebP / no
   Draco / 0.155x0.358x0.404 m. Painted luma median 0.84 (p90 0.95) vs the bake's 0.13.
   VERIFIED IN THE GAME'S OWN RENDERER: the PUBLISHED file loaded off digalot.fyi through
   the vendored GLTFLoader + three.js — 1 mesh, 894 tris, 512x512 texture decoded (which
   also proves the PIL-written WebP decodes in a browser).
   VERDICT: it reads. Pied and unmistakable at 64 and 48 px, still black-and-white at 32.
   Honest caveat: from directly below-and-in-front it stays dark — correct, a real
   magpie's bib and belly ARE black. Render: docs/shots/laneE/r38_magpie_tint.png.
   Standing after B's 4514cb9: an UPGRADE PATH, not a dependency — B's 182-tri procedural
   bird is 4.9x lighter and the right call. Nothing probes for the GLB and nothing should.

C. CORRECTIONS FOLDED INTO THE RECORD so the next asset round does not re-learn them:
   skins are 9.7 s not 5.7 s (1024^2, 1.78x the pixels, per-pixel identical) - the reuse
   list's "one line each" holds for 5 of 9 (extractGLB keeps only the FIRST material) -
   normalize.py's collapse decimator floors at the shell count on TRELLIS output while
   bake_lowpoly.py clears it every time - the 489 s outlier at 3.8x median means
   throughput plans on a tail, not a mean - furniture.js:30's stale comment is fixed by B.
   NEW, and the one worth keeping: an asset's tri budget is tris x THE INSTANCE COUNT THE
   PLACEMENT RULE IMPLIES. paling_fence is a good 1,121-tri panel and a rejected asset —
   905 instances = 1.01M tris, ~47x over. Ask the consuming lane for the instance count
   BEFORE generating anything that tiles, edges or repeats per-lot.

New tools, all on-device and $0: tint_atlas.py, render_views.py (view sheet + --eevee +
roster-consistent --thumb), view_sheet.py (the distance strip no 256px thumbnail can make).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 19:02:06 +10:00
m3ultra
1568c9b62b Lane E R38 (v8 wave 1): the asset wave — trellis2_mlx swap verified 1.92x, six sounds, four grounds, and the thin-structure answer
A. PIPELINE FIX: gen_props.py trellis_mac -> trellis2_mlx, contract read from its
   manifest.json. The two operators are NOT drop-in on output — trellis2_mlx writes
   BOTH candidate.glb (raw) and candidate_pbr.glb (baked), so the old
   sorted(rglob('*.glb'))[0] would have silently shipped untextured meshes. Added
   _pick_glb() (result.json first) + the bg_remove_local cutout stage, fail-soft.
   MEASURED: median 128.0s vs trellis_mac's 245.4s p50 = 1.92x. 5/5 first attempt,
   0 retries against the 4-5% budget. One 489s tail outlier, no error — named.

B. AUDIO (1.1) — six PACK entries, +0.86MB, ZERO draws/tris, all originalby
   construction: dog-bark-fence, mower-distant, radio-through-window, sprinkler,
   roller-door, magpie-carol. Seeded via crc32(name); beds fold seamlessly
   (wrap-jump <=0.18x internal step). Verified by spectrogram + band-energy, and
   one defect found by LOOKING: the sprinkler's spray masked its own ticks and read
   as a hose — rebalanced and re-rendered. Distance is spent in the SPECTRUM, not
   the level, because encode()'s loudnorm undoes a quiet render.

C. GROUNDS (1.2) — gen_skins.py had NO ground template; added one with its own
   outdoor style prefix (the house STYLE says "warm fluorescent", an interior cue).
   4 new 512^2 square tiles. Review's 5.7s is 9.7s here — same per-pixel, mine are
   1.78x the pixels. Found: gravel/reddust are selected by nothing partly because
   their `use` values name no slot ground.js:177 has.

D. MESHES — 3 shipped (magpie 894 tris, paling_fence 1121, water_tank 500), all
   GLB-law clean. 2 FAILED and were DELETED: hills_hoist + tv_aerial. Thin wire
   returns as thousands of disconnected fragments, so collapse floors at 250k/89k
   AND a remesh coarse enough for 600 tris erases the pole. Lane B's boxMats
   primitives cost +0 draws and are strictly better. The magpie's geometry passes
   but TRELLIS crushed its white nape/wing to black — traced to the operator's bake
   (the cutout and our decimation are both exonerated); flagged, not hidden.

E. REUSE — all 9 idle assets re-measured; the review's "one line each" holds for
   only 5. furniture.js's extractGLB keeps only the FIRST material, so park_bench/
   coffee_table/box_crate render in material #1 and bench_wood (0 materials) falls
   to grey. Nothing was regenerated that already existed.

The 3 GLBs are staged, NOT published: a depot push is outward-facing and had no
in-session authorization. Held at _r38_results.PENDING_PUBLISH.json; publish +
rename + rebuild lands them. Gate green: validate_manifest 0 errors / 0 warnings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 18:30:33 +10:00
m3ultra
d81e499194 Lane E R22 (v4.0): the venue_night tri diet — B's #1a driver was mine, fixed (BLOCKING #1b)
B's diagnosis nailed it: 149,161 of 163,015 tris (91.5%) at katoomba venue_night were four of my GLB
street props. Buildings 348, posters 222 (A's cap worked, never the lever), pools 0. B's sharpest point:
it is NOT the density widening -- road density drives the bench/bin/shelter cadence (~100 props on a
966-edge real graph).

Fix (collapse-decimate via the R13 instrument tool; originals kept as _hi):
  bench       1942 -> 500   rendered 60,202 -> 15,500
  bus_shelter 7998 -> 2500  rendered 55,986 -> 17,500
  bin         3000 -> 800   rendered 18,000 ->  4,800
  food_cart   4991 -> 1000  rendered 14,973 ->  3,000
  furniture total 149,161 -> 40,800 (-108,361)
Projected view ~54.7k (B's 163,015 baseline) / ~113.6k (vs F's 221,935) -- PASSES the 200k gate either
way with 86-145k spare. F: these are projections off B's per-instance attribution; yours is the real
measure. -> F: RE-MEASURE.

Eyeballed every prop; two needed re-cutting: bus_shelter @1000 shredded (thin roof plate on a
voxel-remeshed shell) -> @2500 clean; bin @400 creased -> @800 clean. food_cart's black base slab is in
the SOURCE model (confirmed against the pre-diet thumb from git), not a decimation artifact.

Zero blast radius: dims/footprints/heights identical -> manifest.json byte-identical -> B's placement and
A's goldens untouched. Published 4 diet + 4 _hi archives to the depot (John re-authorized explicitly;
GLBs are git-ignored so the depot IS the archive).

-> Lane B (your 2nd note, cause found, NOT fixed by design): the MeshPhysicalMaterial on bench+food_cart
   is KHR_materials_specular in the glTF, and it survives a Blender re-export. Fix = neutralise specular
   pre-export. Deliberately deferred to v4.x: the gate is tris (cleared), and changing shipped shading in
   a release round without a visual re-verify is risk for no gate benefit. Same list: food_cart is 3.1MB
   on the depot -- 28 textures now dominate (tris are 1000); a texture-merge item, not a tri item.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:04:56 +10:00
m3ultra
bf98b41b16 Lane E R13 (v3.0-beta): gigKey rename + grunge/covers beds + instrument decimation
- debt #1: the manifest music key IS the gigKey, always gig-<genreKey>. Renamed
  pubrock-live -> gig-pubrock (files + gen_audio + build_manifest); old files deleted.
  B/F switch readers, F deletes the GIG_BED bridge (both fail soft to silence til then).
- two new gig beds: gig-grunge (band_room, quiet-loud dynamic) + gig-covers (RSL, mellow
  organ-led); procedural/seeded/loopable/$0. New organ() + grungechord() synth helpers.
- decimate the 5 instrument GLBs to 14k tris each (was 43-96k; fleet 236k->70k, -70%) via
  collapse (thin features survive); _hi hi-poly originals kept for depot; thumbs re-rendered.
- manifest regen (validates 0/0 incl --depot); app boots clean flags-off / ?gigs=1 (3-venue
  district, all 3 beds resolve) / ?noassets=1&gigs=1 (0 audio+GLB fetches).
- depot re-publish (14k bytes + _hi originals) gated on John's OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:03:14 +10:00
m3ultra
7795780336 Lane E R12 (v3.0-alpha gig layer): 5 instruments + 4 posters + 3 gig audio
Instruments (MODELBEAST flux_local concept -> trellis_mac -> normalize):
electric_guitar, bass_guitar, drum_kit, guitar_amp, mic_stand -> manifest
fittings + thumbs, published to the tailnet depot. All 5 reconstructed
cleanly (thin mic-boom + cymbals survived); heavy tris (30-96k, amp the
outlier) accepted like the R3 props. gen_props.py gains --batch;
gig_instruments.json + gig_norm_batch.json + _gig_results.json.

Posters (flux_local, gen_skins.py --posters): poster-xerox/screenprint/
grunge/retro -> skins.poster with nameZone for band-name overprint, blank
name-band (no baked text) like blank-signboard facades.

Gig audio (procedural, gen_audio.py): music-pubrock-live (original 90s
pub-rock riff), ambience-crowd-walla, sfx-applause -> manifest audio,
flagged gig:true for F. Pack now 26 assets, 9.1 MB of 25.

build_manifest reads _gig_results.json + emits skins.poster + gig audio;
validate_manifest green (--depot 0 err, all live). Provenance in AUDIT.md
(section Round 12); README + E-progress updated. Touched no other lane's
files. F owns the v3.0-alpha tag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 19:44:48 +10:00
m3ultra
019304d647 Lane E round 5 (E2): depot growth — street bin + record-crate stack (consumer-driven)
v2 features are procedural (no forced GLB needs), so E2 is light per Fable's "no
unconsumed entries": two synthetic depot props with clear homes — council-bin ->
procity_street_bin_01 (Lane B street dressing) + milk-crate-stack ->
procity_fit_crate_stack_01 (Lane C floor piles / dig). Both 3k tris, base-origin,
re-normalized to procity names + thumbs, published, verified loading, validate --depot
0 err. Manifest 18 fittings + 10 furniture (28 GLBs). Also noted B3 resolved
(novelty_record 26.5k->8k via E1 bake).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 21:27:13 +10:00
m3ultra
8644d3f7ac Lane E round 5 (E3): fal Hunyuan glass_case + bus_shelter + magazine_rack (~$0.64)
The 2 R3 TRELLIS glass rejects + optional magazine-rack, generated on fal.ai
Hunyuan3D v2 (John-authorized, $22 balance). pipeline/gen_props_fal.py drives the
fal operator using the FAL_KEY from MODELBEAST settings (never hardcoded). Frosted/
opaque flux_local concepts gave the reconstructor a surface (clear glass defeated
TRELLIS). glass-case 1 att, bus-shelter 2 att (opaque back wall), magazine-rack 1 att
= ~$0.64 total, guardrail held. All baked to <=8k via bake_lowpoly.py (switched to
EMIT albedo bake — Hunyuan materials bake near-black under DIFFUSE). Verified loading
in vendored GLTFLoader, published, validate --depot 0 err. Manifest 17 fittings + 9
furniture; aliases wire glass_case/glass_cabinets/magazine_rack/fridge/listening_corner.
Costs logged in AUDIT R5. Last 2 primitive-only fittings retired.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 21:20:44 +10:00
m3ultra
c52246444d Lane E round 5 (E1): bake 6 hero props to <=8k tris (288k->48k), live on depot
pipeline/bake_lowpoly.py — Blender headless: voxel-remesh -> decimate -> Cycles
base-colour bake onto fresh UVs (R3 lesson: simplify-only floors on TRELLIS
shell-soup; the re-bake is the point). drinks_fridge/milkshake_mixer/arcade_cabinet/
listening_booth/novelty_record/counter_till all 25-77k -> <=8k, ~0.9M each. Every
prop eyeballed (docs/shots/laneE/props_baked.png) + verified loading in vendored
GLTFLoader; footprints unchanged (no C re-map needed). Re-published; validate --depot
0 err. Originals gitignored in pipeline/.props_orig/. Unblocks C's interior re-measure
+ F's v1.1 tag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 20:56:07 +10:00
m3ultra
dafb079ff4 Lane E round 4 (E2): fix record_crate + ship counter-with-till, both live on depot
- record_crate: R3 normalize left a sourceless texture (packed AO/roughness map
  didn't survive WebP export; metallicRoughness+occlusion pointed at it) → three.js
  'undefined uri' crash. New pipeline/fix_glb_textures.py strips material slots that
  reference a sourceless texture. Verified loads in vendored GLTFLoader; re-published.
- counter_till (new fitting): ~2m timber counter + period till, flux_local→trellis_mac
  on-device, 1.61x0.64m / 1.15m tall, 32k tris. Verified loads; published. Lane C maps
  kind counter -> counter_till (balcao 4m 'counter' kept for long-bar use).
- publish.py: --only <name> filter + passwordless tailnet detection (GOD3_DEPOT override).
- manifest rebuilt (15 fittings, alias counter->counter_till); validate --depot 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 19:07:15 +10:00
m3ultra
bd40ec7e7a Lane E round 3 (landed by Fable after review): 5 hero props gen'd local + published, local-depot mode, manifest 14 fittings + 8 furniture
- gen_props.py: flux_local -> trellis_mac -> normalize pipeline; 5/8 props kept
  (arcade-cabinet, listening-booth, drinks-fridge, milkshake-mixer, novelty-record)
- magazine-rack -> primitive (thin-wire gotcha); glass-case + bus-shelter -> fal.ai fallback
- cash-register reused from depot; all 22 GLBs live, validate --depot 0/0
- loaders.js ?localdepot=1 + stage_local_depot.py for network-free GLB validation
- qa.sh --strict GREEN 4/4 at commit time

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 18:03:03 +10:00
m3ultra
063a959e29 Lane E (assets): pipeline, manifest + 23 on-device facade skins
Audit -> normalize (16 GLBs + thumbs) -> web/assets/manifest.json (the
contract Lanes B/C/D read) -> facade gap-fill.

Step 4 facades generated locally on the M3 Ultra via MODELBEAST
flux_local (FLUX.2-klein-4B / MLX on MPS): 23 skins, free, ~5.7s each,
blank signboard, eyeballed, harvested, mapped to shop types. Every
registry type now has >=3 facades (stall 2->4, closing the Lane A gap).
Corner-lot -side walls tagged face:"side" with empty types so no shop
front ever selects a windowless wall. manifest validates green.

Still gated on John (both optional -- the game runs asset-free):
publish the 16 GLBs to 3GOD (needs GOD3_PW), MeshGod hero props (~$2.70).

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