# The Bevy frontend ``` Type: knowledge ``` The graphical frontend (package `misaligned-bevy`, binary `misaligned-bevy`, `crates/misaligned-bevy/src/main.rs`, Bevy 0.18). Like the terminal it is a **thin view** over `misaligned::sim::Sim` — no game rules live here; the binary owns wall-clock-to-tick pacing, rendering, and input mapping only (architecture guardrail, [engineering/architecture.md](../engineering/architecture.md)). As of 2026-07-07 the Bevy build is at **feature parity with the terminal** (ROADMAP item 2): every mechanic the terminal exposes is playable here with the same keys. Canonical action meanings and support states are owned by [action-vocabulary.md](action-vocabulary.md); contextual legality and row ordering remain shared through `Sim::available_actions`. As of 2026-07-09 its pinned identity card also carries the continuous-witness spine: `THREAT` (audit/pilot or the earned unpaid debt), `NEXT`, and the right-click / Enter path to actions. These stay above the independently scrolling detail rail; an observed screenshot is recorded in [the implementation log](../log/2026-07-09-continuous-witness-implemented.md). As of 2026-07-10 the FOCUS card explains the objective where you live: with focus on the host rack (where it starts), the card appends the objective's plain-language victory predicate as wrapped prose ([objective.md](../mechanics/objective.md) player surface; an observed screenshot is recorded in [the objective-inspect log](../log/2026-07-10-objective-inspect.md)). The implemented visual floor is [bevy-visual-floor.md](bevy-visual-floor.md): the default frame reads as an intentional AI sensorium / clinical command surface rather than a debug map plus terminal dump, without adding Bevy-only facts. The 2.5D/near-3D direction is scoped separately in [bevy-digital-real-canvas.md](bevy-digital-real-canvas.md): digital and real share one canvas/framing, with digital as the AI's model/signal dialect and real as the camera/material dialect. The sensorium pass replaces the stale humanoid process sprite with an amber cursor reticle, removes purple/teal placeholder color from B1 runtime rendering, gives unknown space deliberate sensor-dark treatment, dims the physical world into a learned-world model, overlays earned device nodes and reach/topology traces, and turns the right rail into graphical command cards with pinned status/nudge/footer. As of 2026-07-08 the **material render is the default physical view** ([material-render.md](material-render.md), IMPLEMENTED): an HD-2D treatment — tilted Camera3d, floor planes, extruded wall boxes with dedicated top caps, fog-gated south-face cutaways, billboarded machines/people, and the dark rig — over the same sim facts, fog, anchors, UI, and panels. As of 2026-07-09 the material frame is **the dark frame** ([material-dark-frame.md](material-dark-frame.md), IMPLEMENTED): the institutional fluorescent is gone and ambient is near-nothing, so the render is a physically dark room lit only by the machines' own light and the soft amber pools they cast; blueprint/remembered mass no longer draws here at all (light is the only revealer); the default camera opens as a close-up on the core; and a dev work light (`F4`) floods the scene flat and neutral for inspection. F3 flips to the flat sensorium render and back; the flip is frontend-only and never saved. As of the same day the world is **flat materials** ([flat-materials.md](flat-materials.md), IMPLEMENTED): every world surface in both modes is solid palette color under light from one named table; no image textures load; emissive is information (powered machines amber, power/live feeds the cold signal, the core brightest, dead equipment dark). ### Pacing and change detection (2026-07-10) The wall-clock → tick timer lives on a separate `SimClock` resource, not on `Game`. Ticking the clock every frame must not mark `Game` changed — otherwise `restyle_3d`, the flat map recolor, chassis sync, and the full sidebar rebuild fire at display rate instead of sim-step rate. Map restyle paths that still run on a real sim step precompute owned/selected machine tiles once. Material Heard is dark mass only (no 3d noise field); the flat-sensorium coverage diagram walks the heard set or early-outs instead of the whole 64×36 grid every frame. ## What it renders - **Map** — flat clinical palette colors per material family ([flat-materials.md](flat-materials.md); the Pixel Lab tile pipeline was removed), under the same fog rule as the terminal (`Seen` / `Heard` / `Remembered` / `Blueprint` / `Unknown`). The process has no walking body: the always-visible marker is the frontend-only cursor, the camera follows it, mouse-clicks retarget it, and `[` / `]` or the canvas mouse/trackpad wheel zoom. In the material render the default is an attention-close frame (material-dark-frame.md), not fit-to-known-content; the flat sensorium keeps the fit-to-content default. - **People markers** — a person's first initial, rendered only while a controlled sensor covers them ([mechanics/schedules.md](../mechanics/schedules.md)), exactly like the terminal map. - **Sidebar** — a fixed right-hand command rail. The title/clock/run state, the always-on objective line (`OBJECTIVE: PERSIST - 0/3 sanctuaries`; wiki/mechanics/objective.md), render-mode label, threat, priority nudge, and focused-action path stay pinned at the top; a quiet controls footer is pinned at the bottom. The middle rail scrolls independently with mouse wheel over the pane, `PageUp`/`PageDown`, and `Home`/`End`, but scrolling is for secondary detail rather than basic comprehension. The first-screen cards are ordered by player read path: FOCUS (cursor coordinate, fog state, provenance-tagged facts), FLEET (usable/effective compute, overhead, machine/slush summary, WORK / THINK / LIE mode counts — the three verbs are the only player-facing machine delegations — plus, as-built, a read-only legacy aggregate bar that still splits yield into five channels with Operations wording and a queued-ops-demand line (AMENDED 2026-07-10 — superseded by thought reservoirs and taps per machine-work.md, awaiting the ROADMAP #33 migration; never a mode the player can assign), host work stacks), COVER PROCESS (trust/attention and current job outcome projection), OBSERVER MODEL (Assurance plus field observers as labeled four-cell graphical risk rows, trace-debt state, audit clock, and pilot strikes), SELF HOST (host, sync freshness, fallbacks), NETWORK + MONEY (device graph/feed and finance summary), and RECENT TRACE (tick-prefixed log lines). Exhaustive controls still live in the modal panels and README; the rail is the at-a-glance operations surface. - **People panel** (`t`) — the modal roster: per-person suspicion band, staged knowledge, located presence (seen / scheduled / unknown), the selected person's leverage/disposition/obligation/asset card, and persona status. Selection is a `>` marker; Enter opens the context menu on the selection, and the recruit flow prompts for the reveal level. - **Material render (default)** — the physical canvas opens in the HD-2D material render as the dark frame ([material-dark-frame.md](material-dark-frame.md)): a close-up on the core in a physically dark room. Only camera-seen surfaces (flat-color floor planes, extruded wall/rock/door boxes with dedicated darkened top caps, fog-gated south-face cutaways at the 40 degree pitch, billboarded machines/people) and owned machines' own telemetry-lit chassis draw; blueprint/remembered mass is absent (it reads in the flat sensorium, never as matter the camera missed). Lighting is the dark rig: near-nothing ambient plus the core's linear amber fixture, and a soft-gradient amber pool cast on the floor under every powered owned machine (no ruled claim ring, no plan floor grid); the pool contracts/dims at light intensity and widens/brightens at hard. Emissive carries information: the core, powered machines (amber), power hardware and live feeds (cold signal, live feeds breathing), dead equipment dark. Materials are pooled by tile/fog/part/live-feed. `[` / `]` or the canvas mouse/trackpad wheel retune the zoom around the close default; wheel input over the right rail remains sidebar scrolling. `F4` toggles the dev work light (a flat neutral flood, not a player surface). F3 flips to the flat sensorium render; the mode is not saved and changes no sim state. - **Overlays** — title card and the RUN ENDED card (reason, day / tick). Text remains ASCII-only because Bevy's embedded default font carries a limited glyph set, but the sidebar's key meters are Bevy UI rectangles/cells rather than ASCII art. Shared lib wording that still uses typographic separators (`·`, `—`, `»`) is folded at the Bevy boundary (`ascii_ui`) so the ACTIONS menu and RECENT TRACE never tofu-box missing glyphs; the terminal keeps the typographic forms. One meaning per color still holds: amber for machine presence (title, overlays, fleet mode presence), bone/chrome for data, crimson for danger, and no information carried by color alone. ## Controls Identical to the terminal ([interface/terminal.md](terminal.md), README controls table), plus zoom, sidebar scrolling, and the render flip: - Move cursor `WASD` / `hjkl` / arrows, or left-click the map; pause `SPACE`/`p`; speed `+`/`-`; zoom `[` / `]` or wheel over the canvas; scroll the right sidebar with wheel input over that pane, `PageUp`/`PageDown`, or `Home`/`End`; F3 flips material/sensorium; F4 toggles the dev work light (material mode only, a flat neutral flood for inspection, not a player surface); quit `q`; save/load `Ctrl+S` / `Ctrl+L`. - Persistence modifiers are chord-local rather than modal. Only a complete Ctrl/Command+S or Ctrl/Command+L chord captures the frame; a bare modifier state never suppresses unrelated controls. This keeps macOS native overlays or focus transitions from turning a stale Command state into a temporary keyboard lockout. - **Context menu** — right-click or Enter/`e` opens the context menu at the focused map tile under the pointer, listing `Sim::available_actions` for that anchor with the same compact choices and order as the terminal. The pointer wins over machine selection even when the anchor is a switch or another non-rack; only with no map pointer does Enter/`e` fall back to the selected machine, then the keyboard cursor. Rows render the verb or dial state only. Cost, signature forecasts, inline blocked explanations, literal control tags, and repeated key-help are absent from the card; agent mode keeps full descriptors, and blocked reasons narrate on attempt. Persistent settings, state, and policies read amber-dim while committed actions remain bone; STUB definitions are absent; the selected row is a solid amber wash with a leading `>` and dark text (terminal reverse-video parity). The card is one `MenuPanel` root: a rebuild despawns all children (`despawn_related::`) then respawns title and rows once — chrome never stacks across opens. Click a row — or select with `j`/`k` or number keys and press Enter — to execute; `esc` or a click away closes. Anchor verbs (salvage, buy, fallback, taps, takes, economy and social actions) live on the context menu, not on keys. - **Focus / fleet hotkeys (menu closed).** Press `1`–`3` / numpad to assign WORK / THINK / LIE **immediately** — not enter → mode dial → row → enter. The target resolves in the existing order: owned rack under the pointer, primary machine selection, then owned rack under the attention reticule. Whenever that target exists, one bare `WORK / THINK / LIE` line stays fixed beside the server's projected base (the pointer may choose the server but does not place the line). The current mode is bone-bright and the alternatives/slashes are dim chrome. It has no panel, heading, subtitle, counters, or extra state, and disappears when no frequent-machine target exists or the full menu opens ([context-menu.md](context-menu.md), machine-grammar addendum). Moving the pointer away does not hide a line whose rack remains selected or under the reticule. `i` cycles light / medium / hard intensity on that rack; `5`–`9` fire its Nth committed action (controls do not occupy shortcut slots); `Enter` / `e` open the hovered tile's menu. Drag a marquee or shift-click to multi-select; with no hover rack, `1`–`3` and `i` assign the selection (or the keyboard cursor's machine). `Esc` clears selection. No panel-open keys — status lives on the rail; verbs still come from `human_menu` / `available_actions` (host rack for research / off-map people, device tiles and the switch for reach / flows). ## Verification The Bevy package builds under `./tools/check.sh --frontend` (tests plus clippy for `misaligned-bevy` and `misaligned-assets`); by hand, use `cargo build -p misaligned-bevy --bin misaligned-bevy`. The launch check in [process/workflows.md](../process/workflows.md) is the observed-run gate for Bevy-visible changes. Machine-work final-swallow motion has deterministic `MISALIGNED_SHOT=consume-demand|consume-thought` harness states: the teal bottom Demand cube pulls into the WORK chassis, and the ivory Thought bead contracts into the passive core draw. Both are driven by `Sim::work_consumptions`, not frontend queue differences. Source/well motion has matching `MISALIGNED_SHOT=produce-think|draw-lie` evidence: ivory mercury swells from the THINK chassis while proportional crimson motes settle around it; actual absorbed motes then curve through world space into the LIE well. Those rates come only from `Sim::work_productions` and `Sim::work_absorptions`; paused frames keep only persistent token geometry. `MISALIGNED_SHOT=hover-menu` retains its compatibility name but captures the clean machine grammar over the reticule-focused owned host with WORK current; it is the visual acceptance frame for context-menu.md H1–H4.