New `kiln-tui` crate (ratatui 0.30 / crossterm) that plays a board from a
.toml map named on the command line, letting the player walk around with the
arrow keys or hjkl. It depends only on kiln-core — the engine needed zero
changes, confirming it is genuinely UI-agnostic.
- Text rendering: each Glyph.tile index is reinterpreted as a character via a
CP437->Unicode table (cp437.rs); fg/bg map to ratatui Color::Rgb truecolor.
- render.rs BoardWidget: per-axis viewport that centers a small board and
scrolls a large one to keep the player visible.
- term.rs TerminalCaps: detects truecolor and Kitty keyboard-protocol support,
enabling the protocol when present (held-key repeat, modifier-only keys);
shows a rainbow "truecolor" badge in the bottom border.
- Input loop acts on Press and Repeat (continuous held-key movement) and
ignores Release.
Workspace: removed kiln-egui from members (files left untouched). Updated
CLAUDE.md and ARCHITECTURE.md to document the workspace split and kiln-tui.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ObjectDef gains passable/opaque fields (defaults: false/true); Board::is_passable
consults the object before the grid cell, so objects block movement independently
of the floor tile beneath them
- Editor Objects tab exposes Passable and Opaque checkboxes; changes survive save/load
- Add ObjectDef::new(x, y) to centralise placement defaults; remove triple
default_glyph() call and unused Glyph import from main.rs
- Fix stale Behavior doc comment; update CLAUDE.md and ARCHITECTURE.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace egui text rendering with a BitmapFont system:
- Glyph.tile: u32 replaces ch: char; top-left pixel of PNG is background sentinel
- BitmapFont loads/preprocesses PNG to opaque-white + transparent, tinted at render time
- Default font: assets/vga-font-8x16.png (CP437, 8×16 tiles); placeholder generated if missing
- Boards can specify a per-board font via [font] in their .toml file
- Editor Board tab: "Font…" button opens font dialog (rfd file picker, tile dims, tilesheet preview)
- Glyph picker: tile grid from active font replaces hardcoded ASCII char grid
- map_file: TileIndex untagged enum accepts char or integer in palette entries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add paint_glyph(painter, rect, glyph) to render.rs; draw_glyph now
delegates to it, eliminating the duplicated rect_filled+text pattern
that appeared in four places across editor.rs and glyph_picker.rs
- Remove unused _board param from show_editor_panel and its call site
- Drop redundant section-header comments in glyph_picker.rs (the
ui.label() calls immediately below already name each section)
- Remove extracted fg/bg/cur_ch locals in the char grid loop now that
paint_glyph accepts a Glyph directly
- Fix CLAUDE.md update phase description (stale from pre-refactor)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updates Cargo.toml package name, window title, and all references in
ARCHITECTURE.md and CLAUDE.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Makes the nine layout constants self-documenting by showing which value
controls which part of the window (cell size, menu bar, panel margin,
side panel, and overall window dimensions).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents render.rs, editor.rs, and glyph_picker.rs; updates the module
structure diagram and main.rs section to reflect the refactored layout.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Splits the flat 432-line main.rs into four modules so each file has one
clear job: render.rs owns layout constants and drawing primitives,
editor.rs owns EditorTab/EditorState and the side panel, glyph_picker.rs
owns the floating picker dialog with a decoupled (open, glyph) interface,
and main.rs is reduced to AppMode, App, and the frame loop (~150 lines).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract draw_board() to eliminate duplicated board+player render loop in Edit and Play branches
- Extract pos_to_cell() to eliminate duplicated click-to-cell floor math in board and char grid handlers
- Simplify glyph dedup to use Glyph: PartialEq directly instead of manual key tuples
- Merge two identical clicked() handlers in archetype list into one || check
- Remove WHAT-explaining comments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Selecting a different archetype in the editor now updates the active
glyph to that archetype's default_glyph(), keeping the visual preview
in sync with the selected behavior type.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Glyph chooser: a painted preview button in the Palette tab opens a
floating dialog with a board-palette picker, fg/bg color pickers
(egui built-in), and a 16×6 printable ASCII character grid. The
stamped glyph is now independent of the archetype's default.
Side panel: widened to 200 px (resizable), tabbed (Palette / Board /
World), archetype rows show their default glyph cell, list scrolls
after 5 entries, labels use ui.label() for consistent sizing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Edit mode now wraps the board in a ScrollArea so horizontal/vertical
scroll bars appear when the board is larger than the window. Play mode
keeps the existing player-centered viewport with no scroll bars.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Window size is now fixed (840×524) and independent of map dimensions.
Small maps center in the viewport; maps larger than the viewport keep
the player centered and clamp at board edges so no empty space shows.
Also derives Copy+Clone on Player to enable the per-frame origin calculation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the replacement of Element with Behavior + Archetype, the
elimination of the per-board element palette, the new map file format
(archetype = "name" instead of passable = bool), the ErrorBlock sentinel,
and the editor mode (AppMode, EditorState, palette panel, click-to-paint).
Also updates "What's not yet implemented" to reflect editor progress and
call out the Object behavior / glyph chooser / file open gaps.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AppMode enum (Play/Edit) gates arrow-key input; a mode toggle in the
menu bar switches between them. Edit mode shows a SidePanel listing the
available archetypes (Empty, Wall, Object); clicking one selects it.
Clicking a board cell in Edit mode stamps it with the selected
archetype's default glyph. Mouse-to-cell conversion mirrors the
rendering origin math so clicks land on the correct cell.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Element is replaced by two types: Behavior (a plain struct of runtime
properties: passable, opaque) and Archetype (an enum of named presets:
Empty, Wall, Object, ErrorBlock). Board.cells changes from Vec<(Glyph,
usize)> to Vec<(Glyph, Archetype)>, eliminating the per-board element
palette. Map files now reference archetypes by name (archetype = "wall")
instead of property bags (passable = false), so the archetype list can
be reordered without breaking saved games. Unknown archetype names
produce an ErrorBlock cell (yellow ? on red) so malformed maps are
immediately visible in-game.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All public types, fields, and functions in game.rs and map_file.rs now
have /// doc comments. main.rs has /// on App and draw_glyph plus inline
comments explaining the input/render pipeline. CLAUDE.md records the
expectation that generated code includes comments.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the player-as-object goal and calls out the four specific
places in the current design (Board.player, player_start, try_move,
main.rs overlay) that will need to change when that's implemented.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the module structure, key design decisions and their reasons,
map file format design, what's not yet implemented, and ZZT background
for future development sessions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents all implemented modules, data structures, map file format,
and key design decisions made during this session.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces a map file format: TOML with a [palette] mapping characters
to (Glyph, Element) definitions and a [grid] multi-line string. Board
now owns the player position, objects, and portals. map_file::load()
deserializes a file and converts it to a Board via From<MapFile>.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Accounts for egui's 8px CentralPanel margin in the minimum window size.
When the window is larger than the minimum, the board is centered in the
available area.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements Glyph (per-cell visual), Element (shared behavior palette),
and Board (60x25 grid of (Glyph, usize) cells). Player walks around
with arrow keys and is blocked by wall elements.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>