multi-board files

This commit is contained in:
2026-06-12 23:35:40 -05:00
parent 8e79b30583
commit e5c6affc41
4 changed files with 28 additions and 15 deletions
+2
View File
@@ -6,6 +6,8 @@ pub mod game;
pub mod log; pub mod log;
/// Map file loading and saving (`.toml` format). /// Map file loading and saving (`.toml` format).
pub mod map_file; pub mod map_file;
/// World type: a named collection of boards in a single `.toml` file ([`world::World`], [`world::load`]).
pub mod world;
/// Rhai scripting runtime for board objects ([`script::ScriptHost`]). /// Rhai scripting runtime for board objects ([`script::ScriptHost`]).
pub mod script; pub mod script;
pub mod glyph; pub mod glyph;
+2 -1
View File
@@ -104,7 +104,8 @@ fn start_map_greeter_runs_init() {
// confirm the greeter read the board (interpolated message) and wrote to // confirm the greeter read the board (interpolated message) and wrote to
// itself (set_tile). Also guards the example from drifting out of sync. // itself (set_tile). Also guards the example from drifting out of sync.
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/../maps/start.toml"); let path = concat!(env!("CARGO_MANIFEST_DIR"), "/../maps/start.toml");
let board = crate::map_file::load(path).expect("load start.toml"); let mut world = crate::world::load(path).expect("load start.toml");
let board = world.boards.remove(&world.start).expect("start board");
let mut game = GameState::new(board); let mut game = GameState::new(board);
game.run_init(); game.run_init();
assert!( assert!(
+9 -3
View File
@@ -19,7 +19,7 @@ mod input;
use kiln_core::game::GameState; use kiln_core::game::GameState;
use kiln_core::log::LogLine; use kiln_core::log::LogLine;
use kiln_core::map_file; use kiln_core::world;
use ratatui::Frame; use ratatui::Frame;
use ratatui::crossterm::event::{ use ratatui::crossterm::event::{
self, DisableMouseCapture, EnableMouseCapture, Event, KeyEventKind, self, DisableMouseCapture, EnableMouseCapture, Event, KeyEventKind,
@@ -49,8 +49,14 @@ fn main() -> ExitCode {
}; };
// Load before touching the terminal so load errors print to a normal screen. // Load before touching the terminal so load errors print to a normal screen.
let board = match map_file::load(&path) { let board = match world::load(&path) {
Ok(board) => board, Ok(mut w) => match w.boards.remove(&w.start) {
Some(b) => b,
None => {
eprintln!("error: start board '{}' not found", w.start);
return ExitCode::FAILURE;
}
},
Err(e) => { Err(e) => {
eprintln!("error loading {path}: {e}"); eprintln!("error loading {path}: {e}");
return ExitCode::FAILURE; return ExitCode::FAILURE;
+15 -11
View File
@@ -1,10 +1,14 @@
[map] [world]
name = "Kiln Demo"
start = "start"
[boards.start.map]
name = "Starting Room" name = "Starting Room"
width = 60 width = 60
height = 25 height = 25
player_start = "@" # placed by the '@' grid char (convention) player_start = "@" # placed by the '@' grid char (convention)
[palette] [boards.start.palette]
" " = { archetype = "empty", tile = " ", fg = "#000000", bg = "#000000" } " " = { archetype = "empty", tile = " ", fg = "#000000", bg = "#000000" }
"#" = { archetype = "wall", tile = "#", fg = "#808080", bg = "#606060" } "#" = { archetype = "wall", tile = "#", fg = "#808080", bg = "#606060" }
"+" = { archetype = "banana", tile = "#", fg = "#808080", bg = "#606060" } "+" = { archetype = "banana", tile = "#", fg = "#808080", bg = "#606060" }
@@ -17,7 +21,7 @@ player_start = "@" # placed by the '@' grid char (convention)
# name the built-in generators (random dark, low-saturation texture cached at # name the built-in generators (random dark, low-saturation texture cached at
# load); a palette entry could also be a fixed glyph like # load); a palette entry could also be a fixed glyph like
# `{ tile = ".", fg = "#222", bg = "#000" }`. # `{ tile = ".", fg = "#222", bg = "#000" }`.
[floor] [boards.start.floor]
content = """ content = """
gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg
@@ -46,13 +50,13 @@ gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg
gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
""" """
[floor.palette] [boards.start.floor.palette]
"g" = "grass" "g" = "grass"
"d" = "dirt" "d" = "dirt"
"s" = "stone" "s" = "stone"
" " = { tile = "~", fg = "#6666ff", bg = "#000066" } " " = { tile = "~", fg = "#6666ff", bg = "#000066" }
[grid] [boards.start.grid]
content = """ content = """
############################################################ ############################################################
# # # #
@@ -83,7 +87,7 @@ content = """
# Placed by its grid character `G` (uppercase-letter convention for objects) # Placed by its grid character `G` (uppercase-letter convention for objects)
# rather than x/y; the cell under it loads as Empty. # rather than x/y; the cell under it loads as Empty.
[[objects]] [[boards.start.objects]]
fg = "#aa3333" fg = "#aa3333"
bg = "#000000" bg = "#000000"
palette = "G" palette = "G"
@@ -94,7 +98,7 @@ script_name = "greeter"
# A solid object placed by x/y that paces east on its own. Demonstrates the # A solid object placed by x/y that paces east on its own. Demonstrates the
# rate-limited move(), the blocked() collision check, the Queue object, and the # rate-limited move(), the blocked() collision check, the Queue object, and the
# bump() hook (walk the player into it to trigger a bump). # bump() hook (walk the player into it to trigger a bump).
[[objects]] [[boards.start.objects]]
x = 10 x = 10
y = 12 y = 12
fg = "#33aa33" fg = "#33aa33"
@@ -102,7 +106,7 @@ bg = "#000000"
tile = 1 tile = 1
script_name = "mover" script_name = "mover"
[[objects]] [[boards.start.objects]]
palette = "M" palette = "M"
tile = 15 tile = 15
fg = "#ffdd88" fg = "#ffdd88"
@@ -112,7 +116,7 @@ name = "muffin"
script_name = "muffin" script_name = "muffin"
# Notice board — long scroll to test overflow and scrolling. # Notice board — long scroll to test overflow and scrolling.
[[objects]] [[boards.start.objects]]
palette = "B" palette = "B"
tile = 240 tile = 240
fg = "#cc9944" fg = "#cc9944"
@@ -121,7 +125,7 @@ solid = true
name = "noticeboard" name = "noticeboard"
script_name = "noticeboard" script_name = "noticeboard"
[scripts] [boards.start.scripts]
greeter = """ greeter = """
fn init() { fn init() {
log(`hello from object — player at ${Board.player_x}, ${Board.player_y}`); log(`hello from object — player at ${Board.player_x}, ${Board.player_y}`);
@@ -205,4 +209,4 @@ fn bump(id) {
" Unauthorised notices will be removed.", " Unauthorised notices will be removed.",
]); ]);
} }
""" """