# Spec: effects lab — shared dust and liquid at every zoom ``` Type: spec Status: IN PROGRESS Status note: decided 2026-07-10. The first implementation establishes the separate lab binary, shared renderer boundary, deterministic presets, and close / medium / far visual levels. A second slice replaces close high-rate Thought's rejected hose/pearl geometry with a CPU implicit surface, animated strain-window frames, and internal-flow marbling. The next silhouette pass replaces that field's single-lane bulges and drilled window with intertwined sheet-forming paths whose separation creates the opening. Main-game binding follows the live machine-work and thought-fluid readouts; the lab does not invent game state. Stage: B1 — The Basement Work order: effects-lab Work priority: 26 Work class: frontend Blocked by: none Exclusive keys: - crates/misaligned-assets/ - wiki/art/effects-lab.md Design: - wiki/art/visual-identity.md#visual-identity-clinical-gore - wiki/interface/thought-fluid.md#spec-the-thought-fluid-slugs-meniscus-and-the-filament-snap - wiki/mechanics/machine-work.md#spec-machine-work-delegation-visible-tokens-and-the-byproduct-network Depends on: - wiki/interface/flat-materials.md#spec-flat-materials-the-world-without-textures - wiki/engineering/crate-workspace.md#spec-crate-workspace-core-terminal-bevy-assets - wiki/art/asset-tester.md#procedural-asset-tester ``` ## Dependency notes The visual-identity law owns the material split: Thought is wet ivory mercury; Exposure is dry crimson contamination and never borrows blood's smooth pool. thought-fluid.md owns the exact slug, pool, vessel, and filament grammar. machine-work.md owns the quantities and carrier rules. This page owns only the shared effects implementation, its standalone laboratory, and how that implementation becomes cheaper with distance. ## Why a separate lab Dust and liquid are camera-sensitive effects. Their quality comes from motion, lighting, scale, and the transition between representations; iterating them by booting a full run makes every visual correction slow and encourages a pretty prototype that never becomes the game renderer. `misaligned-effects` is a second binary in the `misaligned-assets` package. It boots a small clinical stage containing only Exposure dust and Thought liquid. The effect systems themselves live in the package library and are consumed by both the lab and `misaligned-bevy`. **Separate binary, shared implementation:** the lab may synthesize inputs for inspection, but it may not grow a private renderer that must later be rewritten. ## One effect, three visual levels The renderer chooses a visual level from camera distance. The lab can force a level so transitions can be judged directly. Thresholds and population counts are `[TUNE]`; the semantic compression is fixed. | Level | Thought | Exposure | | --- | --- | --- | | **Close** | Specular slugs, pool surface, meniscus and filament gestures; motion may use rich local easing. | Fine angular motes, turbulent drift, settling and local trails. | | **Medium** | Fewer merged slugs/rivulet segments and a simplified pool silhouette. | Reduced motes over a stable drift footprint. | | **Far** | A sparse ivory route pulse plus aggregate source/sink mass. | A dark crimson stain/haze whose area and density carry amount. | Crossing a threshold must not pop an amount in or out. Representations cross-fade or exchange equivalent silhouettes over a short presentation-only window `[TUNE]`. Far zoom is deliberately not a tiny close simulation: it spends detail on the decision the player can make at that scale. ## Truth boundary The lab uses authored demo values. The game supplies real readouts: - Thought route, direction, amount, and rate come from `work_in_flight`, queue, and sink readouts named by thought-fluid.md. - Exposure amount, emission, deposited residue, and carrier trails come from machine-work / people-token state as those readouts land. - Local particle positions, turbulence phase, surface wobble, and cross-fade state are presentation. They may be discarded and reconstructed. No visual level accumulates gameplay Thought or Exposure. Zooming cannot change a route, consume a quantity, settle gameplay residue, or alter detection. A paused frame still communicates amount through pool/stain geometry even when rate animation stops. ## The effects laboratory The binary provides one orbitable, close-lit stage and deterministic presets: - **liquid** — source pool, traveling slugs/rivulet, receiving mass; - **dust** — active plume above a settled downwind drift; - **both** — proves wet ivory and dry crimson remain distinct in one frame; - **stress** — repeats the shared effect across twelve roots at high amount; - forced **close / medium / far** levels for transition and cost inspection. Interactive controls select the preset and level, pause time, change effect amount/rate, orbit, and zoom. A shot harness fixes the seed and timestep, writes a PNG, and exits. This is evidence infrastructure, not a second game. ### Run and controls ```bash cargo run -p misaligned-assets --bin misaligned-effects MISALIGNED_SHOT=both_close \ MISALIGNED_SHOT_PATH=/tmp/effects.png \ cargo run -p misaligned-assets --bin misaligned-effects ``` | Input | Action | | --- | --- | | `1` / `2` / `3` / `4` | Liquid / dust / both / stress | | `Q` / `W` / `E` | Force close / medium / far level | | `A` | Return to automatic camera-distance level | | `Space` | Pause/unpause presentation time | | Up/down | Raise/lower both visible amounts | | Left/right | Lower/raise both visible rates | | Drag / scroll | Orbit / zoom | ## Quality and performance posture Close quality is allowed to be ambitious because only nearby effects receive it. Medium and far levels carry a hard population reduction. The lab includes a stress preset so frame cost is measured before the implementation is wired through a whole building. Exact particle counts, distance thresholds, shader technique, and frame budgets remain `[TUNE]` against representative hardware; the required result is stable cost as the visible machine count grows. ## Acceptance criteria 1. `cargo run -p misaligned-assets --bin misaligned-effects` opens the effects lab without booting `Sim` or loading a save. 2. The liquid/dust systems are exported by `misaligned-assets`; the lab does not own a private copy of their rendering code. 3. Liquid and dust can be viewed separately and together, with fixed-seed close, medium, and far captures. 4. Camera distance selects all three levels automatically; a lab override can force each level, and transitions preserve the aggregate amount read. 5. Close Thought reads wet and specular against matte chalk. Close Exposure reads dry, angular, settling, and substantially darker than signal light. 6. Pausing stops rate animation without erasing the pool or drift amount. 7. The shot harness uses a fixed timestep and leaves a deterministic PNG at the requested path before exiting. 8. The main Bevy frontend consumes the same exported effect systems and feeds them only named sim readouts. Until this criterion lands, status remains `IN PROGRESS`. ## Implementation slice — 2026-07-10 Criteria 1–7 are held by the first lab slice: the exported `MaterialEffectsPlugin`, four interactive presets (including twelve-root stress), automatic and forced LOD, deterministic scatter/time, and the PNG harness. Screenshot review rejected the first pearl-train close prototype and replaced high-rate Thought first with an overlapping rivulet, then with a close-only implicit surface. The current field intertwines two continuous paths beneath flattened pressure lobes; their animated separation creates the window without a subtractive bore. Eight deterministic surface frames make the rate-derived strain travel, open, and seal; a custom PBR extension advects marbled ivory, silver, and gunmetal bands from the same phase. Amount, rate, route, and direction remain the only authored inputs. Medium and far retain the cheaper rivulet and aggregate-route representations. The implicit frames are generated once per distinct input set, shared across matching roots, and swapped during animation. They are disposable presentation assets, not accumulated fluid state. This is deliberately an art-directed field rather than SPH/CFD: it can hit the selected silhouette and surface-tension grammar while obeying the one-truth boundary. Criterion 8 remains: `misaligned-bevy` has a concurrent Thought-flow renderer, so binding the shared plugin to its named sim readouts must be a deliberate reconciliation rather than an overwrite. The implemented silhouette refinement keeps the same extraction/cache boundary but changes the close field itself: two asymmetrical returning paths merge into a flattened sheet, separate into a traveling slit/window, and reunite behind a dominant pressure lobe. Thin capsule fields guarantee each path remains continuous through the split; anisotropic lobes, not those hidden spines, own the broad visible silhouette. Geometry and marbling use the same angular phase so visible internal flow predicts deformation. Exact path offsets, anisotropy, and phase curves remain `[TUNE]` in deterministic lab captures. ## Decided, open, and deferred **DECIDED:** separate `misaligned-effects` binary; shared package-library implementation; close / medium / far representations; materially simpler medium/far rendering; deterministic presets and capture. **OPEN AS TUNING:** exact thresholds, counts, shader/mesh technique, turbulence, viscosity, and cross-fade duration. These are judged in the lab rather than turned into design questions. **DEFERRED TO OWNING SPECS:** gameplay dust deposition/carrier mechanics and the final game readout wiring. The lab may visualize those behaviors but does not create their rules.