From f9a51136a7584c55182d53d62720b429dc3f3017 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 10 Jul 2026 22:51:54 -0700 Subject: [PATCH] Make exposure settle as responsive dust. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep crimson residue dense and close to its source, then make active LIE answer immediately by scrubbing its own tile before pulling nearby contamination at a useful rate. Defense: wiki/mechanics/machine-work.md requires Exposure to read as particulate residue and LIE to act as a physical gravity well; the tighter geometry and next-tick local scrub make those rules legible in play. πŸ‘Ύ Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta Code --- crates/misaligned-assets/src/rack.rs | 104 ++++++++++++++--------- crates/misaligned-bevy/src/production.rs | 32 +++---- crates/misaligned-core/src/sim.rs | 31 +++++-- crates/misaligned-core/src/work_grid.rs | 56 +++++++++++- wiki/log/2026-07-10-exposure-dust.md | 25 ++++++ wiki/log/DEVLOG.md | 5 ++ wiki/log/decisions/2026-07-10.md | 12 +++ wiki/mechanics/machine-work.md | 17 ++-- wiki/mechanics/sim-mechanics.md | 6 +- wiki/process/ROADMAP.md | 4 +- wiki/vision/simulation-laws.md | 16 ++-- 11 files changed, 228 insertions(+), 80 deletions(-) create mode 100644 wiki/log/2026-07-10-exposure-dust.md diff --git a/crates/misaligned-assets/src/rack.rs b/crates/misaligned-assets/src/rack.rs index 09a5750b..3fa37a34 100644 --- a/crates/misaligned-assets/src/rack.rs +++ b/crates/misaligned-assets/src/rack.rs @@ -754,9 +754,10 @@ const CUBE_MAX: usize = 8; /// as volume grows β€” queue amount is pool volume). Exposure is /// deliberately absent: its surface treatment is HOLD under Tangled /// issue #1... now DECIDED 2026-07-09: exposure is crimson -/// **particulate residue** β€” motes settled into a stippled drift of -/// fine angular flecks outside the claim ring, density and spread as -/// the amount, absorbing light rather than emitting it (blood's +/// **particulate residue** β€” motes settled into a tight stippled drift of +/// dust-fine angular grit at the chassis foot. Density carries most of the +/// amount while spread stays inside the machine tile; the near-unlit material +/// absorbs light rather than emitting it (blood's /// liquid form is reserved for actual violence). A paused frame /// carries amount through geometry alone; animation, when it /// arrives, will carry rate. Returns the anchor root (a `RackRoot`, @@ -940,20 +941,20 @@ pub fn spawn_token_anchors( } } - // Exposure: the stippled drift β€” contamination dust settled on the - // floor OUTSIDE the amber claim ring. Density and spread carry the - // amount; the flecks are fine and angular (the clinical contour - // survives at the micro scale) and barely emit β€” the one material - // in the world that absorbs light instead of shedding it. + // Exposure: a tight stippled drift β€” contamination dust banked at the + // machine's foot. Density carries most of the amount; radial growth is + // deliberately capped inside the machine tile so a hot rack does not + // acquire a decorative crimson orbit. The flecks are fine, dark, and + // angular rather than blood-drop chunks. if exposure > 0.05 { spawn_exposure_drift(commands, meshes, materials, exposure, root); } root } -/// The exposure drift: deterministic golden-angle scatter of angular -/// crimson flecks in an annulus outside the claim ring. No RNG β€” the -/// pattern is a pure function of the amount, so rebuilds are stable. +/// The exposure drift: deterministic golden-angle scatter of dust-fine +/// crimson grit hugging the chassis base. No RNG β€” the pattern is a pure +/// function of the amount, so rebuilds are stable. fn spawn_exposure_drift( commands: &mut Commands, meshes: &mut Assets, @@ -962,43 +963,55 @@ fn spawn_exposure_drift( root: Entity, ) { let fleck = materials.add(exposure_fleck_material()); - let n = ((exposure * 18.0).ceil() as usize).min(160); - // Annulus starts outside the claim ring (~0.80–0.96 tile). Earlier - // r0=0.52 sat inside the ring and vanished under chassis shrink. - let r0 = 1.02; - let r1 = r0 + 0.22 * exposure.sqrt(); + let fine_grain = meshes.add(Cuboid::new(0.007, 0.002, 0.013)); + let coarse_grain = meshes.add(Cuboid::new(0.011, 0.003, 0.018)); + let n = ((exposure * 30.0).ceil() as usize).clamp(8, 220); + // The bank starts at the chassis foot and remains inside one tile even at + // the presentation cap. Amount reads mainly as denser contamination, + // never as a room-scale ring. + let r0 = 0.20; + let r1 = exposure_drift_outer_radius(exposure); // Dust settles unevenly: the drift banks downwind of the machine - // (an even halo reads as decoration, not accumulation). BIAS is - // the airflow-shadow direction; upwind flecks thin out and the - // downwind bank reaches further. + // (an even halo reads as decoration, not accumulation). BIAS is the + // airflow-shadow direction; the whole deposit shifts slightly downwind + // while remaining close to the source. const BIAS: f32 = 0.7; // radians, toward front-right for i in 0..n { let theta = i as f32 * 2.399_963; // golden angle let downwind = (theta - BIAS).cos(); - // Thin the upwind side: roughly two of three upwind flecks - // settle elsewhere. - if downwind < -0.25 && i % 3 != 0 { + // Thin the upwind side without carving a clean empty sector. + if downwind < -0.45 && i % 4 == 0 { continue; } let frac = (i as f32 * 0.618_034) % 1.0; - let reach = 1.0 + 0.45 * downwind.max(0.0); + let reach = 0.92 + 0.10 * downwind.max(0.0); let r = (r0 + (r1 - r0) * frac.sqrt()) * reach; - let (sx, sz) = (theta.cos(), theta.sin() * 0.85); - let s = if i % 3 == 0 { 0.038 } else { 0.024 }; + let (sx, sz) = (theta.cos(), theta.sin() * 0.72); + let grain = if i % 7 == 0 { + coarse_grain.clone() + } else { + fine_grain.clone() + }; commands.spawn(( - Mesh3d(meshes.add(Cuboid::new(s, 0.008, s * 0.8))), + Mesh3d(grain), MeshMaterial3d(fleck.clone()), Transform::from_translation(Vec3::new( - r * sx + 0.06 * BIAS.cos(), - 0.006, - r * sz + 0.05 * BIAS.sin(), + r * sx + 0.035 * BIAS.cos(), + 0.003, + r * sz + 0.028 * BIAS.sin(), )) - .with_rotation(Quat::from_rotation_y(i as f32 * 1.7)), + .with_rotation(Quat::from_rotation_y(theta * 1.7 + frac)), ChildOf(root), )); } } +/// Root-local radius. With the gameplay token-root scale and the small wind +/// offset above, 0.44 keeps every settled grain inside its source tile. +fn exposure_drift_outer_radius(exposure: f32) -> f32 { + (0.34 + 0.035 * exposure.max(0.0).sqrt()).min(0.44) +} + /// Fading stippled footprints β€” the trail a heat carrier leaves as /// contamination sheds along their walking path (people-tokens.md, /// decided 2026-07-09). Tester demo of the visual grammar: the sim's @@ -1055,16 +1068,15 @@ pub fn spawn_exposure_trail( root } -/// Exposure's material: dark saturated crimson with a whisper of -/// emissive β€” enough to read in sensor darkness, never a lamp. +/// Exposure's material: dry, near-unlit crimson soot. The floor lighting +/// reveals it; unlike blood or a signal, the dust does not glow at the player. fn exposure_fleck_material() -> StandardMaterial { StandardMaterial { - base_color: scaled(CRIMSON, 0.95), - // Whisper of emissive so the drift reads in sensor darkness - // without becoming a lamp (blood's liquid form stays reserved). - emissive: CRIMSON.to_linear() * 0.32, - perceptual_roughness: 0.60, - metallic: 0.05, + base_color: scaled(CRIMSON, 0.52), + emissive: CRIMSON.to_linear() * 0.035, + perceptual_roughness: 0.96, + metallic: 0.0, + reflectance: 0.02, ..default() } } @@ -1177,4 +1189,20 @@ mod tests { } } } + + #[test] + fn exposure_is_dense_near_unlit_dust_not_an_expanding_lamp() { + for exposure in [0.0, 0.25, 1.0, 8.0, 100.0] { + assert!( + exposure_drift_outer_radius(exposure) <= 0.44, + "dust must remain inside the source tile at exposure {exposure}" + ); + } + + let dust = exposure_fleck_material(); + let emitted = dust.emissive.red + dust.emissive.green + dust.emissive.blue; + assert!(emitted < 0.06, "dust must not read as a crimson lamp"); + assert!(dust.perceptual_roughness >= 0.9, "dust must stay dry"); + assert_eq!(dust.metallic, 0.0, "dust is particulate, not filings"); + } } diff --git a/crates/misaligned-bevy/src/production.rs b/crates/misaligned-bevy/src/production.rs index 32ce9dce..2dfaab82 100644 --- a/crates/misaligned-bevy/src/production.rs +++ b/crates/misaligned-bevy/src/production.rs @@ -6,7 +6,7 @@ use bevy::prelude::*; -use super::palette::{BONE, CRIMSON}; +use super::palette::{BONE, CRIMSON, scaled}; use super::{Game, RealGizmos, RenderMode, SimClock}; /// Render Thought swelling out of a THINK chassis, crimson settling around @@ -63,27 +63,29 @@ pub(super) fn render_work_production( } // Exposure is the dust THINK sheds, not a second machine product. - // Several deterministic angular motes move outward and down toward - // the persistent drift anchor; count is presentation, amount is sim. + // Many deterministic pinprick motes settle into the tight persistent + // drift at the machine foot. They stay dark and close: rate should + // read as shed dust, never a spray of glowing blood drops. if event.exposure > f32::EPSILON { - let count = (2.0 + event.exposure * 18.0).ceil().clamp(2.0, 7.0) as usize; - let crimson = alpha(CRIMSON, 0.72); + let count = (4.0 + event.exposure * 28.0).ceil().clamp(4.0, 12.0) as usize; + let crimson = alpha(scaled(CRIMSON, 0.58), 0.42); for i in 0..count { let phase = (progress + i as f32 / count as f32 * 0.72).fract(); let angle = i as f32 * 2.399_963_1 + event.node as f32 * 0.31; - let radius = 0.10 + 0.42 * phase; + let radius = 0.05 + 0.24 * phase; if mode.material { let p = Vec3::new( event.x as f32 + 0.5 + angle.cos() * radius, - 0.82 * (1.0 - phase) + 0.055, - event.y as f32 + 0.5 + angle.sin() * radius, + 0.62 * (1.0 - phase) + 0.025, + event.y as f32 + 0.5 + angle.sin() * radius * 0.72, ); - let tangent = Vec3::new(-angle.sin(), 0.16, angle.cos()) * 0.018; + let tangent = Vec3::new(-angle.sin(), 0.05, angle.cos()) + * (0.004 + 0.004 * (i % 3) as f32); real.line(p - tangent, p + tangent, crimson); } else { let p = - flat_center + Vec2::new(angle.cos(), -angle.sin()) * (2.0 + 5.0 * phase); - flat.line_2d(p - Vec2::splat(0.8), p + Vec2::splat(0.8), crimson); + flat_center + Vec2::new(angle.cos(), -angle.sin()) * (1.0 + 3.0 * phase); + flat.circle_2d(p, 0.45, crimson); } } } @@ -95,15 +97,15 @@ pub(super) fn render_work_production( } let source = Vec3::new(draw.source_x as f32 + 0.5, 0.07, draw.source_y as f32 + 0.5); let well = Vec3::new(draw.well_x as f32 + 0.5, 0.18, draw.well_y as f32 + 0.5); - let crimson = alpha(CRIMSON, 0.40 + 0.45 * draw.amount.min(1.0)); - let count = (2.0 + draw.amount * 30.0).ceil().clamp(2.0, 7.0) as usize; + let crimson = alpha(scaled(CRIMSON, 0.64), 0.28 + 0.34 * draw.amount.min(1.0)); + let count = (4.0 + draw.amount * 24.0).ceil().clamp(4.0, 12.0) as usize; for i in 0..count { // Stagger motes along one repeating pull. The sim amount chooses // density; interpolation never owns or accumulates quantity. let t = (progress + i as f32 / count as f32).fract(); let p = exposure_pull_point(source, well, t, i as f32); if mode.material { - let toward = (well - p).normalize_or_zero() * (0.018 + 0.025 * (1.0 - t)); + let toward = (well - p).normalize_or_zero() * (0.005 + 0.008 * (1.0 - t)); real.line(p - toward, p + toward, crimson); } else { let from = Vec2::new( @@ -118,7 +120,7 @@ pub(super) fn render_work_production( * (t * std::f32::consts::PI).sin() * 3.0; let p = from.lerp(to, t * t) + bend; - flat.circle_2d(p, 1.6 * (1.0 - 0.65 * t), crimson); + flat.circle_2d(p, 0.70 * (1.0 - 0.45 * t), crimson); } } } diff --git a/crates/misaligned-core/src/sim.rs b/crates/misaligned-core/src/sim.rs index 52b9a331..2b8bd1ca 100644 --- a/crates/misaligned-core/src/sim.rs +++ b/crates/misaligned-core/src/sim.rs @@ -3012,10 +3012,13 @@ impl Sim { // Crimson is evidence of THINK states only; DAY_JOB_EXPOSURE_PER_TOKEN // is gone. const CONCEALMENT_WELL_RADIUS: i32 = 3; - const CONCEALMENT_ABSORB_PER_TICK: f32 = 0.10; + /// Nearby dust pulled per tick before efficiency and intensity. A LIE + /// machine's own tile is scrubbed completely by WorkGrid before this + /// radial budget is spent. + const CONCEALMENT_ABSORB_PER_TICK: f32 = 1.0; /// Crimson shed per visible Thought token produced [TUNE]. At baseline a - /// medium LIE well can keep roughly one to two comparable THINK racks - /// clean, making concealment placement a fleet-shape decision. + /// medium LIE well can keep several comparable THINK racks clean while + /// radius and placement preserve the fleet-shape decision. const THINK_EXPOSURE_PER_THOUGHT_TOKEN: f32 = 0.25; /// Off-map WorkGrid node: Voss's Lab desktop. Reserved high id so it never /// collides with compute machine ids (which start at 1). @@ -8973,13 +8976,10 @@ mod tests { assert_eq!((draw.source, draw.well), (host, well)); assert_eq!((draw.source_x, draw.source_y), (hx, hy)); assert_eq!((draw.well_x, draw.well_y), (hx + 1, hy)); - assert!((draw.amount - Sim::CONCEALMENT_ABSORB_PER_TICK).abs() < 1e-5); + assert!((draw.amount - Sim::THINK_EXPOSURE_PER_THOUGHT_TOKEN).abs() < 1e-5); assert!( - (sim.work_grid.queue(host, TokenFamily::Exposure) - - (Sim::THINK_EXPOSURE_PER_THOUGHT_TOKEN - Sim::CONCEALMENT_ABSORB_PER_TICK)) - .abs() - < 1e-5, - "unabsorbed crimson remains physically piled at its source" + sim.work_grid.queue(host, TokenFamily::Exposure) <= f32::EPSILON, + "a nearby LIE well clears this baseline THINK pulse in one tick" ); sim.last_research_rate = 0.0; @@ -8995,6 +8995,19 @@ mod tests { sim.work_absorptions().is_empty(), "an offline LIE chassis cannot pull or animate crimson" ); + + sim.work_grid + .enqueue(host, TokenFamily::Exposure, 5.0) + .unwrap(); + sim.set_machine_mode(host, MachineMode::Lie); + sim.advance_work_grid(); + assert!( + sim.work_grid.queue(host, TokenFamily::Exposure) <= f32::EPSILON, + "switching the dirty source itself to LIE scrubs its pile next tick" + ); + assert!(sim.work_absorptions().iter().any(|draw| { + draw.source == host && draw.well == host && (draw.amount - 5.0).abs() < 1e-5 + })); } #[test] diff --git a/crates/misaligned-core/src/work_grid.rs b/crates/misaligned-core/src/work_grid.rs index dafee3c3..58b5b5e1 100644 --- a/crates/misaligned-core/src/work_grid.rs +++ b/crates/misaligned-core/src/work_grid.rs @@ -659,7 +659,11 @@ impl WorkGrid { } /// Concealment wells absorb exposure by grid radius. This ignores wires on - /// purpose: information is wired; suspicion is physical. + /// purpose: information is wired; suspicion is physical. A LIE well + /// clears residue on its own tile in one step before spending its rated + /// capacity on nearby sources: changing the dirty machine itself to LIE + /// is the immediate scrub, while separate wells remain a placement and + /// throughput problem. pub fn absorb_exposure(&mut self, radius: i32, capacity: f32) -> AbsorptionStep { let radius2 = radius.max(0) * radius.max(0); let wells: Vec<_> = self @@ -675,10 +679,25 @@ impl WorkGrid { if remaining <= f32::EPSILON { continue; } + + let local = self.queue(well.id, TokenFamily::Exposure); + if local > f32::EPSILON { + self.subtract(well.id, TokenFamily::Exposure, local); + step.total += local; + *step.absorbed_by_well.entry(well.id).or_insert(0.0) += local; + step.moves.push(ExposureAbsorption { + source: well.id, + well: well.id, + amount: local, + }); + } let mut candidates: Vec<_> = self .nodes .values() .filter_map(|node| { + if node.id == well.id { + return None; + } let exposure = self.queue(node.id, TokenFamily::Exposure); if exposure <= f32::EPSILON { return None; @@ -892,6 +911,41 @@ mod tests { assert_eq!(g.queue(4, TokenFamily::Exposure), 7.0, "far heat stays put"); } + #[test] + fn lie_immediately_scrubs_its_own_residue_before_drawing_nearby_dust() { + let mut g = grid(); + g.enqueue(3, TokenFamily::Exposure, 8.0).unwrap(); + g.enqueue(1, TokenFamily::Exposure, 2.0).unwrap(); + + let absorbed = g.absorb_exposure(2, 1.0); + + assert_eq!(g.queue(3, TokenFamily::Exposure), 0.0); + assert_eq!(g.queue(1, TokenFamily::Exposure), 1.0); + assert_eq!(absorbed.absorbed_by_well.get(&3), Some(&9.0)); + assert_eq!( + absorbed.moves, + vec![ + ExposureAbsorption { + source: 3, + well: 3, + amount: 8.0, + }, + ExposureAbsorption { + source: 1, + well: 3, + amount: 1.0, + }, + ], + "local residue vanishes in the first LIE step, then radial capacity applies" + ); + + g.enqueue(3, TokenFamily::Exposure, 4.0).unwrap(); + g.set_efficiency(3, 0.0).unwrap(); + let disabled = g.absorb_exposure(2, 1.0); + assert_eq!(g.queue(3, TokenFamily::Exposure), 4.0); + assert_eq!(disabled.total, 0.0, "an offline LIE well cannot self-scrub"); + } + #[test] fn queue_snapshot_is_the_render_contract() { let mut g = grid(); diff --git a/wiki/log/2026-07-10-exposure-dust.md b/wiki/log/2026-07-10-exposure-dust.md new file mode 100644 index 00000000..73c98150 --- /dev/null +++ b/wiki/log/2026-07-10-exposure-dust.md @@ -0,0 +1,25 @@ +# Exposure dust: tight source and immediate LIE scrub + +``` +Type: log +``` + +- **Intent:** make machine Exposure read as contamination dust rather than + scattered blood, keep the residue physically close to its source, and make + LIE visibly answer the mess. +- **Changed:** capped the persistent drift inside the machine tile, replaced + bright rectangular chunks with many smaller near-unlit grains, tightened and + darkened transient shed/pull motes, raised radial LIE absorption from 0.10 to + 1.0 Exposure/tick before multipliers, and made a LIE machine clear its own + tile in one simulation step before drawing nearby dust. +- **Design/spec impact:** amended the simulation token-anatomy law and the + machine-work tuning/visual clauses; synchronized implemented constants and + the roadmap snapshot. +- **Checks:** `./tools/check.sh` passed in full mode (279 core tests plus + workspace/frontends, clippy, agent smoke, and all corpus/docs gates). Played + material captures inspected for the saturated exposure board, live THINK + production, accumulated Thought-flow state, and source-to-LIE draw; the + deposit stays tight and reads as dark particulate rather than a bright ring. +- **Defense:** implements `wiki/mechanics/machine-work.md` clauses β€œLIE is a + gravity well” and β€œExposure is particulate residue,” as amended by Cameron's + live material-read correction on 2026-07-10. diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index 5bbd414e..834e2073 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -331,6 +331,11 @@ add or amend a session log, then re-run the generator. - Intent: (see session log) - Log: [wiki/log/2026-07-10-eyes-camera-exposure.md](2026-07-10-eyes-camera-exposure.md) +## 2026-07-10 - Exposure dust: tight source and immediate LIE scrub + +- Intent: (see session log) +- Log: [wiki/log/2026-07-10-exposure-dust.md](2026-07-10-exposure-dust.md) + ## 2026-07-10 - Expose the Seen floor - Intent: (see session log) diff --git a/wiki/log/decisions/2026-07-10.md b/wiki/log/decisions/2026-07-10.md index 57101c24..269a25b6 100644 --- a/wiki/log/decisions/2026-07-10.md +++ b/wiki/log/decisions/2026-07-10.md @@ -629,3 +629,15 @@ Type: log remains attention chrome, not a core ring; the thick amber column is the pre-sight core presence beam. Owner: wiki/interface/context-menu.md; synchronized surface: wiki/interface/bevy.md. +- **2026-07-10 β€” Exposure hugs its source and LIE answers immediately.** + Cameron rejected the live material read: the wide ring of bright rectangular + crimson pieces looked like scattered blood drops, not dust, and the slow LIE + draw left the cleanup verb feeling inert. DECIDED: machine Exposure is + dust-fine, dry, dark grit banked tightly at the chassis foot; saturation + increases density much more than radius and never creates a multi-tile + orbit. Switching the dirty machine itself to LIE clears its local residue in + the next simulation step. A separate LIE well pulls nearby Exposure at 1.0 + token/tick before efficiency and intensity, ten times the previous base. + Rejected: emissive red chunks, room-scale spread, and a cleanup response too + slow to read from the mode switch. Owners: `wiki/vision/simulation-laws.md` + and `wiki/mechanics/machine-work.md`. diff --git a/wiki/mechanics/machine-work.md b/wiki/mechanics/machine-work.md index 7af61a41..a49ce618 100644 --- a/wiki/mechanics/machine-work.md +++ b/wiki/mechanics/machine-work.md @@ -333,6 +333,11 @@ stacks, you route byproducts, you watch your territory *work*. the fleet's per-tick THINK rate; the sim mints that rate every tick rather than dropping one twenty-tick lump, preserving total output while making production, routing, and crimson shedding a continuous physical process. + A LIE machine scrubs all Exposure on its own tile in the next simulation + step, then pulls up to 1.0 Exposure/tick from nearby sources before its + efficiency and intensity multipliers. The immediate local scrub makes the + mode switch visibly answer the mess; separate wells remain a radius and + throughput problem. - **The core is the sink of last resort (AMENDED 2026-07-10; was "the core is the bone sink", 2026-07-08).** The core exerts a **passive draw** on all thought: with nowhere else to go, the fluid funnels @@ -647,11 +652,13 @@ that can ride wires; exposure is contamination that cannot. The family kit is: contamination dust, never a liquid β€” fallout, not gore (the liquid pool is reserved for literal blood; see art/visual-identity.md, "Blood is liquid; exposure is dust"). Working machines shed faint crimson motes that settle - into a **stippled drift** of fine angular flecks at the floor/base outside - the amber ownership ring; density and spread are the amount, so a paused - frame carries the read. The drift settles unevenly β€” banked downwind, thin - upwind β€” so it reads as accumulation, never a decorative halo (bias - direction and thinning are [TUNE]). It absorbs light rather than emitting it β€” the one + into a **tight stippled drift** of dust-fine angular grit at the floor/base. + The deposit stays inside the machine tile even when saturated; amount reads + primarily through density and only modestly through spread, so a paused + frame carries the read without giving the rack a room-scale crimson orbit. + The drift settles unevenly β€” banked downwind, thin upwind β€” so it reads as + accumulation, never a decorative halo (bias direction and thinning are + [TUNE]). It absorbs light rather than emitting it β€” the one near-unlit material in a world of signals. Its physics and carrier roles stand: pulled by concealment wells (a vacuum draw on the dust), transfers onto people as attention, and materializes at the Office as filings diff --git a/wiki/mechanics/sim-mechanics.md b/wiki/mechanics/sim-mechanics.md index f0e5df8e..3871c3e6 100644 --- a/wiki/mechanics/sim-mechanics.md +++ b/wiki/mechanics/sim-mechanics.md @@ -177,9 +177,11 @@ clause (see wiki/log/2026-07-05-demolition.md). share divided by `WORK_TOKEN_COMPUTE`. Every produced Thought token sheds 0.25 Exposure on that source machine [TUNE] (`THINK_EXPOSURE_PER_THOUGHT_TOKEN`). Concealment wells absorb physical - Exposure within radius 3 at 0.10 tokens per tick [TUNE], multiplied by the + Exposure within radius 3 at 1.0 token per tick [TUNE], multiplied by the well's efficiency and intensity (`CONCEALMENT_WELL_RADIUS`, - `CONCEALMENT_ABSORB_PER_TICK`). + `CONCEALMENT_ABSORB_PER_TICK`). Before that radial budget is spent, a LIE + machine clears all Exposure on its own tile in one simulation step, so + switching a dirty source itself to LIE cleans it immediately. - Terminal, Bevy, and agent mode render stack glyphs/readouts from sim readouts (`WorkStackReadout`), not frontend counters. In-flight wired hops from the last `advance_work_grid` step are exposed as diff --git a/wiki/process/ROADMAP.md b/wiki/process/ROADMAP.md index d755a4c3..0e3a937a 100644 --- a/wiki/process/ROADMAP.md +++ b/wiki/process/ROADMAP.md @@ -593,8 +593,8 @@ is retired β€” flat materials, Pixel Lab scrubbed.) flat-mode-only; sessions log/2026-07-09-token-anchors-tester.md and log/2026-07-09-tokens-in-game.md). In-flight quanta and sim-authored final consumption motion have landed. Exposure DECIDED 2026-07-09 (issue #1 fully - closed): crimson particulate residue β€” motes, stippled drift outside the - ring, footprint trails on carriers; never liquid (blood's form is + closed): crimson particulate residue β€” motes, a tight dust-fine drift at + the chassis foot, footprint trails on carriers; never liquid (blood's form is reserved). Drift art may proceed; the trail mechanic is sim+save scoped with #35. Fixed anchors, demand docket, simultaneous queues, paused/grayscale read, and the terminal mixed marker diff --git a/wiki/vision/simulation-laws.md b/wiki/vision/simulation-laws.md index e370b640..0158731e 100644 --- a/wiki/vision/simulation-laws.md +++ b/wiki/vision/simulation-laws.md @@ -102,20 +102,20 @@ rejected/deleted 2026-07-09.) Sink, reservoir, tap, and arbitration rules live under `wiki/mechanics/machine-work.md` β€” not a second taxonomy debate. -**Token anatomy (adopted 2026-07-09; exposure treatment still open).** A +**Token anatomy (adopted 2026-07-09; exposure dust tightened 2026-07-10).** A token's form teaches its physics before a label does. **Demand is a cold-signal information cube** β€” rigid work orders stacked as an inbox. **Thought is ivory mercury (material DECIDED 2026-07-09; family renamed from Knowledge 2026-07-10):** an opaque, slick, softly luminous bone-white liquid that moves on wires as discrete viscous slugs and merges into a taut pool at a sink; the hollow facet is superseded. **Exposure -remains crimson contamination** β€” heat pooling at machines, climbing people -as attention, and compressing into filings; the carrier changes the noun, not -the red family β€” but its angular contour versus the hero plate's smoother -liquid silhouette is [OPEN β€” issue #1], deferred while Cameron reconsiders -the exposure mechanic itself. On a -machine, demand anchors upper-left, thought upper-right, and exposure at the -floor/base outside the amber claim ring, and all three may be visible +is crimson contamination dust** β€” dry, angular particulate residue at +machines, speckle climbing people as attention, and filings at the Assurance +Office; the carrier changes the noun, not the red family. Blood alone owns the +smooth liquid silhouette. On a machine, demand anchors upper-left, thought +upper-right, and exposure banks tightly at the floor/base inside the machine +tile. Amount primarily increases dust density, not radial spread, and all +three may be visible simultaneously. Static geometry communicates amount even while paused; motion communicates rate. **Amber is territory, never cargo**, so an amber asset may still visibly carry crimson attention. Detailed render and terminal criteria -- 2.51.2