From 3e3084c35d96fa39783ab9a4c20e6cc6b5405492 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Tue, 3 Nov 2026 08:19:49 +0100 Subject: [PATCH] Fix tile outlines drawn over units (miniquad only depth-tests with depth writes); Soul Core starts with a treasury ring Co-Authored-By: Claude Opus 5.5 --- DESIGN.md | 3 ++- src/game.rs | 19 +++++++++++++++++++ src/render3d.rs | 11 +++++++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 9c305cf..9f21529 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -56,7 +56,8 @@ An original dungeon management game (genre: dungeon building & defence) that run ## Game content - **Digging**: mark earth/gold → Pit Imps dig, bring gold home and claim ground -- **Rooms**: treasury, lair, mushroom garden, training hall, library +- **Rooms**: treasury, lair, mushroom garden, training hall, library (+ torture chamber, temple) +- The Soul Core starts surrounded by a **one tile wide ring of treasury** (16 tiles) - Claim the **portal** → creatures: kobold, cave spider, shadow mage, stone ogre (depending on rooms) - **Needs**: sleep, food, wages (payday); unhappy creatures leave - **Hand**: pick up / drop own units (max. 8) diff --git a/src/game.rs b/src/game.rs index 73686e8..ea6165d 100644 --- a/src/game.rs +++ b/src/game.rs @@ -386,6 +386,16 @@ impl Game { hint_t: [-1000.0; 16], }; let (cx, cy) = g.map.core; + // the soul core starts surrounded by a one tile wide ring of treasury + for y in cy - 1..=cy + 3 { + for x in cx - 1..=cx + 3 { + let t = &mut g.map.t[idx(x, y)]; + if t.kind == Kind::Floor { + t.kind = Kind::Treasury; + t.owner = Owner::Player; + } + } + } for k in 0..4 { g.spawn(EK::Worker, false, cx as f32 - 0.5, cy as f32 + k as f32 * 0.7 + 0.3, 1); } @@ -3115,4 +3125,13 @@ mod tests { g.plan_entries(); assert_eq!(g.planned_entries.len(), 2); } + + #[test] + fn core_starts_with_treasury_ring() { + let g = Game::new(21, 64, 64); + let (cx, cy) = g.map.core; + let ring = (cy - 1..=cy + 3).flat_map(|y| (cx - 1..=cx + 3).map(move |x| (x, y))).filter(|&(x, y)| g.map.t[idx(x, y)].kind == Kind::Treasury).count(); + assert_eq!(ring, 16); + assert_eq!(g.counts[0], 16); + } } diff --git a/src/render3d.rs b/src/render3d.rs index e7493e6..807e9c9 100644 --- a/src/render3d.rs +++ b/src/render3d.rs @@ -262,7 +262,9 @@ void main() { MaterialParams { pipeline_params: PipelineParams { depth_test: Comparison::LessOrEqual, - depth_write: false, + // miniquad only enables the depth *test* together with depth writes, so this + // material writes depth too; large translucent glows are therefore drawn last + depth_write: true, color_blend: Some(BlendState::new(Equation::Add, BlendFactor::Value(BlendValue::SourceAlpha), BlendFactor::OneMinusValue(BlendValue::SourceAlpha))), ..Default::default() }, @@ -906,15 +908,16 @@ impl R3d { draw_sphere(vec3(x, 0.8, z), 0.05 * fl, None, Color::new(1.0, 0.95, 0.6, 1.0)); } draw_shadows(g); - draw_landmarks_glow(g, t); - draw_towers_glow(g, t); if let Some(f) = g.flag { draw_flag(f, t); } + draw_overlay(&g.map, ov, self.wall_sub); + // translucent glows and effects last (they write depth, see glow_material) + draw_landmarks_glow(g, t); + draw_towers_glow(g, t); for f in &g.fx { draw_fx(f, t); } - draw_overlay(&g.map, ov, self.wall_sub); gl_use_default_material(); set_default_camera();