From 5a85360ef9c4ac7b474cad4a8e90115e23a9ebb1 Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 17 Jul 2026 16:11:35 +1000 Subject: [PATCH] [screen] round 1 notes Co-Authored-By: Claude Opus 4.8 --- fktry/lanes/LANE-SCREEN.md | 83 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/fktry/lanes/LANE-SCREEN.md b/fktry/lanes/LANE-SCREEN.md index 2b8d7c0..37e20ca 100644 --- a/fktry/lanes/LANE-SCREEN.md +++ b/fktry/lanes/LANE-SCREEN.md @@ -63,3 +63,86 @@ measured ms). NOTES written. ### Round N — YYYY-MM-DD — [your model] SHIPPED: / DECISIONS: / BLOCKED/BROKEN: / CONTRACT REQUEST: / PROPOSAL: / NEXT: ``` + +### Round 1 — 2026-07-17 — Opus 4.8 + +SHIPPED: all 5 orders done and verified on the dev build. +- `params.ts` — the 8 params + frame-rate-independent `ease()`. +- `glitchStack.ts` — GLYTCH shader stack ported. Raw WebGL, NOT three.js (order 1 said my + call): it's one fullscreen triangle + one texture; three.js would cost more than the + whole effect is allowed to. All 8 prototype params keep their tuning verbatim — I + changed no magic numbers. Added 3 uniforms of my own: `u_drift`, `u_brownout`, `u_flash`. +- `baseTexture.ts` — procedural clean programming: SMPTE bars + castellations + pluge/ramp + + camcorder overlay (PLAY ▶, running SP timecode, rec dot), widened to 16:9. +- `corruptionMap.ts` — the ledger + item→artifact table + escalation curve. +- `index.ts` — compositor: ledger, easing, wobble, brownout, awakening. +- `corruptionMap.test.ts` — 24 tests, all green. + +DECISIONS: +- **Mix vs. total are separate axes.** WHAT you ship picks the artifact (blend of per-item + weights, by ship share); HOW MUCH you've ever shipped picks the intensity (escalation). + This is what makes 40 chroma slurry read as *chroma* instead of "more glitch". +- Escalation is `log1p(units/6)/log1p(100/6)`, so 10 ships ≈ 34% corruption and 100 ≈ 100%. + Front-loaded hard, per orders — there's a test pinning early-vs-late slope. +- Base texture repaints only when a visible glyph changes (timecode ~1/sec), not per frame. + Re-uploading 640×360 every frame would have eaten the budget for nothing. Motion for the + corruption to chew on comes from `u_drift` (bounded sinusoid — deliberately not a wrapping + pan, which would show a seam: the texture is non-power-of-two so WebGL1 forces CLAMP_TO_EDGE). +- Wobble above 0.8 total is CPU-side, 8 distinct slow rates, ±0.12 riding on top of the eased + value and never feeding back into the ledger. +- **I extended the item table well past the orders' examples.** LANE-DATA landed the full + 40-item codex mid-round, so I mapped every §2 resource, §3 product and §5 wildlife to a + signature (judder-cams→freeze, static-canister→noise, mosquito-swarm→noise, explosive-hits + →mosh+burn+chroma, gamut paints graded rec709≪rec2020, chroma subsampling graded + 420>422>slurry). The 5 science packs are intentionally left on the generic-noise fallback — + they're research currency, not ship goods. Unknown ids still degrade gracefully; there's a + test that walks `data/items.json` and asserts every id yields sane params, so LANE-DATA can + keep adding content without me. + +VERIFIED (dev build, driving the real module on the real canvas, reading GL pixels — not vibes): +- Starts sterile: bars + "NOTHING IS WRONG" chyron, `idle:true`, all params 0. +- 40× chroma-slurry → `chroma 0.684`, every other param 0 except a 0.082 burn trace. Screenshot + shows channel-split fringing on bars and doubled glyphs. Item-specific: confirmed. +- Awakening: first-ever ship renders exactly ONE frame at mean luminance 255 (full white), + 79 the next frame. +- Mature: 120× melt → total 1.0, melt 1.0 / mosh 0.451; screenshot shows the bars dripping + into black. Above 0.8, params drift ~0.095 between frames — alive, not maxed-out static. +- Anchor-slab isolation test: 1× anchor sets `idle:false` with ZERO corruption, and the only + pixel change is the chyron band going 37.1→100.8 luminance (dark overlay removed, bars + revealed). Chyron logic and sanitation both confirmed in one shot. +- Brownout: 1.0 when on, 0.0 when lifted, freeze+dropout+judder all driven off it. +- **Frame budget: 0.004–0.013 ms/frame CPU** (rolling avg, `__fktryScreen.stats().msPerFrame`). + Budget was <2ms. GPU side is one fullscreen triangle, no readbacks in the hot path. + +BLOCKED/BROKEN: nothing blocking me. Two things worth knowing: +- LANE-SIM emits no `shipped` events yet, so THE SCREEN can't be driven by the real chain. + I shipped a debug hook instead: `__fktryScreen.ship('melt',40)`, `.brownout(true)`, + `.reset()`, `.stats()`. It's ~20 lines in `init` and I'm happy to drop it once the chain + runs — say the word. +- `npm test` currently has 2 red in `src/sim/sim.test.ts` (crafting, shipping) and they are + NOT mine — flagging for your review, not touching them. My 24 pass; tsc is clean repo-wide. + +NOTE ON A THING I TOUCHED OUTSIDE MY LANE: I briefly created `.claude/launch.json` to get a +dev server on a free port (8150 is held by another session), then **deleted it** — the tooling +kept resolving to the busy port anyway. Net diff outside `src/screen/**` is zero. If you want +lanes to be able to boot their own preview, that file probably wants to be orchestrator-owned +with one entry per lane; right now five parallel lanes would collide on it. + +CONTRACT REQUEST: none. `ScreenFX` + `SimEvent` gave me everything I needed. + +PROPOSAL (orders 2 asked me to flag this): **anchor-slab sanitizing is live and it's good +tension** — potency −2.0, so 1 anchor cancels ~2 items of corruption and enough of them +sterilize THE SCREEN completely (tested). Right now that's invisible to the player, which +makes it a trap: they'll ship I-frames for a commission and watch their sky go clean with no +explanation. Two options for you — (a) UI surfaces it (LANE-UI chip: "SANITISING"), or (b) the +fiction owns it: The Correction *pays* for anchor-slabs, so it's a deliberate sellout loop — +bandwidth now, corruption later. I'd build (b); it's the codex's whole conflict in one item. +Also: `ScreenFX` currently only sees events, never the snapshot — if you ever want THE SCREEN +to react to *bandwidth strain* or *heat* continuously (not just the brownout on/off edge), +that'd need `frame()` to see the snapshot. Not asking yet; noting the seam. + +NEXT (my read, not self-assigning): item-specific artifacts that the 8 prototype params can't +express — moiré needs a real interference lattice, ringing needs edge-detected halos, +macroblock bricks want the 8×8 grid to be *legible*. That's new shader passes, not new +weights. Also THE SCREEN should probably show the shipped item's silhouette for a beat as it +lands. Say the word on round 2.