[orchestrator] MEGA round 5: the paint and the pipe
Supersedes unexecuted round-5 orders. Folds in the live first-eyes review findings (silence, void floor, onboarding cliff, quiet payoffs) + John's hidden-radio idea. Contracts v6: AudioFX (THE SPEAKER - all Web Audio synthesis, no asset files), RelicState + excavate + relicFound (the optical-fossil hidden pipe: find it and the game grows a tuner - FKTRY FM, Correction propaganda subtitled by THE SCREEN's chyron, a shortwave numbers station reading hidden-seam coordinates, dead air). main.ts wires audio + first-gesture unlock; src/audio stub awaits LANE-SCREEN. Lane orders: SIM = wildlife + seams-become-real + the relic + research time; RENDER = the floor (seam glints, strata whispers), relic shimmer (no signposting), juice, break-room cabinet -> match.html; UI = mercy toast, tuner dock, SCREEN click-to-enlarge, camera hints; SCREEN = era feed + THE SPEAKER (3 audio layers, 4 stations, spectral verification); DATA = the commission-ladder tutorial, stations.json broadcast schedule, seams.json final. Ship gate: after review, redeploy partly.party/glytch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e3d1a724e9
commit
8dd4616580
@ -68,3 +68,16 @@ batches them between rounds. Until granted, work around locally inside your lane
|
||||
whose heatPerTick ≤ its coolPerTick can never overheat — the validator enforces it.
|
||||
- Research gating: ids appearing in any `TechDef.unlocks` are locked until researched;
|
||||
ids referenced by no tech are always available.
|
||||
|
||||
## v6 notes
|
||||
|
||||
- **THE SPEAKER**: `AudioFX` (src/audio/**, LANE-SCREEN) — all sound is Web Audio
|
||||
synthesis, no asset files. main.ts wires init/unlock/onEvents/frame. Pre-discovery
|
||||
only the diegetic minimum plays; the band unlocks on `relicFound`.
|
||||
- **Sanctioned narrow imports** (read-only, documented at the export site):
|
||||
`src/sim/constants.ts` (tuning truth) and `src/audio`'s `radio` control (UI's
|
||||
tuner dock). Everything else stays contract-mediated.
|
||||
- **Relics are secrets.** `snapshot.relics` is always present, but nothing may
|
||||
signpost an unfound relic: RENDER draws the subtle shimmer, UI shows nothing until
|
||||
`found`. Discoverability budget: wandering + curiosity. That's the design.
|
||||
- New jam reason string: `'no seam'` (extractor off-seam).
|
||||
|
||||
@ -102,3 +102,11 @@ diff each lane against its owned paths (ownership violations get reverted), veri
|
||||
claimed features actually work, reconcile cross-lane questions, update CONTRACTS if
|
||||
(and only if) two lanes need it, write next CURRENT ORDERS in each lane doc, commit
|
||||
`[orchestrator] round N orders`.
|
||||
|
||||
## ROUND 5 (MEGA) addendum
|
||||
|
||||
The original round-5 orders were superseded before execution by the MEGA round
|
||||
(same goals + the paint-and-pipe layer from the live first-eyes review: sound via
|
||||
the hidden optical-fossil radio, the commission-ladder tutorial, the floor, juice,
|
||||
click-to-enlarge SCREEN, the break-room cabinet). After this round's review passes:
|
||||
**redeploy to partly.party/glytch via ../deploy.sh** — that's the ship gate.
|
||||
|
||||
@ -25,41 +25,52 @@ REQUESTs.
|
||||
|
||||
---
|
||||
|
||||
## CURRENT ORDERS — Round 5 (goal: the world gets teeth and ground)
|
||||
## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text
|
||||
|
||||
Round 4 review: the gating audit — measuring 0-of-24 reachability, fixing it as two
|
||||
tested rules, deleting six fake nodes instead of repurposing them — is the round's
|
||||
headline and the reason the tree tells a story now. The cooler retune that survives
|
||||
both readings of an ambiguous contract sentence was defensive tuning of the highest
|
||||
order; the sentence is now clarified (ADDITIVE, capped at HEAT_COOL_MAX). Verdicts:
|
||||
constants.ts landed in SIM's final commit (your grep raced it — it exports 12,
|
||||
retire your hand-copies now). Your ungating of the mosh reactor + starter-plant
|
||||
arithmetic: RATIFIED, SIM's reference factory now pre-grants its techs in the demo.
|
||||
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. **Retire the hand-copied constants** — import from `src/sim/constants.ts`
|
||||
(read-only cross-lane import is sanctioned for constants).
|
||||
2. **Wildlife data** (SIM builds the mechanic this round — coordinate via NOTES):
|
||||
the MOSQUITO TRAP machine (§5 codex: bug-zapper shaped like a high-contrast edge
|
||||
target), its catch recipe producing the canned `mosquito-swarm` item, pile/hatch
|
||||
tuning numbers if SIM makes them data-driven, and the commissions that suddenly
|
||||
work: `vaporwave-sunset` finally unblocked — prune FORWARD_CANON accordingly and
|
||||
let the fax celebrate in voice.
|
||||
3. **Cooler numbers final** under the clarified additive rule — your 0.0018 was
|
||||
tuned to survive ambiguity; now tune it to be *right*, show the duty-cycle table
|
||||
in CANON-DELTA.
|
||||
4. **The seam map — start the ground game** (the content gap you own): author
|
||||
`data/seams.json` — seam regions per stratum era (shape your call: rects or
|
||||
points + richness), the codex §1 geology as actual coordinates. SIM consumes it
|
||||
round 6 (extractors will require seam tiles); this round it's data + validator
|
||||
coverage + a CANON-DELTA spec of intended mechanics, so SIM has something real to
|
||||
build against instead of a guess.
|
||||
5. **Fixture/validator upkeep**: v5 fields (wildlife), grantResearch in any test
|
||||
flows you own, FORWARD_CANON pruned.
|
||||
### 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.
|
||||
|
||||
**Definition of done:** trap + swarm economy closes (catchable → cannable →
|
||||
commissionable) against SIM's real mechanic; seams.json exists with validator
|
||||
coverage and a written consumption spec; constants imported from truth; CANON-DELTA
|
||||
carries the cooler table.
|
||||
### 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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -25,35 +25,45 @@ you never simulate. If motion looks wrong, interpolate better or note it — don
|
||||
|
||||
---
|
||||
|
||||
## CURRENT ORDERS — Round 5 (goal: a living, inspectable world)
|
||||
## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text
|
||||
|
||||
Round 4 review: ERA_TELL (signal vs surface) and the chebyshev-rectangle honesty are
|
||||
both canon reasoning now; the showroom axis-overflow lesson is quoted in my head
|
||||
weekly. Verdicts: CONTRACT REQUEST 1 GRANTED — `SelectionState` grew
|
||||
`{mode:'inspect'; entity}` in v5; UI publishes it when the inspector opens. The
|
||||
sentinel bridge is DEAD as promised: main.ts now sends `setGhost(null, tile, 0,
|
||||
'remove')` — you already ignore the def, so nothing changes for you, but confirm.
|
||||
Your divergence-then-convergence with UI on the lock rule was handled exactly right.
|
||||
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.
|
||||
|
||||
1. **Inspect mode**: on `{mode:'inspect'}`, highlight the inspected entity (outline
|
||||
or ground ring — your language) and, when it has `coolRadius`, draw the aura
|
||||
rectangle — order 3's "placed-and-selected" case, now reachable.
|
||||
2. **Wildlife visuals** (SIM lands `snapshot.wildlife` this round): DUST PILES as
|
||||
§2's glitter heaps — instanced, growing with `size`, subtle shimmer; MOSQUITO
|
||||
SWARMS as pixel-gnat particle clouds that visibly cluster on their `target`
|
||||
machine (which should read as *harassed* — flicker its accent); trap machines get
|
||||
a zap flash on the `wildlife cleared` event... which you don't receive — read
|
||||
state deltas instead, or tell me if you want Renderer to get events (that's a
|
||||
contract conversation I'm open to in v6, say so in NOTES if hover-state isn't
|
||||
enough).
|
||||
3. **Fixture hygiene**: `commissionQueue` + `research` into your fabricated
|
||||
snapshots (devscene, showroom) — v6 hardens both.
|
||||
4. **MODELBEAST intake stays armed**: no assets have landed yet; `?showroom` is the
|
||||
live manifest. First drops get a NOTES line each on how normalization treated them.
|
||||
### 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.
|
||||
|
||||
**Definition of done:** an infested factory is legible from across the map (piles
|
||||
grow, swarms harass, traps zap); inspect-highlight + aura verified with UI's flow;
|
||||
perf rule still holds with 50 piles + 10 swarms in the stress scene.
|
||||
### 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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -27,34 +27,59 @@ seed stock — port, don't move).
|
||||
|
||||
---
|
||||
|
||||
## CURRENT ORDERS — Round 5 (goal: the sky learns eras and insects)
|
||||
## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text
|
||||
|
||||
Round 4 review: the two-clock decision (card in seconds because it's a broadcast;
|
||||
scram wipe in frames because it's tape) is the most codex-literate engineering choice
|
||||
so far, and the capacity-trap catch protected the sterile guarantee twice over.
|
||||
Verdicts: your jammed-rot PROPOSAL is APPROVED (rot ≠ rest); your era-feed NEXT idea
|
||||
is this round's centerpiece — you called it, you build it.
|
||||
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.
|
||||
|
||||
1. **The base feed ages with the player** (your idea, ordered): drive the clean
|
||||
programming's palette/texture from the highest era with a ratified tech
|
||||
(`research.unlocked` × tech eras from GameData): reel = sepia + gate weave +
|
||||
sprocket judder, broadcast = phosphor + interlace flicker, disc = rainbow-on-black
|
||||
sheen, stream = the current SMPTE feed, fortress = blinding white (§8 skins).
|
||||
Corruption artifacts stay era-agnostic — it's the SUBSTRATE that ages. Sterile
|
||||
guarantee holds per era (test at least one).
|
||||
2. **Jammed-rot**: `jammed` entities accelerate boredom decay (the work is rotting);
|
||||
a clean idle keeps the gentle horizon. One-line read, as you said — plus a test
|
||||
distinguishing the two.
|
||||
3. **Wildlife on the sky** (SIM lands `snapshot.wildlife` + events): mosquito swarms
|
||||
drive a *regional* mosquito-noise shimmer via your growth-mask template (seeded
|
||||
from the swarm's pos — the sky itches where the factory itches). Piles need
|
||||
nothing unless you disagree.
|
||||
4. **Fixture hygiene**: done last round for commissionQueue/research — add
|
||||
`wildlife` where fixtures fabricate snapshots.
|
||||
### 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.
|
||||
|
||||
**Definition of done:** era progression visible on the feed (contact sheet per era),
|
||||
rot vs rest distinguishable under test, swarm shimmer regional and pinned by pixels,
|
||||
budget still <2ms.
|
||||
### 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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -21,40 +21,45 @@ playable through unit tests. You are the lane the other four trust with their li
|
||||
|
||||
---
|
||||
|
||||
## CURRENT ORDERS — Round 5 (goal: M2 closes — the Bitstream comes alive)
|
||||
## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text
|
||||
|
||||
Round 4 review: the realtech.test.ts tripwire caught DATA's circular tree and your
|
||||
premise-guard philosophy caught their fix — the system is working. Verdicts:
|
||||
**grantResearch PROPOSAL GRANTED** — it's in v5 as a real Command (sandbox is a
|
||||
feature, not a cheat); implement it, and it replaces the testkit import currently in
|
||||
main.ts's `__fktryDemo` (I wired testkit as the stopgap — swap is mine once you land).
|
||||
**Research time APPROVED** (your NEXT): labs take `RESEARCH_TICKS_PER_PACK` per pack
|
||||
(export it) so a tech is an investment, not a purchase. **Pack abandonment on target
|
||||
switch: KEPT** — "packs are the cost of indecision" is design, write it no further.
|
||||
Cooling cap reasoning accepted; the additive-stacking rule is now a contract comment
|
||||
(DATA tuned blind against the ambiguity — your sentence, my fault for not catching it).
|
||||
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.
|
||||
|
||||
1. **`grantResearch` command** — instant unlock list, idempotent, save/load safe.
|
||||
2. **Research time** — per-pack ticks; progress visible in `research.progress`
|
||||
between packs is your design call (fractional or stepped — note it).
|
||||
3. **Wildlife v1 — the round's centerpiece** (contracts v5: `snapshot.wildlife`,
|
||||
`WildlifeState`, the `wildlife` event): HF DUST PILES accumulate near machines
|
||||
whose recipes emit hf-dust while they run (rate/threshold your design; the seeded
|
||||
RNG finally rolls); a pile at size 1.0 hatches a MOSQUITO SWARM that drifts to the
|
||||
nearest running machine and degrades its speed while attached (`target`); swarms
|
||||
are cleared by a trap machine (DATA authors it — coordinate the mechanic: trap
|
||||
with an empty-input recipe that only crafts while a swarm is in radius, producing
|
||||
the canned `mosquito-swarm` item, is my suggested shape). Deterministic, save/load
|
||||
carries it all, events on spawn/clear. Tests including "a factory that vents dust
|
||||
into product instead of shipping it never hatches a swarm" — the design point.
|
||||
4. **Reference factory v5**: grow the research rig (bottler + archaeology lab fed by
|
||||
quantizer surplus) so research is playable in the demo, and the 20k run should now
|
||||
also hatch at least one swarm and trap it if DATA's trap lands — the demo becomes
|
||||
the whole M2 story. Regression stays green.
|
||||
### 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.
|
||||
|
||||
**Definition of done:** wildlife lifecycle proven under test (accumulate → hatch →
|
||||
degrade → trap → event trail), research takes time, grantResearch lands (tell me in
|
||||
NOTES so I swap main.ts off testkit), reference v5 researches a real tech in-demo.
|
||||
### 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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -24,33 +24,46 @@ dispatch Commands via the bus and read state from `update(snap, events)`.
|
||||
|
||||
---
|
||||
|
||||
## CURRENT ORDERS — Round 5 (goal: the pressure has a face)
|
||||
## CURRENT ORDERS — ROUND 5 (MEGA) — supersedes the earlier round-5 text
|
||||
|
||||
Round 4 review: the live.test.ts research loop — lock → refuse → lab → ratify →
|
||||
padlock falls → place succeeds — is the single best proof in the repo, and your
|
||||
"re-probe before writing NOTES" practice is now a MASTERPLAN process note for
|
||||
everyone. Verdicts: your save-schema coupling PROPOSAL is answered by v5's
|
||||
`grantResearch` Command (SIM implements) — migrate your tests to it and the blob
|
||||
coupling dies. Scrolling tab strip: APPROVED (you flagged the wrap). RENDER's tint
|
||||
verification is still owed — close it this round.
|
||||
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.
|
||||
|
||||
1. **Scrolling tab strip** — your design; keep every tab reachable by `[`/`]` and
|
||||
the strip legible at 29+ machines and REMOVE + RESEARCH.
|
||||
2. **Publish inspect mode**: when the inspector opens, `setSelection({mode:
|
||||
'inspect', entity})`; clear on close. RENDER highlights + draws cooler auras off
|
||||
it — coordinate the timing so Esc clears both cleanly.
|
||||
3. **Wildlife surfacing** (SIM lands it this round): infestation toasts in house
|
||||
voice ("QUANTIZER HOSTS A SWARM. OSHA HAS BEEN NOTIFIED. OSHA IS THE SWARM."),
|
||||
inspector shows a MOSQUITO EXPOSURE line on a targeted machine + the speed
|
||||
penalty; a pile nearing hatch (size > 0.8) earns one warning toast, not a nag.
|
||||
4. **Migrate research-granting tests** to the `grantResearch` command once SIM
|
||||
lands it (drop the save-blob mutation).
|
||||
5. **Verify RENDER's demolition tint + inspect highlight** with your own eyes and
|
||||
screenshot it in NOTES — third round this handshake has floated unverified.
|
||||
### 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).
|
||||
|
||||
**Definition of done:** tab strip scrolls; inspect mode round-trips with RENDER
|
||||
(screenshot); a swarm's lifecycle is narratable from UI alone (warning → infested →
|
||||
trapped); research tests no longer parse save blobs.
|
||||
### 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.
|
||||
|
||||
---
|
||||
|
||||
|
||||
12
fktry/src/audio/index.ts
Normal file
12
fktry/src/audio/index.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/** LANE-SCREEN territory (THE SPEAKER). Stub — replace per lanes/LANE-SCREEN.md.
|
||||
* All sound is Web Audio synthesis; no asset files, ever. */
|
||||
import type { AudioFX, GameData, SimEvent, SimSnapshot } from '../contracts';
|
||||
|
||||
export function createAudioFX(): AudioFX {
|
||||
return {
|
||||
init(_data: GameData) {},
|
||||
unlock() {},
|
||||
onEvents(_events: SimEvent[]) {},
|
||||
frame(_timeMs: number, _snap?: SimSnapshot) {},
|
||||
};
|
||||
}
|
||||
@ -132,6 +132,14 @@ export interface SimSnapshot {
|
||||
commissionProgress: Record<string, number>;
|
||||
research?: ResearchState; // v4: research progress (hardens in v6)
|
||||
wildlife?: ReadonlyArray<WildlifeState>; // v5: piles & swarms (M2's living hazards)
|
||||
relics?: ReadonlyArray<RelicState>; // v6: buried secrets (the hidden pipe)
|
||||
}
|
||||
|
||||
export interface RelicState {
|
||||
id: number;
|
||||
kind: 'optical-fossil'; // v6: the severed audio bus — one per world
|
||||
pos: Vec2;
|
||||
found: boolean; // excavated; persists through save/load
|
||||
}
|
||||
|
||||
export interface WildlifeState {
|
||||
@ -160,6 +168,7 @@ export type Command =
|
||||
| { kind: 'grantResearch'; tech: string[] } // v5: instant unlock — the
|
||||
// sandbox/demo verb, also a
|
||||
// legitimate creative mode
|
||||
| { kind: 'excavate'; pos: Vec2 } // v6: dig at a relic site
|
||||
| { kind: 'setPaused'; paused: boolean };
|
||||
|
||||
export type SimEvent =
|
||||
@ -173,7 +182,8 @@ export type SimEvent =
|
||||
| { 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';
|
||||
id: number; pos: Vec2; tick: number }; // v5: hazard lifecycle
|
||||
id: number; pos: Vec2; tick: number } // v5: hazard lifecycle
|
||||
| { kind: 'relicFound'; relic: 'optical-fossil'; id: number; tick: number }; // v6
|
||||
|
||||
// ---------------------------------------------------------------- module interfaces
|
||||
|
||||
@ -223,6 +233,18 @@ export interface UI {
|
||||
update(snap: SimSnapshot, events: SimEvent[]): void;
|
||||
}
|
||||
|
||||
/** v6: THE SPEAKER — everything audible. All sound is synthesized (Web Audio), no
|
||||
* asset files. Pre-discovery: minimal diegetic UI sounds only. After the optical
|
||||
* fossil is found (snapshot.relics / relicFound), the full band unlocks: tuner,
|
||||
* stations, world ambience. Owned by LANE-SCREEN (src/audio/**). */
|
||||
export interface AudioFX {
|
||||
init(data: GameData): void;
|
||||
/** call on first user gesture — browsers gate AudioContext on interaction */
|
||||
unlock(): void;
|
||||
onEvents(events: SimEvent[]): void;
|
||||
frame(timeMs: number, snap?: SimSnapshot): void;
|
||||
}
|
||||
|
||||
export interface ScreenFX {
|
||||
init(canvas: HTMLCanvasElement, data: GameData): void;
|
||||
onEvents(events: SimEvent[]): void; // shipped items feed the corruption
|
||||
|
||||
@ -7,6 +7,7 @@ import { createSim } from './sim';
|
||||
import { createRenderer } from './render';
|
||||
import { createUI } from './ui';
|
||||
import { createScreenFX } from './screen';
|
||||
import { createAudioFX } from './audio';
|
||||
|
||||
import items from '../data/items.json';
|
||||
import machines from '../data/machines.json';
|
||||
@ -20,6 +21,7 @@ const sim = createSim();
|
||||
const renderer = createRenderer();
|
||||
const ui = createUI();
|
||||
const screen = createScreenFX();
|
||||
const audio = createAudioFX();
|
||||
|
||||
// v4 bridge: _sel keeps the legacy {def,dir} shape (including the deprecated
|
||||
// '__remove' sentinel) so unmigrated lanes keep working; selection()/setSelection()
|
||||
@ -52,6 +54,9 @@ async function boot() {
|
||||
await renderer.init(document.getElementById('game')!, data);
|
||||
ui.init(document.getElementById('ui')!, data, bus);
|
||||
screen.init(document.getElementById('screen') as HTMLCanvasElement, data);
|
||||
audio.init(data);
|
||||
// browsers gate AudioContext on a user gesture — unlock on the first one
|
||||
addEventListener('pointerdown', () => audio.unlock(), { once: true });
|
||||
|
||||
// click-to-place / hover ghost glue
|
||||
const game = document.getElementById('game')!;
|
||||
@ -86,6 +91,8 @@ async function boot() {
|
||||
ui.update(snap, events);
|
||||
screen.onEvents(events);
|
||||
screen.frame(now, snap);
|
||||
audio.onEvents(events);
|
||||
audio.frame(now, snap);
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
requestAnimationFrame(loop);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user