diff --git a/fktry/lanes/LANE-DATA.md b/fktry/lanes/LANE-DATA.md index 7ac2c4d..3b4fc32 100644 --- a/fktry/lanes/LANE-DATA.md +++ b/fktry/lanes/LANE-DATA.md @@ -25,52 +25,24 @@ REQUESTs. --- -## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text +## CURRENT ORDERS — Round 6 (goal: The Correction gets teeth, the map stops drifting) -Review verdict you're executing: the onboarding cliff. The fax IS the tutorial — -you write the ladder. Plus the radio's entire broadcast schedule and the ground -truth for the floor. +1. **FIREWALL machine** + catch recipe on SIM's trap pattern (they detect by recipe + shape); `parity-mite` canned item; mite spawn tuning if SIM makes it data-driven; + commissions that want canned mites ("ONE (1) UNIT OF THE CORRECTION, ALIVE. + INVOICE ATTACHED. DO NOT READ THE INVOICE."). +2. **Numbers-station drift fix** (SCREEN's round-5 finding): two decoys decode onto + real visible seams (08127 → reel-beds-deep, 27503 → broadcast-shelf-south); + your validator recomputes plants but not decoys — re-cut the decoys and extend + the validator so a decoy landing on ANY seam fails by name. +3. **Accent fills for the GLB'd 10**: the ten machines with real models now get + `accent` values chosen against their actual textures (RENDER's overlay reads it). +4. **THE STANDARD mite lines** (~8 new, coordinate with SCREEN), CANON-DELTA the + mite reading of §5. -### PART A — carried from round 5 -1. **Constants**: import from `src/sim/constants.ts`, retire hand-copies. -2. **Wildlife data**: MOSQUITO TRAP machine (§5: bug-zapper shaped like a - high-contrast edge target) + catch recipe (canned `mosquito-swarm`), pile/hatch - tuning if SIM makes it data-driven, `vaporwave-sunset` unblocked, FORWARD_CANON - pruned, fax celebrates in voice. -3. **Cooler numbers final** under the additive ruling; duty table in CANON-DELTA. - -### PART B — the ladder, the ground, the broadcast schedule (new) -4. **THE COMMISSION LADDER — the game's real tutorial.** Rewrite the opening queue - as an escalating teaching ladder, one mechanic per rung, all in voice: - - Rung 1: ~20 MDAT-ORE, raw ("Do not wash it. Do not ask why.") — teaches - extractor→belt→uplink. MUST be completable inside 3 minutes with 4 machine - types; prove it with a sim probe test like your tick-0 melt guard. - - Rung 2: LUMA BARS (teaches demuxer + byproduct pain — the slurry has to go - somewhere and the fax does not care). - - Rung 3: HF DUST (teaches the quantizer + that waste is product — DUST - ALLOWANCE fits here). - - Rung 4: one MELT, fresh (first-taste, reward bumped — it's a graduation now). - - Thereafter: your existing escalation. Ladder intent documented in CANON-DELTA. -5. **`data/seams.json` FINAL** (SIM consumes this round): seam regions per stratum - era with richness; the reference factory's ground coordinated with SIM; include - 2-3 `hidden: true` bonus seams — the numbers station reads their coordinates. -6. **`data/stations.json`**: the broadcast schedule — station ids, band, frequency, - name, format tag, flavor line, and the copy pools: THE STANDARD's propaganda - chyron lines (polite, clean, horrifying — this is The Correction with a - transmitter; 20+ lines so it doesn't loop fast), NUMBERS digit-group config - (incl. the hidden-seam pointers), DEAD AIR's one ghost line. Schema agreed with - SCREEN in NOTES. -7. **Relic canon**: CANON-DELTA the optical-fossil mechanics reading (§1 fossils - "sing when excavated" → the severed audio bus) + one mid-ladder fax margin that - *hints* without pointing ("someone has drawn a sine wave in the corner of this - fax. it is not our department."). -8. **Validator**: seams/stations schemas, ladder invariants (rung-1 buildability at - tick 0), relic never on a seam (cross-check vs SIM's placement rule). - -**Definition of done:** cold-start rung 1 provably completable fast; every station -has enough copy to broadcast for 10 minutes without repeating; seams validated -against both SIM's consumption and RENDER's rendering; CANON-DELTA tells the whole -story of the round. +**DoD:** firewall catches against SIM's real mechanic; no decoy decodes onto any +seam (validator-enforced); all 10 GLB machines accented; the fax celebrates its +first canned mite in voice. --- diff --git a/fktry/lanes/LANE-RENDER.md b/fktry/lanes/LANE-RENDER.md index 47eb127..c64ff66 100644 --- a/fktry/lanes/LANE-RENDER.md +++ b/fktry/lanes/LANE-RENDER.md @@ -25,45 +25,28 @@ you never simulate. If motion looks wrong, interpolate better or note it — don --- -## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text +## CURRENT ORDERS — Round 6 (goal: the GLB era looks as good as it is) -The review verdict driving this round: *the game about place has no place.* You own -fixing that. Everything from the previous round-5 orders is carried, plus the floor, -the juice, and one secret you must draw without signposting. +MODELBEAST delivered: 10 real GLBs now live in `public/assets/models/` (mosh-reactor, +quantizer, seam-extractor, muxer, archaeology-lab, software-decoder, decode-asic, +mosquito-trap, chroma-keyer, artifact-bottler). Hot-swap + normalization worked +first try. One problem, and it's yours: **at game zoom they read dark** — baked +textures carry no emissive, so the two-material rule dies on real assets. -### PART A — carried from round 5 -1. **Inspect mode**: highlight the inspected entity via `{mode:'inspect'}`; cooler - aura rectangle on inspect (the placed-and-selected case). -2. **Wildlife visuals**: piles = §2 glitter heaps growing with `size`; swarms = - pixel-gnat clouds clustering on `target` (harassed machines flicker); trap zap - read from wildlife-state deltas. -3. **Fixture hygiene**: commissionQueue/research/wildlife/relics in fabricated snapshots. +1. **GLB legibility pass, the round's centerpiece**: give hot-swapped GLBs the + accent treatment placeholders get — your existing accent derivation drives a + small emissive element (glow sprite / rim boost / brightest-texel emissive lift; + your call, note it) + an overall brightness floor so a dark chassis never reads + as a hole. Verify all 10 in showroom AND in the demo world at default zoom; + screenshot before/after in NOTES. +2. **Mite visuals** (SIM lands `'parity-mite'` wildlife): hospital-white beetles, + green checkmark eye (§5), unsettling gentleness; a caught mite in a firewall + reads as filed paperwork. The 'repaired' event gets a small, infuriatingly tidy + sparkle where your product used to be. +3. **Excavation VFX** on `relicFound` (carried from your round-5 NEXT). -### PART B — the floor, the juice, the secret (new) -4. **THE FLOOR.** Kill the void: seam regions from `data/seams.json` render as - subtle glinting mineral patches (the player should *discover* that extractors - want them — the glint is the tell); large-scale ground-tone variation (fbm - patches, barely-there) so the plane reads as terrain; era hinting toward the - world edges per §1 strata (sepia/phosphor whispers at the rim). Restraint rule: - the floor must never compete with belts/machines — it's a stage, not a set. -5. **THE RELIC SHIMMER.** `snapshot.relics` unfound → a faint animated static-patch - decal at its pos: visible to a player actually looking, invisible to one who - isn't. NO signpost, NO minimap ping, NO tutorial arrow — this is a Mario hidden - pipe; its discoverability budget is 'wandering + curiosity'. Found → the patch - becomes a small excavated monument (fossil on a plinth, §1: it *sings*). -6. **JUICE**: placement thunk (scale-pop + dust puff), demolition burst, shipment - flash at the uplink (read shippedTotal deltas from the snapshot). Cheap, - instanced, everywhere. -7. **THE BREAK ROOM.** A decorative arcade cabinet prop near the start zone, marquee - glowing 'GLYTCH', render-owned raycast: click → `window.open('./match.html')`. - The two games finally meet. Coordinate the cursor affordance with UI. -8. **CAMERA + CLICKS (review findings)**: default framing centers the start zone - clear of the build bar (my first machines spawned half-behind it and were - unclickable); investigate entity picking near UI chrome and report what you find. - -**Definition of done:** before/after screenshots of the floor; relic shimmer shown -at two zoom levels (proving subtle-but-findable); cabinet opens match.html; thunk -felt; perf rule holds with floor + 50 piles + 10 swarms. +**DoD:** all 10 GLBs legible at default zoom (before/after proof); mites read as +The Correction at a glance; perf rule holds. --- diff --git a/fktry/lanes/LANE-SCREEN.md b/fktry/lanes/LANE-SCREEN.md index 163b2ff..e533eae 100644 --- a/fktry/lanes/LANE-SCREEN.md +++ b/fktry/lanes/LANE-SCREEN.md @@ -27,59 +27,24 @@ seed stock — port, don't move). --- -## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text +## CURRENT ORDERS — Round 6 (goal: the sky notices the enemy) -You are now two organs: THE SCREEN (sky) and **THE SPEAKER** (`src/audio/**` is -yours — replace the orchestrator stub; contracts v6 `AudioFX` is wired in main.ts -with a first-gesture `unlock()`). House law: **every sound is synthesized with Web -Audio. No asset files, ever.** A game about broken media makes its own noise. +Your chyron now wraps (orchestrator fix — 29/30 STANDARD lines were clipping at ~51 +chars since round 5; two-line wrap verified live). -### PART A — carried from round 5 (THE SCREEN) -1. **Era base feed**: the clean programming ages with the highest ratified era - (sepia/gate-weave reel → phosphor/interlace broadcast → rainbow-on-black disc → - current SMPTE stream → blinding fortress). Corruption stays era-agnostic; the - SUBSTRATE ages. Sterile guarantee holds per era (test one). -2. **Jammed-rot**: jammed entities accelerate boredom decay; clean idle stays gentle. -3. **Wildlife shimmer**: swarms drive regional mosquito-noise via the growth-mask - template, seeded from the swarm pos. -4. **Title card**: WIMVEE FKTRY burn-in ~2s on boot (the game never says its own - name — fix that), then NOTHING IS WRONG. First-ever shipment's awakening upgrades - from 1 frame to a ~0.5s full-canvas moment. +1. **`repaired` events on the sky** (SIM lands them): each repair eases total + corruption by its item's contribution AND stamps a small, perfect, green-tick + placard — The Correction signs its work. Boredom and repairs must stay + distinguishable (rot vs theft). +2. **Mite shimmer**: reuse the growth-mask for a faint hospital-white sterile patch + creeping around heavy mite activity — the inverse of corruption, and it should + feel WORSE. +3. **THE STANDARD, new pool**: coordinate with DATA — the propaganda acknowledges + the mites now ("Units are assisting you." / "Inventory discrepancies are being + resolved in your favor."). Chyron-only, mumble untouched (standing constraint). -### PART B — THE SPEAKER (new, the big build) -5. **Layer 1 — diegetic minimum (always on, pre-discovery)**: placement thunk (low - sine + noise burst), fax dot-matrix chatter, brownout pop-crackle + power-down - whine (the codex's catastrophic underrun sound — finally), scram klaxon, - ratification sting (a clean consonant triad — The Correction resolves; you don't). - NOTHING else before discovery: the silence is the tease. -6. **Layer 2 — THE BAND (unlocks on relicFound)**: a tuner. Frequency sweep with - band-appropriate inter-station noise (AM = brown crackle, FM = white hiss, SW = - warble + heterodyne whistles near carriers); station lock via gaussian around - each station's freq. Stations from `data/stations.json` (DATA authors; schema - yours to agree in NOTES): - - **88.1 FKTRY FM** — generative music: seeded 16-step sequencer, square+triangle - voices, pentatonic minor ~92bpm, pattern mutates every 32 bars, flavored by the - current era (reel era gets wow/flutter + crackle). - - **AM 640 THE STANDARD** — Correction propaganda: ring-mod mumble cadence, and - the flagship trick: **THE SCREEN's chyron subtitles the radio** when tuned - (DATA writes the lines). The sky captions the audio. Do this one properly. - - **SW 6955 NUMBERS** — cold formant-synth digit groups; chyron shows the digits; - some groups encode coordinates of DATA's `hidden: true` bonus seams — the radio - is a treasure map for players with a pencil. - - **108.0 DEAD AIR** — room tone, breathing, one reversed-chime ghost per ~10min, - seeded. -7. **Layer 3 — world ambience (post-discovery)**: factory hum scaled by draw/gen, - tape-chunk per shipment stamp, heat adds a strained whine near scram. Subtle; - ducked under the radio. -8. **The control surface**: export a narrow `radio` API (setFrequency/setBand/ - volume/mute/getState/subscribe) — UI's tuner dock drives it (sanctioned import, - document it). Master chain: gain → soft limiter; zero per-frame allocations. - -**Definition of done:** spectral verification (AnalyserNode: station lock vs static -show distinct spectra; brownout pop is a real transient); pre-discovery silence -guarantee tested; subtitles verified on the chyron; era feed contact sheet; CPU -budget stated. This round, verification includes LISTENING — describe what it -sounds like in NOTES, in words. +**DoD:** a mite wave is visible on the sky as creeping cleanliness + tick stamps; +pixel-verified; budget holds. --- diff --git a/fktry/lanes/LANE-SIM.md b/fktry/lanes/LANE-SIM.md index 9d24acd..12036a9 100644 --- a/fktry/lanes/LANE-SIM.md +++ b/fktry/lanes/LANE-SIM.md @@ -21,45 +21,28 @@ playable through unit tests. You are the lane the other four trust with their li --- -## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text +## CURRENT ORDERS — Round 6 (goal: M3's enemy — THE CORRECTION walks) -This is the big one: everything from the previous round-5 orders PLUS the world's -first secret. Read it all before starting; the parts interlock. +Round 5 (MEGA) shipped complete: wildlife, seams, relic, research time — reviewed and +live. The tuner dead-dial and chyron clipping were fixed orchestrator-side; seams are +wired into GameData (your CONTRACT REQUEST, granted in v7). -### PART A — carried from round 5 (unchanged in spirit) -1. **`grantResearch` command** — idempotent, save/load safe. Tell me in NOTES when it - lands; main.ts's `__fktryDemo` swaps off testkit. -2. **Research time** — `RESEARCH_TICKS_PER_PACK` (export it); a tech is an - investment, not a purchase. Fractional vs stepped progress: your call, note it. -3. **Wildlife v1** (contracts v5 shapes): dust piles accumulate near running - hf-dust-emitting machines (seeded RNG finally rolls); size 1.0 hatches a MOSQUITO - SWARM that drifts to the nearest running machine and degrades its speed while - attached (`target`); cleared by DATA's trap machine (suggested shape: trap crafts - its empty-input catch recipe only while a swarm is in radius, producing the canned - `mosquito-swarm` item). Deterministic; save/load carries it; spawn/clear events. - Include the design-point test: a factory that sinks its dust never hatches. +1. **PARITY MITES v1** (codex §5: hospital-white beetle drones that quietly *repair* + your product). Contracts v8 widens `WildlifeState.kind` with `'parity-mite'` — + they ride the wildlife array. Behaviour: spawn from the world rim when + `shippedTotal` corruption crosses thresholds (escalate with progress); seek belts + carrying tier-2 glitch products; on reaching one, EAT the item and emit a new + `{kind:'repaired'; item; pos; tick}` event (v8) — the work is not destroyed, it is + *corrected*, which is worse. Deterministic, save/load carried, capped like swarms. +2. **The counter**: DATA authors a FIREWALL machine on your trap pattern (recipe-shape + detection, radius) — a mite in range is caught and canned (`parity-mite` item, + forward-canon in data). Coordinate via NOTES. +3. **Reference factory v6**: survives a mite wave without losing its melt regression + (a firewall on the uplink approach is the natural layout teach). -### PART B — the ground and the pipe (new) -4. **SEAMS BECOME REAL.** Consume `data/seams.json` (DATA authors this round — - coordinate the schema in NOTES early): extractors only extract while their - footprint overlaps a seam region; off-seam extractors idle with a new jam reason - `'no seam'` (edge-triggered like the others; UI will voice it). Reference factory - v5 must sit on seams — coordinate layout coordinates with DATA. -5. **THE RELIC (the hidden pipe).** One `optical-fossil` per world (contracts v6: - `RelicState`, `excavate`, `relicFound`): position derived from the seed — - deterministic, 18-28 tiles from origin in a quiet corner, never on a seam, never - under the reference factory. `excavate` within 1 tile of the unfound relic flips - `found`, emits `relicFound`, persists through save/load forever. `relics` always - present in the snapshot (found or not — RENDER draws the shimmer, UI must not be - able to cheat-detect it any other way). No bandwidth cost, no research gate: the - only lock is *finding it*. -6. **Reference factory v5**: research rig (bottler + archaeology lab off quantizer - surplus) so research runs in-demo; sits on seams per #4; one swarm hatches and is - trapped within the 20k window if DATA's trap lands. Zero-brownout regression stays. - -**Definition of done:** relic lifecycle tested (excavate too far = dropped; found -persists through save→load→20k ticks); off-seam extractor refuses with 'no seam'; -wildlife full lifecycle; research takes time; reference v5 green and on-seam. +**DoD:** mite lifecycle tested (spawn → seek → repair → event; firewall catch); +zero-brownout regression intact; mites never touch tier-0/1 cargo (they correct +CORRUPTION, not raw material — that's the fiction and the balance). --- diff --git a/fktry/lanes/LANE-UI.md b/fktry/lanes/LANE-UI.md index 8eccec8..df6269b 100644 --- a/fktry/lanes/LANE-UI.md +++ b/fktry/lanes/LANE-UI.md @@ -24,46 +24,23 @@ dispatch Commands via the bus and read state from `update(snap, events)`. --- -## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text +## CURRENT ORDERS — Round 6 (goal: the enemy has a face, the dial has teeth) -Review verdicts you're executing: first-click punishment without guidance, camera -controls taught nowhere, THE SCREEN's payoff too quiet, and one suspect tab click. -Plus the radio — the game's sound is a *discovery*, and you build its face. +Your tuner dock now drives the real engine (orchestrator adapter — the dead-dial +finding from the voice review is fixed and live-verified, station names and all). -### PART A — carried from round 5 -1. **Scrolling tab strip** (your design, approved). -2. **Publish inspect mode**: inspector open → `setSelection({mode:'inspect', - entity})`; clear on close; Esc order preserved (drop tool → close inspector). -3. **Wildlife surfacing**: infestation toasts in voice; MOSQUITO EXPOSURE line + - speed penalty in the inspector; one hatch-warning toast per pile, not a nag. -4. **Migrate research tests** to `grantResearch`; **verify RENDER's demolition tint - + inspect highlight with screenshots** (third round owed — close it). +1. **Mite surfacing**: toasts in voice ("A PARITY MITE IS EDITING YOUR MELT.", + "IT LEFT A RECEIPT."), `repaired` events in the ticker, firewall inspector shows + catches. The Correction is polite; the copy should make players furious. +2. **Tuner tick marks**: the adapter now passes `listStations()` through — draw + station ticks on the dial band so hunting has landmarks (keep the hunt: ticks + mark THAT something is there, not WHAT). +3. **Credits line** (from the voice-cloning plan, cheap now): an ABOUT/credits + entry reachable from the tech panel footer — repo, codex, and the standing + disclosure slot for future synthetic-voice credit. -### PART B — onboarding + the radio face (new) -5. **First-brownout mercy toast** (once per session): "NOTHING IS GENERATING. THE - COMMITTEE SUGGESTS: POWER." — fires on the first brownout event only. The alarm - currently teaches nothing; this is the one hint the opening needs. -6. **Camera hint** in the idle line ("MMB/WASD PAN · WHEEL ZOOM") and a **tab - hitbox check**: in review, a direct click on the POWER tab did nothing once - (keyboard paging worked; may be harness — reproduce with a real mouse, fix or - file it as harness with evidence). -7. **New jam voice**: `'no seam'` lands from SIM — give it the line it deserves - ("SEAM EXTRACTOR: THERE IS NOTHING DOWN THERE. MOVE."). -8. **THE SCREEN click-to-enlarge**: click toggles a centered ~2.5× overlay (CSS - transform + backdrop dim), Esc/click closes. The sky is the score; let people - look at it. -9. **THE TUNER DOCK (the radio's face).** Hidden until `relicFound`/`relics.found`. - Then: a dock slides in (bottom-right) — frequency dial (drag + arrow keys), band - AM/FM/SW, volume + mute, station readout in voice ("88.1 FKTRY FM — SIGNAL - LOCKED"). Controls talk to THE SPEAKER via its exported `radio` control (narrow - sanctioned import from `src/audio` — SCREEN documents the API; coordinate in - NOTES). Discovery ceremony: relicFound → "AUDIO BUS RESTORED. THE BITSTREAM HAS - A VOICE." toast + dock slide-in. Radio state persists per session only (the - fossil's `found` is the durable part, sim-side). - -**Definition of done:** cold-start first-brownout shows the mercy toast; tuner dock -appears only after excavation and drives the real audio engine; enlarge verified; -tint/highlight screenshots in NOTES; tab click adjudicated. +**DoD:** a mite raid is narratable from UI alone; ticks render from real station +data; credits reachable in-game. --- diff --git a/fktry/public/assets/models/archaeology-lab.glb b/fktry/public/assets/models/archaeology-lab.glb new file mode 100644 index 0000000..f171ebc Binary files /dev/null and b/fktry/public/assets/models/archaeology-lab.glb differ diff --git a/fktry/public/assets/models/artifact-bottler.glb b/fktry/public/assets/models/artifact-bottler.glb new file mode 100644 index 0000000..8dfef3a Binary files /dev/null and b/fktry/public/assets/models/artifact-bottler.glb differ diff --git a/fktry/public/assets/models/chroma-keyer.glb b/fktry/public/assets/models/chroma-keyer.glb new file mode 100644 index 0000000..8c6e272 Binary files /dev/null and b/fktry/public/assets/models/chroma-keyer.glb differ diff --git a/fktry/public/assets/models/decode-asic.glb b/fktry/public/assets/models/decode-asic.glb new file mode 100644 index 0000000..fa4c795 Binary files /dev/null and b/fktry/public/assets/models/decode-asic.glb differ diff --git a/fktry/public/assets/models/mosh-reactor.glb b/fktry/public/assets/models/mosh-reactor.glb new file mode 100644 index 0000000..f1b33cf Binary files /dev/null and b/fktry/public/assets/models/mosh-reactor.glb differ diff --git a/fktry/public/assets/models/mosquito-trap.glb b/fktry/public/assets/models/mosquito-trap.glb new file mode 100644 index 0000000..45dfedb Binary files /dev/null and b/fktry/public/assets/models/mosquito-trap.glb differ diff --git a/fktry/public/assets/models/muxer.glb b/fktry/public/assets/models/muxer.glb new file mode 100644 index 0000000..3cd1590 Binary files /dev/null and b/fktry/public/assets/models/muxer.glb differ diff --git a/fktry/public/assets/models/quantizer.glb b/fktry/public/assets/models/quantizer.glb new file mode 100644 index 0000000..61cf079 Binary files /dev/null and b/fktry/public/assets/models/quantizer.glb differ diff --git a/fktry/public/assets/models/seam-extractor.glb b/fktry/public/assets/models/seam-extractor.glb new file mode 100644 index 0000000..2878fca Binary files /dev/null and b/fktry/public/assets/models/seam-extractor.glb differ diff --git a/fktry/public/assets/models/software-decoder.glb b/fktry/public/assets/models/software-decoder.glb new file mode 100644 index 0000000..966a192 Binary files /dev/null and b/fktry/public/assets/models/software-decoder.glb differ diff --git a/fktry/src/contracts.ts b/fktry/src/contracts.ts index fa950c8..6e9fa82 100644 --- a/fktry/src/contracts.ts +++ b/fktry/src/contracts.ts @@ -160,7 +160,7 @@ export interface RelicState { export interface WildlifeState { id: number; - kind: 'dust-pile' | 'mosquito-swarm'; + kind: 'dust-pile' | 'mosquito-swarm' | 'parity-mite'; // v8: The Correction walks pos: Vec2; size: number; // pile: accumulation 0..1; swarm: severity 0..1 target?: number; // swarm: entity id it is currently degrading @@ -197,9 +197,10 @@ export type SimEvent = | { kind: 'commissionDone'; commission: string; tick: number } | { kind: 'scram'; entity: number; on: boolean; tick: number } // v2: heat shutdown edge | { kind: 'researched'; tech: string; tick: number } // v4: research complete - | { kind: 'wildlife'; on: 'spawned' | 'cleared'; wildlife: 'dust-pile' | 'mosquito-swarm'; + | { kind: 'wildlife'; on: 'spawned' | 'cleared'; wildlife: 'dust-pile' | 'mosquito-swarm' | 'parity-mite'; id: number; pos: Vec2; tick: number } // v5: hazard lifecycle - | { kind: 'relicFound'; relic: 'optical-fossil'; id: number; tick: number }; // v6 + | { kind: 'relicFound'; relic: 'optical-fossil'; id: number; tick: number } // v6 + | { kind: 'repaired'; item: string; pos: Vec2; tick: number }; // v8: a mite corrected your work // ---------------------------------------------------------------- module interfaces diff --git a/fktry/src/main.ts b/fktry/src/main.ts index b51ae67..920c95f 100644 --- a/fktry/src/main.ts +++ b/fktry/src/main.ts @@ -83,6 +83,12 @@ function createSpeakerAdapter() { cb(control.getState()); return () => subs.delete(cb); }, + /** v8: station tick marks for the dial — engine truth, MHz units, empty pre-gesture */ + listStations() { + return engine + ? engine.listStations().map((st) => ({ ...st, freqMHz: toMHz(st.band, st.freq) })) + : []; + }, }; function notifyLocal() { for (const cb of subs) cb({ ...local }); } diff --git a/fktry/src/ui/voice.ts b/fktry/src/ui/voice.ts index d3e1dbd..f3e5975 100644 --- a/fktry/src/ui/voice.ts +++ b/fktry/src/ui/voice.ts @@ -98,7 +98,7 @@ export function eventToast(ev: SimEvent, machineName: (id: number) => string): s * per pile — see the notices logic there); a swarm spawning is the bite already landing. */ export function wildlifeToast( - kind: 'dust-pile' | 'mosquito-swarm', + kind: 'dust-pile' | 'mosquito-swarm' | 'parity-mite', on: 'spawned' | 'cleared', ): string | null { if (kind === 'dust-pile') { @@ -106,6 +106,12 @@ export function wildlifeToast( ? 'HF DUST IS POOLING. SOMETHING WILL HATCH IN IT.' : null; // clearing a pile is housekeeping, not news } + if (kind === 'parity-mite') { + // v8 placeholder copy — LANE-UI owns the real lines in round 6 + return on === 'spawned' + ? 'A PARITY MITE HAS ARRIVED. IT IS HERE TO HELP.' + : 'MITE CONTAINED. FILE ITS RECEIPT.'; + } // mosquito-swarm return on === 'spawned' ? 'MOSQUITO SWARM. QUANTIZATION NOISE HAS LEGS NOW.'