Title screen, pause menu, settings dialog and savegames

- title screen (continue/new/load/settings/help) and Esc pause menu
- settings: language & sound, camera, graphics, game, rebindable keys;
  stored in localStorage and in every savegame (always applied on load)
- savegames as JSON (.dcsave): download, load via file picker or drag & drop
- autosave to localStorage every 2 minutes and when the tab is hidden/closed
- configurable wall detail, light count, interface size, game speed, hints
- audio behind a cargo feature so native tests run (cargo test --no-default-features)
- savegame round-trip test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-02 23:08:33 +01:00
1 parent fbf6f223fc
commit fb7dab3683
17 files changed
+1742 -345

No files matched your search

+21 -8
View File
@@ -1,5 +1,6 @@
// Map, tiles, generation and path finding.
use serde::{Deserialize, Serialize};
use std::cmp::Reverse;
use std::collections::BinaryHeap;
@@ -7,7 +8,7 @@ pub const MW: usize = 64;
pub const MH: usize = 64;
pub const N: usize = MW * MH;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum Kind {
Rock,
Earth,
@@ -23,24 +24,34 @@ pub enum Kind {
Gate,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum Owner {
None,
Player,
Hero,
}
#[derive(Clone, Copy)]
// Short serde names keep savegames small (the map has 4096 tiles)
#[derive(Clone, Copy, Serialize, Deserialize)]
pub struct Tile {
#[serde(rename = "k")]
pub kind: Kind,
#[serde(rename = "o")]
pub owner: Owner,
pub hp: f32, // dig resistance
pub gold: i32, // gold left (gold vein)
#[serde(rename = "h")]
pub hp: f32, // dig resistance
#[serde(rename = "g")]
pub gold: i32, // gold left (gold vein)
#[serde(rename = "m")]
pub marked: bool, // marked for digging
#[serde(rename = "r")]
pub reserved: u32, // entity id + 1 working on this tile
pub food: f32, // mushrooms in the mushroom garden
pub bed: u32, // entity id + 1 sleeping here
pub var: u8, // texture variant
#[serde(rename = "f")]
pub food: f32, // mushrooms in the mushroom garden
#[serde(rename = "b")]
pub bed: u32, // entity id + 1 sleeping here
#[serde(rename = "v")]
pub var: u8, // texture variant
}
impl Tile {
@@ -74,6 +85,7 @@ pub fn inb(x: i32, y: i32) -> bool {
pub const DIR4: [(i32, i32); 4] = [(0, -1), (1, 0), (0, 1), (-1, 0)];
pub const DIR8: [(i32, i32); 8] = [(0, -1), (1, 0), (0, 1), (-1, 0), (1, -1), (1, 1), (-1, 1), (-1, -1)];
#[derive(Serialize, Deserialize)]
pub struct Rng(pub u32);
impl Rng {
pub fn next(&mut self) -> u32 {
@@ -95,6 +107,7 @@ impl Rng {
}
}
#[derive(Serialize, Deserialize)]
pub struct Map {
pub t: Vec<Tile>,
pub core: (i32, i32), // top-left corner of the core (3x3)