Load maps from TOML files with XPM-style palette

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>
This commit is contained in:
2026-05-16 01:50:05 -05:00
parent 37c10c7c38
commit 2dc749e037
6 changed files with 254 additions and 69 deletions
+11 -8
View File
@@ -2,7 +2,8 @@ use eframe::egui;
use egui::{Align2, FontId, Key, Pos2, Rect, vec2};
mod game;
use game::{GameState, Glyph, BOARD_W, BOARD_H};
mod map_file;
use game::{GameState, Glyph};
const CELL_W: f32 = 14.0;
const CELL_H: f32 = 20.0;
@@ -11,8 +12,10 @@ const MENU_H: f32 = 24.0;
const PANEL_MARGIN: f32 = 8.0;
fn main() -> eframe::Result<()> {
let board_px_w = BOARD_W as f32 * CELL_W + 2.0 * PANEL_MARGIN;
let board_px_h = BOARD_H as f32 * CELL_H + MENU_H + 2.0 * PANEL_MARGIN;
let board = map_file::load("maps/start.toml").expect("failed to load maps/start.toml");
let board_px_w = board.width as f32 * CELL_W + 2.0 * PANEL_MARGIN;
let board_px_h = board.height as f32 * CELL_H + MENU_H + 2.0 * PANEL_MARGIN;
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_inner_size([board_px_w, board_px_h])
@@ -22,7 +25,7 @@ fn main() -> eframe::Result<()> {
eframe::run_native(
"Viberogue",
options,
Box::new(|_cc| Ok(Box::new(App::new()))),
Box::new(move |_cc| Ok(Box::new(App::new(board)))),
)
}
@@ -31,8 +34,8 @@ struct App {
}
impl App {
fn new() -> Self {
Self { state: GameState::new() }
fn new(board: game::Board) -> Self {
Self { state: GameState::new(board) }
}
}
@@ -74,8 +77,8 @@ impl eframe::App for App {
draw_glyph(
painter,
origin,
self.state.player.x as usize,
self.state.player.y as usize,
self.state.board.player.x as usize,
self.state.board.player.y as usize,
&player_glyph,
);
});