diff --git a/CLAUDE.md b/CLAUDE.md index 23f90eb..1dff940 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -196,7 +196,7 @@ palette = { "g" = { kind = "floor", generator = "grass" } } [[boards.room1.layers]] sparse = [ { x = 5, y = 3, ch = "C" }, { x = 9, y = 7, ch = "C" } ] # two chests -palette = { " " = { kind = "empty" }, "C" = { kind = "object", script_name = "chest" } } +palette = { "C" = { kind = "object", script_name = "chest" } } # spaces are implicitly empty ``` ```toml @@ -237,8 +237,8 @@ content = """ "d" = { kind = "floor", generator = "dirt" } "." = { kind = "floor", tile = ".", fg = "#222", bg = "#000" } # fixed floor glyph -# Layer 1: terrain, the player, objects and portals. A space here resolves to -# kind="empty" (transparent), so the floor below shows through. +# Layer 1: terrain, the player, objects and portals. A space is always a +# transparent empty cell, so the floor below shows through. [[boards.room1.layers]] content = """ ############################################################ @@ -246,7 +246,7 @@ content = """ ############################################################ """ [boards.room1.layers.palette] -" " = { kind = "empty" } # transparent +# A space is always a transparent empty cell — it is never a palette key. "#" = { kind = "wall", tile = 35, fg = "#808080", bg = "#606060" } "o" = { kind = "crate", tile = 254, fg = "#aaaaaa", bg = "#000000" } # solid + pushable (any dir) "-" = { kind = "hcrate" } # pushable east/west only diff --git a/kiln-core/src/layer.rs b/kiln-core/src/layer.rs index 5bb3377..4e609ed 100644 --- a/kiln-core/src/layer.rs +++ b/kiln-core/src/layer.rs @@ -43,6 +43,9 @@ pub(crate) struct Layer { /// layer of identical floor). /// - `sparse` — a list of `{ x, y, ch }` cells over an otherwise all-spaces grid /// (handy for a layer holding just a few objects). +/// +/// A space (`' '`) is always a transparent empty cell and is never a palette key +/// (any `" "` entry in `palette` is ignored). #[derive(Deserialize, Serialize)] pub(crate) struct LayerData { /// Multi-line grid string; one char per cell, looked up in `palette`. @@ -341,12 +344,14 @@ pub(crate) fn build_layer( errors: &mut Vec, ) -> Result<(Layer, Vec), String> { // Resolve each palette entry once (per-cell work like generators happens below). + // Space is always a transparent empty cell, so it is never a palette key — any + // `" "` entry is ignored. let resolved: HashMap = data .palette .iter() - .map(|(key, entry)| { + .filter_map(|(key, entry)| { let ch = key.chars().next().unwrap_or(' '); - (ch, resolve_entry(ch, entry, errors)) + (ch != ' ').then(|| (ch, resolve_entry(ch, entry, errors))) }) .collect(); @@ -358,6 +363,11 @@ pub(crate) fn build_layer( let mut placements: Vec = Vec::new(); for (y, row) in grid.iter().enumerate() { for (x, &ch) in row.iter().enumerate() { + // A space is always a transparent empty cell, palette or not. + if ch == ' ' { + cells.push((Glyph::transparent(), Archetype::Empty)); + continue; + } match resolved.get(&ch) { Some(Resolved::Cell(g, a)) => cells.push((*g, *a)), Some(Resolved::FloorGen(g)) => cells.push((g.generate(rng), Archetype::Empty)), diff --git a/maps/start.toml b/maps/start.toml index d422a1f..28cb682 100644 --- a/maps/start.toml +++ b/maps/start.toml @@ -190,10 +190,10 @@ gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg gggggggggggggggggggggggggsgggggggggggggggggggggggggggggggggg -gggggg gggggggggggggsggggdddddddddddddddddddddggggggggg -gggggg gggggggggggggsggggdddddddddddddddddddddggggggggg -gggggg gggggggggggggsggggdddddddddddddddddddddggggggggg -gggggg gggggggggggggsggggdddddddddddddddddddddggggggggg +ggggggwwwwwwgggggggggggggsggggdddddddddddddddddddddggggggggg +ggggggwwwwwwgggggggggggggsggggdddddddddddddddddddddggggggggg +ggggggwwwwwwgggggggggggggsggggdddddddddddddddddddddggggggggg +ggggggwwwwwwgggggggggggggsggggdddddddddddddddddddddggggggggg gggggggggggggggggggggggggsggggdddddddddddddddddddddggggggggg gggggggggggggggggggggggggsggggdddddddddddddddddddddggggggggg gggggggggggggggggggggggggsggggdddddddddddddddddddddggggggggg @@ -206,10 +206,10 @@ gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg "g" = { kind = "floor", generator = "grass" } "d" = { kind = "floor", generator = "dirt" } "s" = { kind = "floor", generator = "stone" } -" " = { kind = "floor", tile = "~", fg = "#6666ff", bg = "#000066" } +"w" = { kind = "floor", tile = "~", fg = "#6666ff", bg = "#000066" } -# Layer 1: terrain, the player, objects and the portal. A space here is -# transparent (kind = "empty"), so the floor below shows through. +# Layer 1: terrain, the player, objects and the portal. A space is always a +# transparent empty cell, so the floor below shows through. [[boards.start.layers]] content = """ ############################################################ @@ -239,7 +239,6 @@ content = """ ############################################################ """ [boards.start.layers.palette] -" " = { kind = "empty" } "#" = { kind = "wall", tile = "#", fg = "#808080", bg = "#606060" } "+" = { kind = "banana", tile = "#", fg = "#808080", bg = "#606060" } # unknown kind -> ErrorBlock demo "o" = { kind = "crate", tile = 254, fg = "#aaaaaa", bg = "#000000" } @@ -257,35 +256,8 @@ content = """ # Layer 2: a purely decorative, non-solid object drawn *above* the solid crate # beneath it — only possible because draw order follows layer order. [[boards.start.layers]] -content = """ - - - - - - - - - - - - - * - - - - - - - - - - - - -""" +sparse = [{ x = 30, y = 12, ch = "*" }] [boards.start.layers.palette] -" " = { kind = "empty" } "*" = { kind = "object", tile = 15, fg = "#ffff66", bg = "#000000", solid = false } [boards.house.map] @@ -295,33 +267,7 @@ height = 25 # Layer 0: a single fixed floor glyph across the whole board. [[boards.house.layers]] -content = """ -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -""" +fill = "f" [boards.house.layers.palette] "f" = { kind = "floor", tile = 176, fg = "#888888", bg = "#444444" } @@ -355,7 +301,6 @@ content = """ ############################################################ """ [boards.house.layers.palette] -" " = { kind = "empty" } "#" = { kind = "wall", tile = 178, fg = "#888888", bg = "#555555" } "@" = { kind = "player" } "1" = { kind = "portal", name = "from_start", target_map = "start", target_entry = "to_house" }