diff --git a/kiln-core/src/lib.rs b/kiln-core/src/lib.rs index df4966f..a933753 100644 --- a/kiln-core/src/lib.rs +++ b/kiln-core/src/lib.rs @@ -6,6 +6,8 @@ pub mod game; pub mod log; /// Map file loading and saving (`.toml` format). 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`]). pub mod script; pub mod glyph; diff --git a/kiln-core/src/tests/scripting.rs b/kiln-core/src/tests/scripting.rs index 24c1c6b..afdc6ac 100644 --- a/kiln-core/src/tests/scripting.rs +++ b/kiln-core/src/tests/scripting.rs @@ -104,7 +104,8 @@ fn start_map_greeter_runs_init() { // confirm the greeter read the board (interpolated message) and wrote to // itself (set_tile). Also guards the example from drifting out of sync. 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); game.run_init(); assert!( diff --git a/kiln-tui/src/main.rs b/kiln-tui/src/main.rs index 1e337eb..3ec6713 100644 --- a/kiln-tui/src/main.rs +++ b/kiln-tui/src/main.rs @@ -19,7 +19,7 @@ mod input; use kiln_core::game::GameState; use kiln_core::log::LogLine; -use kiln_core::map_file; +use kiln_core::world; use ratatui::Frame; use ratatui::crossterm::event::{ 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. - let board = match map_file::load(&path) { - Ok(board) => board, + let board = match world::load(&path) { + 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) => { eprintln!("error loading {path}: {e}"); return ExitCode::FAILURE; diff --git a/maps/start.toml b/maps/start.toml index 66d51dc..7ebb93d 100644 --- a/maps/start.toml +++ b/maps/start.toml @@ -1,10 +1,14 @@ -[map] +[world] +name = "Kiln Demo" +start = "start" + +[boards.start.map] name = "Starting Room" width = 60 height = 25 player_start = "@" # placed by the '@' grid char (convention) -[palette] +[boards.start.palette] " " = { archetype = "empty", tile = " ", fg = "#000000", bg = "#000000" } "#" = { archetype = "wall", 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 # load); a palette entry could also be a fixed glyph like # `{ tile = ".", fg = "#222", bg = "#000" }`. -[floor] +[boards.start.floor] content = """ gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg @@ -46,13 +50,13 @@ gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg """ -[floor.palette] +[boards.start.floor.palette] "g" = "grass" "d" = "dirt" "s" = "stone" " " = { tile = "~", fg = "#6666ff", bg = "#000066" } -[grid] +[boards.start.grid] content = """ ############################################################ # # @@ -83,7 +87,7 @@ content = """ # Placed by its grid character `G` (uppercase-letter convention for objects) # rather than x/y; the cell under it loads as Empty. -[[objects]] +[[boards.start.objects]] fg = "#aa3333" bg = "#000000" palette = "G" @@ -94,7 +98,7 @@ script_name = "greeter" # 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 # bump() hook (walk the player into it to trigger a bump). -[[objects]] +[[boards.start.objects]] x = 10 y = 12 fg = "#33aa33" @@ -102,7 +106,7 @@ bg = "#000000" tile = 1 script_name = "mover" -[[objects]] +[[boards.start.objects]] palette = "M" tile = 15 fg = "#ffdd88" @@ -112,7 +116,7 @@ name = "muffin" script_name = "muffin" # Notice board — long scroll to test overflow and scrolling. -[[objects]] +[[boards.start.objects]] palette = "B" tile = 240 fg = "#cc9944" @@ -121,7 +125,7 @@ solid = true name = "noticeboard" script_name = "noticeboard" -[scripts] +[boards.start.scripts] greeter = """ fn init() { log(`hello from object — player at ${Board.player_x}, ${Board.player_y}`); @@ -205,4 +209,4 @@ fn bump(id) { " Unauthorised notices will be removed.", ]); } -""" \ No newline at end of file +"""