multi-board files
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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!(
|
||||||
|
|||||||
@@ -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
@@ -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.",
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user