jevsnes.git / packages / panels / README.md

Chapter 7: panels, everything drawn beside the picture

The window shows the game in the middle and, around it, what we want to know about the game: what the bot thinks it is doing, the game state in words, every question Jev was asked, the pad, and a timeline to scrub. This crate draws all of that. It does not draw the game: the picture is never drawn over, so nothing covers the game's own hearts, rupees and item box.

Every panel here is a function from a plain value to egui calls (and, being built with the hot-patch flags, can be changed while the game runs: chapter 27). egui is an immediate-mode UI: there is no tree of widgets kept between frames. Each frame, the app calls panels::state::show(ui, &state) (or its neighbours), and whatever those calls describe is what is on screen. If you have written a React component that is a pure function of its props, you have written one of these; the difference is that it is called sixty times a second and there is no diffing.

Aside: plain data in, on purpose. The bot panel never sees a zbanks::Report, and the replay panel never sees a replay::Tree. Those crates link C or write files, and this one must stay portable (chapter 1). So the app converts what it has into this crate's own small structs, and these functions only draw.

The layout is one function of the window's size, Layout::of: the picture's cell is exactly 4:3 with no slack, the two side columns are always the same width, and directly under the picture are the scrubber and then the pad. A test says so.

flowchart TB
  subgraph window
    direction LR
    L["left: Bot, MCP"] --- P["picture, 4:3"] --- R["right: State, Jev"]
  end
  P --- S["scrubber"] --- PAD["pad"]

Try it. nix develop -c buck2 test //packages/panels:test checks the layout invariant, the scrubber's click-to-frame maths and the Jev history's rows (the favourite, a missing probability, a long option wrapping). To see the panels themselves, open the window (chapter 12).

For the people who maintain it

In this folder

PathWhat
src/lib.rsThe modules.
src/bot.rsWhat the bot says about itself: its info line, task list, goal list with scores, traps, and the stall and recovery lines. Plain data in; this crate never links the bot.
src/jev.rsJev at the goal choice: on or off, the shared spend guards (spent so far, plainly, with no cap), a usage graph bucketed by game frame across the current recording with a playhead, and a scrollable, click-to-expand history of every choice (the request as sent, every option's probability, the pick and upstream's own, tokens, latency, cost, or why nothing was asked).
src/state.rsThe alttp::State in words.
src/pad.rsA SNES pad. Buttons held on the last frame are lit; a press that came with a confidence carries it as a percentage.
src/layout.rsThe whole window layout as one function of its size, with its test.
src/replay.rsThe replay timeline: a scrubber over everything a recording has played, play/pause, skip to end, the speed control, and "run the bot from here".
src/palette.rsEvery colour these panels use, legible on the dark theme.
BUCKThe rust_library, built with the hot-patch flags (-Csave-temps=true, -Clink-dead-code), and //packages/panels:test.

The MCP panel is not here: only the native window has a server, so it lives in apps/native.

← Previous: Chapter 6, replay/ · Up: packages · Next: Chapter 8, mcp/ →