diff --git a/crates/misaligned-assets/src/effects.rs b/crates/misaligned-assets/src/effects.rs index 8bc87e6c..9e9ac009 100644 --- a/crates/misaligned-assets/src/effects.rs +++ b/crates/misaligned-assets/src/effects.rs @@ -1,11 +1,3 @@ -//! Shared Thought-liquid presentation. -//! -//! The effects lab supplies authored values; the game supplies sim readouts. -//! Exposure left this generic particle system when its form became a -//! carrier-local custody record; that presentation lives with the shared rack -//! token anchors. This module owns only disposable Thought presentation state -//! (art/effects-lab.md). - use std::{collections::HashMap, sync::Arc}; use bevy::asset::{load_internal_asset, uuid_handle}; diff --git a/crates/misaligned-assets/src/implicit_surface.rs b/crates/misaligned-assets/src/implicit_surface.rs index 5b92b403..d9adb96f 100644 --- a/crates/misaligned-assets/src/implicit_surface.rs +++ b/crates/misaligned-assets/src/implicit_surface.rs @@ -1,8 +1,3 @@ -//! CPU implicit-surface prototype for close Thought rendering. -//! -//! This is presentation geometry, rebuilt from authored/readout amount and -//! rate. It owns no accumulating fluid state (interface/thought-fluid.md). - use bevy::asset::RenderAssetUsages; use bevy::mesh::PrimitiveTopology; use bevy::prelude::*; diff --git a/crates/misaligned-assets/src/main.rs b/crates/misaligned-assets/src/main.rs index 484a1201..be0e2eee 100644 --- a/crates/misaligned-assets/src/main.rs +++ b/crates/misaligned-assets/src/main.rs @@ -19,14 +19,10 @@ use bevy::window::{CursorGrabMode, CursorOptions, WindowResolution}; use palette::{GUNMETAL, NEAR_BLACK, scaled}; use rack::{ClaimStyle, RackMode, RackRoot, RackState, spawn_server_rack, spawn_token_anchors}; -/// Work-token load staged on the single rack (machine-work.md anchors): -/// demand cubes upper-left and ivory-mercury thought upper-right. #[derive(Debug, Clone, Copy, PartialEq, Resource, Default)] struct TokenLoad { demand: usize, thought: f32, - /// Stranded-pool demo: the overflow beads hanging under the thought - /// anchor (interface/thought-fluid.md). stranded: bool, } @@ -141,8 +137,6 @@ fn scene_from_shot( true, )); } - // Token-anchor evidence: an owned-busy WORK rack under a mid or - // overflow work load (machine-work.md cubes + ivory mercury). if kind == "tokens" || kind == "tokens_max" { let load = match kind { "tokens_max" => TokenLoad { diff --git a/crates/misaligned-assets/src/palette.rs b/crates/misaligned-assets/src/palette.rs index 8bec688c..45b8382b 100644 --- a/crates/misaligned-assets/src/palette.rs +++ b/crates/misaligned-assets/src/palette.rs @@ -1,10 +1,3 @@ -//! Single named clinical palette for production world materials and the asset -//! tester (flat-materials.md). -//! -//! Both `misaligned-assets` and `misaligned-bevy` import this module. New -//! production material colors belong here rather than in a frontend-local -//! table or an inline `Color::srgb` literal. - #![allow(dead_code)] use bevy::prelude::Color; diff --git a/crates/misaligned-assets/src/rack.rs b/crates/misaligned-assets/src/rack.rs index e8794143..e63f7363 100644 --- a/crates/misaligned-assets/src/rack.rs +++ b/crates/misaligned-assets/src/rack.rs @@ -1,17 +1,3 @@ -//! Procedural Foundation compute — a tall, slender deployed appliance -//! built from broad folded plates around one deep circular instrument. -//! Chassis albedo is the ownership field (bone-white = under your control, -//! dark gunmetal = foreign or dead). The instrument's collar carries power -//! and ownership state, its cut pattern carries delegated mode, and its -//! pie field carries sim-authored operation throughput. The core is the -//! hottest amber collar in the world. The instrument is the chassis's single -//! lit element. No image textures. -//! Spec: wiki/interface/computer-visual-language.md. -//! -//! Shared chassis library: `misaligned-assets` owns this implementation and -//! `misaligned-bevy` imports it. Both binaries therefore read the same named -//! clinical palette. Some items are used by only one binary, hence the -//! file-level dead_code allowance. #![allow(dead_code)] use bevy::asset::RenderAssetUsages; @@ -93,10 +79,6 @@ impl RackState { } } -/// Delegated machine mode (machine-work.md: one machine, one mode) — -/// carried by the instrument face. Color names the flow family and a -/// one/two/three-notch pattern keeps the read off hue alone. -/// Three player verbs: WORK / THINK / LIE (machine-work.md, 2026-07-10). #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Resource)] pub enum RackMode { /// WORK — eats demand; uninterrupted cold field. @@ -1404,9 +1386,6 @@ pub fn spawn_switch_chassis( root } -// ─── Work-token anchors (machine-work.md, DECIDED 2026-07-09; -// demand form amended to information cubes the same day) ───────────────── - /// Demand cube edge and stack pitch. Sized so the stack reads at default /// Bevy camera once the game counter-scales anchors (bevy.rs /// TOKEN_WORLD_SCALE); the asset tester uses these at 1:1. @@ -1548,10 +1527,6 @@ pub fn spawn_token_anchors( )); } } else { - // The taut suspended pool: queue amount is pool volume. A - // stranded pool (thought with no route — machine-work.md's - // stranded-pile rule) goes visibly wrong: it bulges past taut - // and hangs low, overloaded. let r = (0.070 + 0.055 * thought.sqrt()).min(0.30); let (squash, sag) = if stranded { (0.55, -0.05) } else { (0.42, 0.0) }; commands.spawn(( @@ -1571,10 +1546,6 @@ pub fn spawn_token_anchors( ChildOf(root), )); } - // Stranded overflow: heavy beads hang under the anchor - // (interface/thought-fluid.md). Weight, not gore — bone liquid - // never reaches the floor; the pooled-liquid silhouette on the - // ground is reserved for literal blood (art/visual-identity.md). if stranded { let mercury_beads = materials.add(StandardMaterial { base_color: scaled(BONE, 1.05), @@ -1629,10 +1600,6 @@ mod tests { 0.2126 * s.red + 0.7152 * s.green + 0.0722 * s.blue } - /// Criterion 2 (computer-visual-language.md): ownership is chassis - /// albedo plus the outer instrument ring. The B1 shell must be built - /// around a broad, deep aperture rather than carry a small circular badge. - /// Foreign and dead machines never borrow the player's amber ring or fill. #[test] fn ownership_is_albedo_and_the_integrated_ring() { let (owned_tower, owned_fold) = chassis_palette(true); @@ -1802,11 +1769,6 @@ mod tests { } } - /// Criterion 9 (computer-visual-language.md): the B1 shell is a folded - /// mass, not a cuboid. A rectangular prism gives every front-facing plate - /// the same normal, which is exactly why the old body read as a slab with - /// a badge on it. The footprint must therefore carry unequal chamfers, and - /// the swept mesh must expose those extra facets with outward normals. #[test] fn the_shell_is_a_folded_mass_with_unequal_facets() { let profile = diff --git a/crates/misaligned-bevy/src/consumption.rs b/crates/misaligned-bevy/src/consumption.rs index 914f299d..dd45f8f0 100644 --- a/crates/misaligned-bevy/src/consumption.rs +++ b/crates/misaligned-bevy/src/consumption.rs @@ -10,10 +10,6 @@ use misaligned::work_grid::TokenFamily; use super::{BONE, Game, RealGizmos, RenderMode, SIGNAL, SimClock, TILE_SIZE}; -/// Draw the bottom Demand cube pulling into an executor and the last Thought -/// slug collapsing into the passive core draw. A paused frame hides the -/// transient swallow: amount remains legible in the persistent stack/sink -/// geometry, while motion communicates rate only (machine-work.md). pub(super) fn render_work_consumptions( game: Res, clock: Res, diff --git a/crates/misaligned-bevy/src/main.rs b/crates/misaligned-bevy/src/main.rs index 9e852ef1..56ca9c2a 100644 --- a/crates/misaligned-bevy/src/main.rs +++ b/crates/misaligned-bevy/src/main.rs @@ -67,9 +67,6 @@ use misaligned_assets::institution::{ spawn_institution_prop, }; -/// Shared Foundation-compute meshes and the switch chassis live in -/// `misaligned_assets` (same code the asset -/// tester uses; wiki/interface/computer-visual-language.md). use misaligned_assets::rack::{ ClaimStyle, INSTRUMENT_STEPS, MACHINE_INSTRUMENT_RADIUS, MACHINE_INSTRUMENT_X, MACHINE_INSTRUMENT_Y, RackMode, RackState, spawn_server_rack, spawn_switch_chassis, @@ -133,7 +130,6 @@ const TILE_SIZE: f32 = 16.0; const COMMAND_BAND_HEIGHT: f32 = 106.0; /// On-demand SYSTEMS and NOTICES drawers share one width and never coexist. const DRAWER_WIDTH: f32 = 360.0; -/// The dev two-pane's agent-read column width (digital-read.md criterion 7). const TWO_PANE_WIDTH: f32 = 384.0; const DEFAULT_WINDOW_WIDTH: f32 = 1280.0; const DEFAULT_WINDOW_HEIGHT: f32 = 720.0; @@ -161,8 +157,6 @@ const COMPUTE_CHANNELS: usize = 3; /// exact records remain in inspect/Operations and raise one sealed index tab /// rather than growing unbounded geometry around the person. const EVIDENCE_LITERAL_SLOTS: usize = 7; -/// Compact context-menu card width. Most rows stay terse; exact device choices -/// may unfold one selected-row consequence read (context-menu.md). const MENU_WIDTH: f32 = 300.0; /// Build choices use almost the whole supported frame: one calm choice column /// beside one consequence column. The maximum leaves the world visible at the @@ -188,11 +182,6 @@ const DETECTION_CELLS: usize = 4; // Material render (HD-2D, REAL view): one 3D world unit per tile. const WALL_HEIGHT: f32 = 1.5; const ROCK_HEIGHT: f32 = 2.0; -/// Cutaway height for south-facing structural mass (wall/rock tiles whose -/// known neighbor toward the camera-side interior is open): low enough to -/// read over, high enough to still read as wall footprint -/// (wiki/interface/material-render.md debt 1, decided by screenshot -/// comparison against a steeper pitch). const CUTAWAY_HEIGHT: f32 = 0.42; /// Door slabs cut lower than full height but higher than walls, so a doorway /// in a cutaway wall line still reads as a door, not a parapet gap. @@ -206,11 +195,6 @@ const CAMERA_TILT_DEG: f32 = 40.0; const CAMERA_TILT_CLOSE_DEG: f32 = 21.0; /// Far-zoom pitch: raised/flatter for a stable facility survey read. const CAMERA_TILT_FAR_DEG: f32 = 52.0; -/// Default material-camera distance in world units at zoom 1.0 -/// (material-dark-frame.md: the opening frame is the attention close-up — -/// the rack remains the anchor, but earned floor and room structure must -/// read around it). Tuned as a room security camera on the focused machine, -/// not a god-view of the whole basement or an isolated product shot. const CLOSE_DIST: f32 = 3.25; /// Reference perspective FOV (degrees) at medium zoom. Mild FOV drift at /// close/far is distance-compensated so zoom remains monotonic. @@ -223,9 +207,6 @@ const CAMERA_FOV_FAR_DEG: f32 = 40.0; const LOOK_Y_CLOSE: f32 = 0.32; const LOOK_Y_MED: f32 = 0.55; const LOOK_Y_FAR: f32 = 0.42; -/// Zoom multipliers around the close default (material-dark-frame.md -/// criterion 5): min stays a tight rack close-up, max can still survey -/// lit pools without the plan driving the frame. const ZOOM_STEP: f32 = 0.8; const MIN_ZOOM: f32 = 0.7; const MAX_ZOOM: f32 = 5.2; @@ -235,18 +216,12 @@ const DEFAULT_FLAT_ZOOM: f32 = 0.42; /// A pixel-scrolling trackpad needs a travel distance rather than treating /// every sub-pixel update as a full discrete wheel notch. const WHEEL_PIXELS_PER_ZOOM_STEP: f32 = 120.0; -/// The dark rig's near-nothing ambient brightness (material-dark-frame.md: -/// a physically dark room before Eyes — nobody is home, the AI does not need -/// lights). A live sight feed adds low fill around authored sources. const DARK_AMBIENT: f32 = 8.0; /// Low neutral fill once Eyes earns a live image. The level's authored floor /// fixtures provide the directional light; this only keeps their shadow side /// from collapsing into black. Audio creates no material geometry, so this /// fill cannot turn sound into sight. const CAMERA_AMBIENT: f32 = 160.0; -/// The dev work light's flat neutral flood: ambient bright enough that every -/// mesh is inspectable and albedo reads with no mood. Dev affordance only, -/// never a player surface (material-dark-frame.md, the dev work light). const WORKLIGHT_AMBIENT: f32 = 900.0; /// Recessed data-hall floor fixtures: bright enough to model nearby racks, /// short-ranged enough that the room reads as a sequence of lit aisles rather @@ -389,9 +364,6 @@ fn detailed_read_prose_has_no_standing_world_layer() { assert!(annotations.contains("read_sentences_at_rate(minimum, game.tick_ms)")); } -/// Flat base color per material family (flat-materials.md: material -/// families, not per-tile art). This is the Seen-under-light albedo; fog -/// states and the flat sensorium apply treatments over the same names. fn family_color(tile: TileType) -> Color { use TileType::*; match tile { @@ -522,9 +494,6 @@ fn flat_remembered_color(tile: TileType) -> Color { } fn blueprint_color(tile: TileType) -> Color { - // Blueprint is room topology only (machine-work.md / cursor.md): walls, - // doors, floors. Machine chassis are absent until intel or sight — never - // painted as amber "known racks" on the plan. use TileType::*; if machine_tile(tile) { scaled(PORCELAIN, 0.115) // treat chassis tiles as empty floor on the plan @@ -552,14 +521,6 @@ fn unknown_color(x: i32, y: i32) -> Color { // ─── Render mode (DIGITAL home, REAL material) ─────────────────────────────── -/// Frontend-only representation for the shared physical canvas (F3). This is -/// pure presentation over the same sim state, anchors, cursor, selection, and -/// fog (wiki/interface/views.md criterion 1); it is never saved. -/// -/// `material == false` (DIGITAL, the default/home representation) is the flat -/// sensorium. `material == true` (REAL) is a tilted Camera3d over the same tile -/// grid, floor planes, extruded wall boxes, billboarded props/people, and a few -/// point lights. #[derive(Resource)] struct RenderMode { material: bool, @@ -567,15 +528,7 @@ struct RenderMode { dirty: bool, /// User zoom multiplier for the material camera ([ and ]). zoom: f32, - /// Dev work light (material-dark-frame.md): floods the material scene - /// flat and neutral so geometry the dark rig keeps unlit is inspectable. - /// A debug affordance, never a player surface; toggling it off restores - /// the current fiction exposure (camera-exposed after Eyes, dark before). worklight: bool, - /// Dev two-pane (digital-read.md criterion 7): pairs the live visual - /// dialect with the agent frame's text for the same tick, so parity — - /// how humans think versus how agents think — is diffable. A debug - /// view, never the player-facing default and outside frames-not-dumps. two_pane: bool, } @@ -740,11 +693,6 @@ struct ShotHarness { presentation_progress: Option, } -/// Whether world-overlay gizmo layers must stay off this frame. Gizmos -/// composite in a late render pass that lands on top of UI chrome, so the -/// full-window Operations workspace cannot cover them with an opaque panel -/// alone: every gizmo-drawing system yields at this boundary instead -/// (bevy.md: the resting slab and world verbs do not bleed beneath it). fn world_overlays_suppressed(game: &Game) -> bool { game.screen != Screen::Playing || game.ops.is_some() } @@ -767,32 +715,21 @@ struct Game { /// [`SimClock`] so ticking it does not dirty `Game` every frame and /// force a full restyle/UI rebuild. tick_ms: u64, - /// Log entries with the tick they happened on (the clock is always on - /// screen; every line carries its tick — terminal parity). Sim events - /// keep their anchor: anchored lines are focus links (context-menu.md - /// addendum — clicking one carries the cursor to the thing). log: Vec, /// Frontend-only unread exception subjects. The simulation authors every /// consequential transition; Bevy groups recurrence so one oscillating /// sink or observer cannot turn priority into a raw event count. unread_notice_groups: BTreeSet, - /// The context menu on the focused anchor (wiki/interface/context-menu.md), - /// when open. Only anchor + selection are held; rows are re-queried live. menu: Option, /// Frontend-only held beat after a local menu command. The simulation has /// already committed the action; this preserves its core-authored receipt /// at the acted-on anchor until the player explicitly dismisses it. command_receipt: Option, - /// Frontend-only attention cursor (wiki/mechanics/cursor.md). It is not - /// saved and moving it never mutates sim state. cursor_x: i32, cursor_y: i32, - /// Frontend-only machine multi-select (machine-work.md). Not saved. selected_machines: BTreeSet, /// Active left-drag marquee in grid coordinates, if any. marquee: Option, - /// The Operations workspace (operations-workspace.md), when open. - /// Frontend attention state only: never saved, never a sim mutation. ops: Option, /// Selection retained while FOCUS temporarily returns to the world. ops_resume: Option, @@ -803,8 +740,6 @@ struct Game { /// identity at commit. A stale override (identity no longer eligible) /// is ignored rather than dispatched. ops_plot_personas: BTreeMap<(u8, String), misaligned::persona::PersonaId>, - /// The origin highlighted on the title-screen picker (chargen.md). Applied - /// when the run begins; defaults to Pilot (the identity origin). selected_origin: Origin, } @@ -848,7 +783,6 @@ struct HeldChoiceUi { selected: usize, } -/// Click-drag box select over the map (machine-work.md multi-select). #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct MarqueeDrag { origin_x: i32, @@ -857,7 +791,6 @@ struct MarqueeDrag { current_y: i32, } -/// Open context-menu state (wiki/interface/context-menu.md). #[derive(Debug, Clone, PartialEq)] struct MenuState { anchor: Anchor, @@ -976,17 +909,12 @@ impl Game { .human_menu .is_empty() { - // A tile whose only actionable body is a visible earned person - // routes into their PEOPLE dossier — the person-detail entry - // into the one workspace (operations-workspace.md). if let Anchor::Tile { x, y } = anchor && let Some(person) = self.visible_earned_person_at(x, y) { self.open_operations_at(&OperationsTarget::Person(person)); return; } - // The feedback pulse (context-menu.md addendum): a seen anchor - // answers instead of silence; fogged ground stays silent. if let Some(line) = self.sim.menu_empty_feedback(anchor) { let tick = self.sim.tick; self.add_log(tick, line); @@ -1025,8 +953,6 @@ impl Game { self.command_receipt = None; } - /// A visible, earned person under a tile is the material person-detail - /// route into their PEOPLE dossier (operations-workspace.md entry). fn visible_earned_person_at(&self, x: i32, y: i32) -> Option { self.sim.people.people.iter().map(|p| p.id).find(|&id| { self.sim.person_pos(id) == Some((x, y)) @@ -1089,9 +1015,6 @@ impl Game { true } - /// One Enter/click commitment step on the open workspace: dispatch the - /// exact bound row, or narrate the exact blocked reason to the trace - /// (operations-workspace.md criterion 10). fn ops_enter(&mut self) { let result = { let Self { sim, ops, .. } = self; @@ -1183,12 +1106,6 @@ impl Game { } } - /// Apply the fronting-identity control's rebind to one bound plot start - /// command (operations-workspace.md persona binding control): a pure - /// persona-parameter swap on the exact core-owned `StartPlot` row. The - /// override applies only while that identity is still a live binding - /// choice for this counterparty, so a retired or burned mask silently - /// falls back to the row's own default. fn ops_plot_command(&self, command: &ActionCommand) -> ActionCommand { let ActionCommand::StartPlot { person, @@ -1281,12 +1198,6 @@ impl Game { } } - /// Focus a linked log event (context-menu.md addendum; - /// operations-workspace.md events-and-focus): strategic events open - /// their exact Operations object; spatial anchors carry the cursor — - /// the camera follows — and open the menu. Durable person/flow anchors - /// are Operations targets now. An anchor the senses can no longer place - /// is refused honestly. fn focus_event_anchor(&mut self, anchor: Anchor) { match anchor { Anchor::Flow(id) => self.open_operations_at(&OperationsTarget::Flow(id)), @@ -1357,8 +1268,6 @@ impl Game { } } - /// Begin the run with the title-screen picker's selected origin, rebuilding - /// the sim if it changed (chargen.md: origin is chosen at new-game). fn start_run(&mut self) { if self.sim.origin != self.selected_origin { self.sim = Sim::with_origin(self.selected_origin); @@ -1450,9 +1359,6 @@ impl Game { .map(|m| (m.id, m.x, m.y)) } - /// Shared machine-hotkey target: explicit selection first, then pointer - /// hover, then the keyboard cursor (context-menu.md). Selection is a - /// deliberate act; the pointer may merely be resting over another rack. fn primary_machine_tile(&self, hover: Option<(i32, i32)>) -> Option<(u32, i32, i32)> { if let Some(&id) = self.selected_machines.iter().next() && let Some(m) = self.sim.compute.machines.iter().find(|m| m.id == id) @@ -1636,11 +1542,6 @@ impl Game { } } - /// `r` / `R`: pooled information processing on the selection/hover/reticule - /// target (context-menu.md R1-R3, menu closed). A thin dispatcher over - /// the same `human_menu` rows the open menu executes — `available_actions` - /// stays the single legality source, never a second path into the buffer. - /// A target without the row answers with the empty-menu feedback pulse. fn recording_review_key(&mut self, command: ActionCommand, hover: Option<(i32, i32)>) { let anchor = match self.primary_machine_tile(hover) { Some((_, x, y)) => { @@ -1788,9 +1689,6 @@ fn held_choice_option_bundle(index: usize) -> impl Bundle { ) } -/// The context-menu root node (wiki/interface/context-menu.md), absolute and -/// hidden until an anchor is focused. Its children are the whole card -/// (title and rows); rebuilds clear them via `despawn_related::`. #[derive(Component)] struct MenuPanel; /// One selectable menu row; `index` maps into the live `menu_rows()`. @@ -1936,10 +1834,6 @@ fn main() { ) .add_plugins(MaterialEffectsPlugin) .insert_resource(ClearColor(Color::srgb(0.01, 0.01, 0.02))) - // The pre-Eyes dark rig (material-dark-frame.md): near-nothing ambient, - // carved out only by machine light. After Eyes, authored level fixtures - // do the lighting while apply_material_exposure supplies low neutral fill. - // 3D-only; sprites are unlit. .insert_resource(GlobalAmbientLight { color: Color::srgb(0.62, 0.70, 0.86), brightness: DARK_AMBIENT, @@ -2210,10 +2104,6 @@ fn setup( } } - // Frontend-only attention cursor (wiki/mechanics/cursor.md): not a - // humanoid/process body, just an amber targeting reticle over the tile. - // Eight exterior corner strokes: attention surrounds the anchor and - // never erases the rack, camera, person, or floor mark beneath it. let center = grid_to_world(start.0, start.1, 4.0); for (offset, size) in attention_reticle_segments() { commands.spawn(( @@ -2367,9 +2257,6 @@ fn material_work_route_geometry(route: MaterialWorkRoute, mut line: impl FnMut(V line(route.start, route.end, route.trail); } -/// Wired work cargo in flight (machine-work.md): teal Demand / bone Thought -/// blips crawl the last hop over the wall-clock tick. Positions come from -/// `Sim::work_in_flight` — not frontend counters. fn render_work_routes( game: Res, clock: Res, @@ -2393,11 +2280,6 @@ fn render_work_routes( else { continue; }; - // A thought slug lives inside its move's tick window - // (interface/thought-fluid.md): rate reads as sub-tick transit — a - // bigger move crosses earlier in the window — plus head volume, and - // past RIVULET_TOKENS the move draws as a continuous rivulet with a - // meniscus head. Demand keeps the full-window cross blip. let is_thought = hop.family == TokenFamily::Thought; // Material Thought is owned by the shared effects renderer. Keep this // lightweight gizmo grammar only for the flat sensorium so the two @@ -2478,9 +2360,6 @@ fn render_work_routes( } } -/// Above this many tokens in one move, the wire read merges the slug train -/// into a continuous rivulet (trickle vs stream) [TUNE] -/// (interface/thought-fluid.md). const RIVULET_TOKENS: f32 = 1.0; /// Attach a Thought meniscus to the physical silhouette that owns the sink. @@ -2531,11 +2410,6 @@ fn presentation_progress(game: &Game, clock: &SimClock, harness: Option<&ShotHar } } -/// Sink vessels and the filament snap (interface/thought-fluid.md): every -/// open sink draws a meniscus climbing its capacity, straight from -/// `Sim::sink_readouts()`; a reservoir that fired last tick contracts into -/// the device over the same tick window the sim fired in. The only frontend -/// state is the tick phase — starvation renders as stillness, never a blink. fn render_thought_sinks( game: Res, clock: Res, @@ -2825,10 +2699,6 @@ enum PersistenceInput { Load, } -/// Title-screen origin picker grammar (chargen.md player surface). -/// Navigation steps the selection; only an explicit confirm begins the run. -/// Modifiers, function keys, and every other key are ignored so an OS chord -/// (Control for a screenshot, Command, Shift, Alt) cannot skip the choice. #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum TitlePickerInput { Quit, @@ -2887,9 +2757,6 @@ fn persistence_input(kb: &ButtonInput) -> Option { } } -/// F3 is an anchorless global control. Route it before any world menu or -/// Operations workspace captures input, and leave that attention state intact -/// (views.md criterion 1; context-menu.md). fn view_flip_input(kb: &ButtonInput, game: &mut Game, mode: &mut RenderMode) -> bool { if !kb.just_pressed(KeyCode::F3) { return false; @@ -2972,9 +2839,6 @@ fn handle_input( } match game.screen { Screen::Title => { - // Explicit confirm only (chargen.md). A bare Control / Command / - // Shift must not begin the run — those are OS chords (screenshots, - // paste, etc.), not a picker decision. match title_picker_input(&kb) { TitlePickerInput::Quit => { exit.write(AppExit::Success); @@ -3085,9 +2949,6 @@ fn handle_input( return; } - // The context menu captures input while open (wiki/interface/context-menu.md): - // keyboard select/execute/close here; row clicks and click-away land in - // `menu_pointer`. Opened over anything, it is the action surface. if game.menu.is_some() { menu_keyboard_input(&kb, &mut game, &mut exit); game.drain(); @@ -3114,12 +2975,6 @@ fn handle_input( return; } - // The Operations workspace owns input while open - // (operations-workspace.md): its printed keys navigate views, objects, - // actions, and the confirmation step. Opening the dialogue holds the - // simulation clock and both cameras until it closes; it does not alter - // the player's explicit pause state. Pointer interaction lands in - // `ops_pointer`. if game.ops.is_some() { // Taking `&mut Game` marks the resource changed. Do that only when // Operations actually received input: the panel rebuilds on a changed @@ -3181,9 +3036,6 @@ fn handle_input( }) .flatten(); - // Left-drag marquee selects owned machines in a rect (machine-work.md). - // A click with no drag still moves the cursor (and shift-click toggles - // the machine under the pointer into the selection). if mouse.just_pressed(MouseButton::Left) && let Some((x, y)) = grid { @@ -3268,9 +3120,6 @@ fn handle_input( return; } - // F4: the dev work light (material-dark-frame.md). Floods the material - // scene flat and neutral so geometry the dark rig keeps unlit is - // inspectable; a debug affordance, not a player surface. if kb.just_pressed(KeyCode::F4) && mode.material { mode.worklight = !mode.worklight; let (tick, on) = (game.sim.tick, mode.worklight); @@ -3284,9 +3133,6 @@ fn handle_input( ); } - // F8: the dev two-pane (digital-read.md criterion 7). Pairs the live - // visual with the agent frame's text for the same tick — a debug - // parity instrument, never a player surface. if kb.just_pressed(KeyCode::F8) { mode.two_pane = !mode.two_pane; let (tick, on) = (game.sim.tick, mode.two_pane); @@ -3302,8 +3148,6 @@ fn handle_input( let (dx, dy) = movement(&kb); if dx != 0 || dy != 0 { - // Shift makes the step semantic: the next earned anchor that way, - // not the next tile (keymap.md). if shift { game.jump_anchor(dx, dy); } else { @@ -3344,8 +3188,6 @@ fn handle_input( } if kb.just_pressed(KeyCode::KeyI) { if shift { - // Uppercase `I` opens the Operations workspace on INTEL - // (operations-workspace.md); lowercase `i` stays intensity. rail.close_drawers(); game.open_operations(); } else { @@ -3372,10 +3214,6 @@ fn handle_input( game.quick_one_shot(i / 2, grid); } } - // `r` processes the pooled information inbox on the hover/selection/reticule - // target; `R` (Shift-R) toggles its automatic-processing policy - // (context-menu.md R1-R3). The open-menu branch returned above, so - // these fire only while the menu is closed. if kb.just_pressed(KeyCode::KeyR) { let command = if shift { ActionCommand::ToggleAutoReview @@ -3458,10 +3296,6 @@ fn held_choice_keyboard_controls( kb.just_pressed(KeyCode::KeyQ) } -/// The open context menu's keyboard drive (wiki/interface/context-menu.md): -/// j/k or arrows select, number keys jump, Enter executes the selection -/// (blocked entries narrate why), esc closes. Row clicks and click-away are -/// handled by `menu_pointer`. fn menu_keyboard_input( kb: &ButtonInput, game: &mut Game, @@ -3730,9 +3564,6 @@ fn render_map(game: Res, mut q: Query<(&mut Sprite, &TilePos), With= min_x && pos.x <= max_x && pos.y >= min_y && pos.y <= max_y }); @@ -4179,14 +4010,6 @@ fn focused_reach_path( path } -/// Walk the focused device's graph path back to owned hardware along the -/// cables it actually crosses. -/// -/// Each hop contributes its placed wire route (the wire law, system-laws.md), -/// so the promoted route is the physical run a record or a command would -/// travel — not a shortest-aisle guess. The previous same-room shortcut and -/// out-and-back cancellation existed because hop geometry was inferred; with -/// real routes there is nothing to correct. fn focused_physical_route(sim: &Sim, graph_path: &[(u32, u32)]) -> Vec<(i32, i32)> { let mut points: Vec<(i32, i32)> = Vec::new(); for &(from, to) in graph_path { @@ -4359,8 +4182,6 @@ fn render_sensor_links( draw_local_bay_marker(&mut gizmos, c, Color::srgba(0.70, 0.88, 1.0, alpha)); } - // Proposed build intents: dashed ghosts distinct from built reality - // (building.md / views.md honesty clause). for (start, end) in build_ghost_links(&game.sim) { let start = grid_to_world(start.0, start.1, 0.0).truncate(); let end = grid_to_world(end.0, end.1, 0.0).truncate(); @@ -4470,12 +4291,6 @@ mod build_ghost_projection_tests { } } -/// Held moments stop the world (digital-read.md criterion 5): when a plot -/// waits on the player, dim the frame and hang the question and its bound -/// commands at the target's projected anchor. The card's rows come from -/// `held_choice_cards` unmodified, so the surface's held state and the -/// sim's cannot disagree. Anchor falls back to screen-center when the -/// person is off-camera (a held choice is attention-mandatory even blind). #[expect(clippy::too_many_arguments)] fn render_held_choice( game: Res, @@ -4497,9 +4312,6 @@ fn render_held_choice( else { return; }; - // Both dialects draw the interrupt card (digital-read.md criterion 5). - // Operations owns its own held surface when that workspace is open, so - // do not double-draw there. let card = game .ops .is_none() @@ -4596,15 +4408,6 @@ fn held_choice_pointer( } fn setup_ui(mut commands: Commands) { - // Title / RUN ENDED boundary field (bevy.md overlays). `render_ui` owns its - // copy and visibility; it sits under the opening scrim so starting a run - // hands the frame straight to the silent boundary. - // - // The field is opaque black. A boundary state occludes the world outright: - // no slab, machine body, cursor, focus label, or status read may show - // through it (liturgical-ui-constitution.md, boundary/threshold canon). - // Composition is whitespace, type scale, and one long rule — never cards, - // and the Bevy frame carries no game title (that canon forbids one). let rule = "-".repeat(TITLE_RULE_WIDTH); commands .spawn(( @@ -5291,9 +5094,6 @@ fn setup_ui(mut commands: Commands) { )); } }); - // The held post-commit receipt (digital-read.md): the exact - // committed action's cost and expected signature, straight off - // the ActionDesc captured before mutation. bar.spawn(( Node { width: Val::Percent(100.0), @@ -5419,9 +5219,6 @@ fn setup_ui(mut commands: Commands) { }); }); - // The context menu: an absolute, initially-hidden card whose rows are - // (re)built by `manage_menu_ui` (wiki/interface/context-menu.md). Placed - // at the pointer/cursor by that system. commands.spawn(( Node { position_type: PositionType::Absolute, @@ -5442,9 +5239,6 @@ fn setup_ui(mut commands: Commands) { MenuPanel, )); - // Held moments stop the world (digital-read.md criterion 5): a - // full-frame dim behind the choice card. One step darker, not opaque — - // the world the choice acts on stays visible beneath the question. commands.spawn(( Node { position_type: PositionType::Absolute, @@ -5510,9 +5304,6 @@ fn setup_ui(mut commands: Commands) { )); }); - // Dev two-pane (digital-read.md criterion 7): a left-edge column that - // renders the agent frame's text for the same tick beside the live - // visual. Debug-only; hidden unless F8 is on. commands .spawn(( Node { @@ -5544,10 +5335,6 @@ fn setup_ui(mut commands: Commands) { )); }); - // The Operations workspace (operations-workspace.md): a deliberate - // command surface, not another card beside the resting slab. It takes the - // whole window so the selected object -> relationships -> decision path - // receives the visual weight of the current task. commands.spawn(( Node { position_type: PositionType::Absolute, @@ -5560,8 +5347,6 @@ fn setup_ui(mut commands: Commands) { row_gap: Val::Px(0.0), ..default() }, - // Fully opaque: the workspace owns its moment, and the resting slab - // must not read through it even faintly (clinical-frame.md). BackgroundColor(scaled(NEAR_BLACK, 0.14)), Visibility::Hidden, GlobalZIndex(60), @@ -5775,9 +5560,6 @@ mod menu_focus_tests { #[test] fn keyboard_menu_keeps_cursor_focus_despite_pointer_or_selection_state() { - // context-menu.md: Enter belongs to keyboard focus. Pointer hover is - // intentionally absent from this path, and stale machine selection - // must not move the reticule either. let mut game = Game::new(); game.selected_machines.insert(game.sim.core.host_machine); let (x, y) = game @@ -5883,9 +5665,6 @@ mod menu_focus_tests { } } -/// The recording-review hotkeys (wiki/interface/context-menu.md R1-R3): -/// `r` / `R` are thin dispatchers over the same `human_menu` rows the open -/// menu executes, on the hover/selection/reticule target, menu closed. #[cfg(test)] mod review_key_tests { use super::{ActionCommand, Anchor, Game}; @@ -7126,10 +6905,6 @@ fn menu_row_color(r: &HumanMenuRow, selected: bool) -> Color { } } -/// Pointer drive for the context menu (wiki/interface/context-menu.md): hover -/// selects a row, a click runs it, and a click anywhere off the menu closes -/// it. Keyboard drive is in -/// `menu_keyboard_input`; both surfaces run the identical `menu_rows`. fn menu_row_background(selected: bool) -> Color { if selected { scaled(GUNMETAL_DARK, 0.54) @@ -7406,10 +7181,6 @@ fn wrap_menu_detail_line(line: &str) -> Vec { wrapped } -/// Build and place the context-menu selector (wiki/interface/context-menu.md). -/// The panel is one root; a rebuild despawns *all* its children (title, rows, -/// detail) then respawns the selector. Selection/label refresh mutates row -/// entities in place so pointer interactions stay stable. #[allow(clippy::type_complexity, clippy::too_many_arguments)] fn manage_menu_ui( mut commands: Commands, diff --git a/crates/misaligned-bevy/src/material_view.rs b/crates/misaligned-bevy/src/material_view.rs index 9ddbd19b..a849765d 100644 --- a/crates/misaligned-bevy/src/material_view.rs +++ b/crates/misaligned-bevy/src/material_view.rs @@ -68,8 +68,6 @@ fn material_camera_profile(zoom: f32) -> MaterialCameraProfile { // ─── The wake (world/story/opening.md beat 1 — glow choreography) ──────────── -/// Build-beam birth gesture (feel-floor.md): pad → rising beam → chassis. -/// Frontend-only; the sim already placed the machine. #[derive(Resource, Default)] pub(super) struct BuildBeam { /// Tile where the beam plays; None when idle. @@ -250,9 +248,6 @@ pub(super) enum TilePart { /// A thin dark foot around structural mass: it anchors a wall to the /// porcelain field without adding decorative room dressing. Base, - /// Dedicated cap over a block's top face: without a separate treatment, - /// the top inherits the side material and reads as a flat slab - /// (material-render.md debt 2). Top, Prop, } @@ -328,9 +323,6 @@ pub(super) struct Real3dRoot; #[derive(Component)] pub(super) struct RealCamera; -/// The dev work light flood (material-dark-frame.md): a neutral directional -/// light, hidden with the dark rig, that apply_worklight reveals so geometry -/// the fiction keeps dark can be inspected. #[derive(Component)] pub(super) struct WorkLight; @@ -348,14 +340,6 @@ pub(super) struct FloorFixture { #[derive(Default, Reflect, GizmoConfigGroup)] pub(super) struct RealGizmos; -/// Shared handles for the 3D scene's Seen materials, keyed by -/// (tile, part, live): tiles swap between a small set of pooled materials -/// instead of mutating thousands of unique ones every tick. Fog is -/// deliberately absent from the key because the visibility boundary rejects -/// Unknown, Blueprint, and Remembered geometry before this pool can be read. -/// The `live` bit is the emissive-state variant (flat-materials.md criterion -/// 3): a device with a live feed to the player pools separately from the same -/// device dark. #[derive(Resource, Default)] pub(super) struct Materials3d { pub(super) cache: HashMap<(TileType, u8, bool), Handle>, @@ -790,8 +774,6 @@ pub(super) fn owned_machine_tiles(sim: &misaligned::sim::Sim) -> HashSet<(i32, i .collect() } -// ─── Machine chassis (computer-visual-language.md) ─────────────────────────── - /// The monolith is authored ~2.35 world units tall (identity-plate /// proportions); scaled to sit under the 1.5-unit wall line. const MACHINE3D_SCALE: f32 = 0.56; @@ -913,8 +895,6 @@ pub(super) struct ChassisVisual { /// Thought queue quantized to half-units for change detection; /// the mercury volume renders thought / 2.0. pub(super) thought: u8, - /// Thought here had no route last step: the pool hangs overflow beads - /// (interface/thought-fluid.md stranded read). pub(super) stranded: bool, } @@ -959,9 +939,6 @@ fn machine_activity_amount(sim: &Sim, machine: u32, mode: RackMode) -> f32 { .filter(|readout| readout.node == machine) .map(|readout| readout.thought) .sum(), - // LIE's performed work is interdiction now, not absorption: the - // records it stopped on this tick (machine-work.md under routed - // evidence). RackMode::Lie => sim.lie_stops_for_machine(machine) as f32, } } @@ -1121,10 +1098,6 @@ pub(super) fn chassis_visual(game: &Game, x: i32, y: i32, tile: TileType) -> Cha .unwrap_or_default(); let load = (queues.get(TokenFamily::Demand) + queues.get(TokenFamily::Thought)).ceil() as u8; - // Token anchors (machine-work.md): Demand as countable - // information cubes and Thought as mercury volume. The crimson - // custody rack is retired with pooled exposure — evidence is a - // record on its route, drawn there. let demand = (queues.get(TokenFamily::Demand).ceil() as u8).min(9); let thought = ((queues.get(TokenFamily::Thought) * 2.0).ceil() as u8).min(16); let mode = rack_mode_of(game.sim.work_grid.mode(m.id)); @@ -1365,11 +1338,6 @@ fn spawn_chassis( .insert(Transform::from_translation(pos).with_scale(Vec3::splat(MACHINE3D_SCALE))); (e, 1.0 / MACHINE3D_SCALE) }; - // The soft amber pool the machine's own light throws on the floor - // (material-dark-frame.md): the close-range claim read is white chassis - // plus this cast pool. The ruled underglow claim ring is gone from the - // material frame — it read as UI painted on a physical floor. Drawn at - // tile scale, counter-scaled against the chassis root. if v.state.owned() { spawn_floor_pool( commands, @@ -1381,14 +1349,6 @@ fn spawn_chassis( e, ); } - // Work-token anchors on owned racks (machine-work.md): demand as - // glowing information cubes at the upper-left and Thought as ivory - // mercury at the upper-right — driven by live queue depths. The crimson - // custody rack is gone with pooled exposure: evidence is a record on its - // route now, drawn where it travels. Counter-scaled toward - // TOKEN_WORLD_SCALE so the decided forms stay legible under the - // chassis shrink (same inv-scale pattern as the claim ring). Flat - // sensorium keeps exact-count D/T glyphs; material hides them. if !v.switch && v.state.owned() && (v.demand > 0 || v.thought > 0) { // Counter-scale toward TOKEN_WORLD_SCALE: chassis is MACHINE3D_SCALE, // so local scale = world_target / chassis_scale. @@ -1414,15 +1374,6 @@ fn spawn_chassis( e } -/// The soft amber pool a powered owned machine casts on the floor -/// (material-dark-frame.md): a gradient falloff from the chassis foot into -/// darkness, never a ruled edge — the machine's own light on the ground, -/// and the close-range claim read now that the ruled ring is gone from the -/// material frame. Built from nested emissive discs (no image texture, -/// flat-materials.md): a large faint outer disc fading to nothing, brighter -/// discs stacked toward the center, so the sum reads as a smooth radial -/// gradient with no hard edge. The core throws a wider, hotter pool (it is -/// the most orange thing in the world). fn spawn_floor_pool( commands: &mut Commands, meshes: &mut Assets, @@ -1453,10 +1404,6 @@ fn spawn_floor_pool( }; let outer = base_outer * radius_scale; let peak = base_peak * light_scale; - // Many thin nested discs (no image texture, flat-materials.md): each disc - // covers [0, r], so the center accumulates every layer and the rim only - // the outermost — a smooth radial falloff. The step count is high enough - // that no individual disc edge reads as a hard ring. let layers = 28; let flat = Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2); for i in 0..layers { @@ -1499,12 +1446,6 @@ pub(super) fn known_tile(game: &Game, x: i32, y: i32) -> TileType { } } -/// South-face cutaway rule (material-render.md debt 1): a structural block -/// drops to parapet height when the tile it hides from the pitched camera -/// (its north neighbor, y - 1, farther from the south-anchored camera) is -/// KNOWN open interior. Gated on the neighbor being known: an unknown -/// neighbor keeps full height, so the cutaway itself never leaks whether -/// unscouted space behind a wall is open (legibility law). fn cutaway(game: &Game, x: i32, y: i32) -> bool { y > 0 && !matches!(game.sim.fog_at(x, y - 1), Fog::Unknown) @@ -1596,11 +1537,6 @@ mod door_mesh_tests { } } -/// Emissive glow for a Seen prop — emissive is information, never -/// decoration (flat-materials.md criterion 3): the core reads brightest (it -/// is you), powered machines carry amber machine presence, power -/// infrastructure carries the cold signal, a live feed to the player scans -/// cold on the device, and dead equipment stays dark. fn prop_emissive(tile: TileType, live: bool) -> LinearRgba { use TileType::*; if live { @@ -1618,12 +1554,6 @@ fn prop_emissive(tile: TileType, live: bool) -> LinearRgba { } } -/// Build one Seen material: a solid palette color under light with no image -/// textures anywhere in the world render (flat-materials.md criterion 1). -/// This constructor cannot represent model-state material. The production -/// visibility boundary admits only local Seen before the pool calls it, so -/// Unknown, Blueprint, and Remembered remain geometry-free rather than -/// acquiring dormant material variants. fn seen_material_3d(tile: TileType, part: TilePart, live: bool) -> StandardMaterial { let mut m = StandardMaterial { perceptual_roughness: 0.94, @@ -1640,37 +1570,23 @@ fn seen_material_3d(tile: TileType, part: TilePart, live: bool) -> StandardMater // conduit retain their amber-warm service read. m.base_color = match tile { TileType::CableRun | TileType::Conduit => family_color(tile), - // clinical-frame.md: the Seen floor is a medium-light matte - // porcelain field — broad and calm, still below chassis white - // (capture-validated). _ => scaled(PORCELAIN, 0.74), }; } TilePart::Block => { - // clinical-frame.md: Seen walls are bone/ivory institutional - // faces (gunmetal stays on functional parts); the flat sensorium - // keeps family_color's schematic gunmetal. m.base_color = match tile { TileType::Wall => scaled(BONE, 0.84), _ => family_color(tile), }; } TilePart::Base => { - // Clinical-frame.md: a structural seam at the wall base - // establishes the floor/wall junction without consuming a signal - // color or implying unseen interior detail. m.base_color = scaled(NEAR_BLACK, 1.35); } TilePart::Top => { - // Dedicated cap treatment (material-render.md debt 2): the block - // family darkened per structural class, so tops read as poured - // caps / rock crowns, not the side color smeared flat. let cap = { use TileType::*; match tile { Rock => scaled(GUNMETAL, 0.27), - // clinical-frame.md: the wall cap is the near-black - // cutaway seam — ivory faces, dark cut edge. Wall => scaled(NEAR_BLACK, 1.7), SecurityDoor3 | SealedDoor | RollDoor => scaled(SECURITY, 0.85), _ => scaled(DOOR_SLAB, 0.56), // door slabs: worn plate @@ -1739,12 +1655,6 @@ pub(super) fn setup_3d( )) .id(); - // The material camera: same anchor (the cursor tile) as the flat camera, - // pitched down into the room at the attention-close distance - // (material-dark-frame.md). Renders before the 2D camera, which stops - // clearing in material mode so the UI composites on top. Composition - // (pitch / look height / FOV-compensated distance) is owned by - // material_camera_profile — spawn at the medium default. let profile = material_camera_profile(mode.zoom); let target = grid_to_world_3d(game.cursor_x, game.cursor_y, profile.look_y); commands.spawn(( @@ -1856,9 +1766,6 @@ pub(super) fn setup_3d( }, ChildOf(root), )); - // Dedicated top cap over the box (material-render.md debt 2): - // sides keep the structural family material, while the top - // gets its own treatment instead of a smeared slab. let cap_scale = if matches!(tile, TileType::Rock | TileType::Wall) { Vec3::ONE } else { @@ -2125,11 +2032,6 @@ pub(super) fn setup_3d( )); } - // The light rig (material-dark-frame.md): before Eyes, machine light and - // near-nothing ambient. Once Eyes exists, the authored fixtures light the - // level and a low neutral ambient preserves their shadow-side shape. - // This directional flood belongs only to F4 inspection; ordinary camera - // exposure never reveals it. commands.spawn(( DirectionalLight { color: Color::srgb(0.96, 0.97, 1.0), @@ -2230,9 +2132,6 @@ pub(super) fn setup_3d( } } - // No second amber lamp on foreign/known-subnet devices: blueprint is - // topology, not a glowing rack farm (machine-work.md: no intel, no render). - commands.insert_resource(mesh_pool); } @@ -2413,12 +2312,6 @@ pub(super) fn sync_institution_props( } } -/// Restyle the 3D scene from sim facts: same fog precedence as render_map, -/// projected into visibility + pooled materials/meshes instead of sprite -/// tints. Unknown space stays geometry-free — sensor darkness, not hidden -/// art. Structural blocks swap to the cutaway parapet mesh when they would -/// hide known interior from the pitched camera (south-face occlusion, -/// material-render.md debt 1), and their top caps ride the same height. pub(super) fn restyle_3d( game: Res, mut mode: ResMut, @@ -2443,13 +2336,6 @@ pub(super) fn restyle_3d( for (t, mut mesh, mut mat, mut tf, mut vis) in q.iter_mut() { let fog = game.sim.fog_at(t.x, t.y); let tile = known_tile(&game, t.x, t.y); - // Light is the only revealer (material-dark-frame.md): the material - // render is a camera, and a camera photographs light, not floor - // plans. Only camera-Seen surfaces draw as physical matter. Owned - // telemetry remains readable without sight, but its amber presence - // language is separate from geometry. Blueprint/Remembered mass reads - // in DIGITAL and overlays, never as matter the camera did not see. - // Audio is channel evidence and never creates matter. let show = material_tile_part_visible( t.part, fog, @@ -2486,9 +2372,6 @@ pub(super) fn restyle_3d( tf.translation.y = height + 0.002; } } - // Live-feed emissive state (flat-materials.md criterion 3): a Seen - // device actively feeding the player scans in the cold signal color. - // Telemetry without local Seen remains non-geometric in REAL. debug_assert!(matches!(fog, Fog::Seen)); let live = t.part == TilePart::Prop && game.sim.reach.known_at(t.x, t.y).is_some_and(|d| { @@ -2521,11 +2404,6 @@ fn material_tile_part_visible( } } -/// Scan flicker on live feeds (flat-materials.md: functional shader-level -/// detail only): the pooled live-feed materials' cold-signal emissive -/// breathes, so a device actively feeding the player reads as a running -/// scan, not a static lamp. Mutates only the handful of live-feed pool -/// handles — never per-tile materials. pub(super) fn flicker_feeds( time: Res