From 76f37d4c1f59717fab5b5ab603ae9ba56bc7942a Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 13:53:17 +0100 Subject: [PATCH 01/16] Add subcommand boilerplate --- src/server/config/commands.rs | 11 +++++++++++ src/server/config/mod.rs | 1 + src/server/main.rs | 34 ++++++++++++++++++++++++++-------- src/server/prelude.rs | 2 ++ 4 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 src/server/config/commands.rs create mode 100644 src/server/config/mod.rs diff --git a/src/server/config/commands.rs b/src/server/config/commands.rs new file mode 100644 index 00000000..3dee4758 --- /dev/null +++ b/src/server/config/commands.rs @@ -0,0 +1,11 @@ +use clap::Subcommand; + +#[derive(Debug, Subcommand)] +pub enum ConfigCommands { + #[command(about = "Initialize config file with default settings")] + Init, + #[command(about = "Show currently applied configuration")] + Show, + #[command(about = "Show defaults")] + Defaults, +} diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs new file mode 100644 index 00000000..82b6da3c --- /dev/null +++ b/src/server/config/mod.rs @@ -0,0 +1 @@ +pub mod commands; diff --git a/src/server/main.rs b/src/server/main.rs index bdb0e22e..5aaf1eee 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -1,11 +1,12 @@ pub mod chat; +pub mod config; pub mod networking; pub mod player; pub mod prelude; pub mod terrain; use bevy::app::TerminalCtrlCHandlerPlugin; -use clap::Parser; +use clap::{Parser, Subcommand}; #[cfg(feature = "egui_layer")] use bevy::DefaultPlugins; @@ -22,7 +23,15 @@ use crate::prelude::*; #[command(long_about = None)] struct Cli { #[command(subcommand)] - world_commands: terrain_commands::WorldCommands, + commands: MainCommands, +} + +#[derive(Debug, Subcommand)] +enum MainCommands { + #[command(flatten)] + World(terrain_commands::WorldCommands), + #[command(subcommand, about = "Actions regarding server configuration")] + Config(config_commands::ConfigCommands), } fn main() { @@ -44,13 +53,22 @@ fn main() { } let args = Cli::parse(); - match terrain::TerrainPlugin::from_command(args.world_commands) { - Ok(terrain_plugin) => app.add_plugins(terrain_plugin), - Err(error) => { - eprintln!("Error: {}", error); - return; + match args.commands { + MainCommands::World(world_commands) => { + match terrain::TerrainPlugin::from_command(world_commands) { + Ok(terrain_plugin) => app.add_plugins(terrain_plugin), + Err(error) => { + eprintln!("Error: {}", error); + return; + } + }; } - }; + MainCommands::Config(config_commands) => match config_commands { + config_commands::ConfigCommands::Init => todo!("Init"), + config_commands::ConfigCommands::Show => todo!("Show"), + config_commands::ConfigCommands::Defaults => todo!("Defaults"), + }, + } app.add_plugins(player::PlayerPlugin); app.add_plugins(networking::NetworkingPlugin); diff --git a/src/server/prelude.rs b/src/server/prelude.rs index dad65071..66b62f15 100644 --- a/src/server/prelude.rs +++ b/src/server/prelude.rs @@ -50,3 +50,5 @@ pub use crate::terrain::util as terrain_util; pub use crate::chat::events as chat_events; pub use crate::chat::resources as chat_resources; pub use crate::chat::systems as chat_systems; + +pub use crate::config::commands as config_commands; From 6da5f448425fde42213e43d8317a51b8a7371261 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 14:45:17 +0100 Subject: [PATCH 02/16] Implement default CONFIG for world persistence --- src/server/config/mod.rs | 31 +++++++++++++++++++++++++++++++ src/server/terrain/persistence.rs | 14 ++++++-------- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index 82b6da3c..0c3ac16b 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -1 +1,32 @@ +use std::sync::LazyLock; + pub mod commands; + +pub static CONFIG: LazyLock = LazyLock::new(|| { + // TODO: read from file + Config::default() +}); + +use serde::Deserialize; + +#[derive(Deserialize, Default)] +pub struct Config { + pub world: WorldConfig, +} + +#[derive(Deserialize)] +pub struct WorldConfig { + pub backups_dir: String, + pub worlds_dir: String, + pub world_extension: String, +} + +impl Default for WorldConfig { + fn default() -> Self { + Self { + backups_dir: String::from("backups/"), + worlds_dir: String::from("worlds/"), + world_extension: String::from(".rsmcw"), + } + } +} diff --git a/src/server/terrain/persistence.rs b/src/server/terrain/persistence.rs index d79cf14b..10a9eb07 100644 --- a/src/server/terrain/persistence.rs +++ b/src/server/terrain/persistence.rs @@ -10,10 +10,6 @@ use std::{ use crate::{prelude::*, terrain::resources::Generator}; -const BACKUPS_DIR: &str = "backups/"; -const WORLDS_DIR: &str = "worlds/"; -const WORLD_EXTENSION: &str = ".rsmcw"; - #[derive(Serialize, Deserialize, Default)] pub struct WorldSave { pub name: String, @@ -28,6 +24,8 @@ impl Display for WorldSave { } mod path_helpers { + use crate::config::CONFIG; + use super::*; impl WorldSave { @@ -41,8 +39,8 @@ mod path_helpers { } pub fn path_for_world(world_name: &str) -> PathBuf { - let file_name = format!("{}{}", world_name, WORLD_EXTENSION); - PathBuf::from(WORLDS_DIR).join(file_name) + let file_name = format!("{}{}", world_name, CONFIG.world.world_extension); + PathBuf::from(&CONFIG.world.worlds_dir).join(file_name) } pub fn path_for_world_backup(world_name: &str, timestamp: DateTime) -> PathBuf { @@ -50,9 +48,9 @@ mod path_helpers { "{}_{}{}.bak", world_name, timestamp.format("%Y%m%d%H%M%S%3f"), - WORLD_EXTENSION, + CONFIG.world.world_extension, ); - PathBuf::from(BACKUPS_DIR).join(file_name) + PathBuf::from(&CONFIG.world.backups_dir).join(file_name) } } From 696aa670fcf6d8ddea46f86a7d55699361fbb3ed Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 14:59:24 +0100 Subject: [PATCH 03/16] Implement config file loading --- src/server/config/mod.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index 0c3ac16b..3c762517 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -3,8 +3,29 @@ use std::sync::LazyLock; pub mod commands; pub static CONFIG: LazyLock = LazyLock::new(|| { - // TODO: read from file - Config::default() + #[cfg(test)] + { + Config::default() + } + + #[cfg(not(test))] + { + use std::path::PathBuf; + const CONFIG_PATH: &str = "server.toml"; + + match std::fs::read_to_string(PathBuf::from(CONFIG_PATH)) { + Ok(string) => match toml::from_str(&string) { + Ok(config) => config, + Err(_) => panic!("Could not parse config file at '{CONFIG_PATH}'"), + }, + Err(_) => { + eprintln!( + "Could not read config file at '{CONFIG_PATH}', proceeding with defaults" + ); + Config::default() + } + } + } }); use serde::Deserialize; From 518ec4766236dfa9f663730fcb75808049e32084 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 15:50:38 +0100 Subject: [PATCH 04/16] Implement config commands --- .gitignore | 4 ++++ Cargo.lock | 31 ++++++++++++++++++++++++++ Cargo.toml | 1 + src/server/config/mod.rs | 8 ++++--- src/server/main.rs | 48 +++++++++++++++++++++++++++++++++++----- 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 832ccc66..bdf8d011 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,9 @@ tree-sitter-rust *-E +# default world locations backups/ worlds/ + +# local config files +server.toml diff --git a/Cargo.lock b/Cargo.lock index 207753ad..d0ffb3b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5363,6 +5363,7 @@ dependencies = [ "renet_visualizer", "serde", "serde-big-array", + "toml", ] [[package]] @@ -5587,6 +5588,15 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + [[package]] name = "servo_arc" version = "0.4.3" @@ -5966,6 +5976,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "toml" +version = "0.9.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + [[package]] name = "toml_datetime" version = "0.7.5+spec-1.1.0" @@ -5996,6 +6021,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_writer" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" + [[package]] name = "tracing" version = "0.1.44" diff --git a/Cargo.toml b/Cargo.toml index 043012ef..9be615df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ serde-big-array = "0.5.1" chrono = "0.4.43" rayon = "1.10.0" clap = { version = "4.5.54", features = ["derive"] } +toml = "0.9.11" [patch.crates-io] # TODO: Remove patch once egui requirement is more flexible. diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index 3c762517..dfbb822d 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -2,6 +2,8 @@ use std::sync::LazyLock; pub mod commands; +pub const CONFIG_PATH: &str = "server.toml"; + pub static CONFIG: LazyLock = LazyLock::new(|| { #[cfg(test)] { @@ -11,7 +13,6 @@ pub static CONFIG: LazyLock = LazyLock::new(|| { #[cfg(not(test))] { use std::path::PathBuf; - const CONFIG_PATH: &str = "server.toml"; match std::fs::read_to_string(PathBuf::from(CONFIG_PATH)) { Ok(string) => match toml::from_str(&string) { @@ -29,13 +30,14 @@ pub static CONFIG: LazyLock = LazyLock::new(|| { }); use serde::Deserialize; +use serde::Serialize; -#[derive(Deserialize, Default)] +#[derive(Serialize, Deserialize, Default)] pub struct Config { pub world: WorldConfig, } -#[derive(Deserialize)] +#[derive(Serialize, Deserialize)] pub struct WorldConfig { pub backups_dir: String, pub worlds_dir: String, diff --git a/src/server/main.rs b/src/server/main.rs index 5aaf1eee..684860ba 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -5,6 +5,8 @@ pub mod player; pub mod prelude; pub mod terrain; +use std::path::Path; + use bevy::app::TerminalCtrlCHandlerPlugin; use clap::{Parser, Subcommand}; @@ -16,7 +18,10 @@ pub mod gui; #[cfg(not(feature = "egui_layer"))] use bevy::log::LogPlugin; -use crate::prelude::*; +use crate::{ + config::{Config, CONFIG, CONFIG_PATH}, + prelude::*, +}; #[derive(Debug, Parser)] #[command(version)] @@ -63,11 +68,42 @@ fn main() { } }; } - MainCommands::Config(config_commands) => match config_commands { - config_commands::ConfigCommands::Init => todo!("Init"), - config_commands::ConfigCommands::Show => todo!("Show"), - config_commands::ConfigCommands::Defaults => todo!("Defaults"), - }, + MainCommands::Config(config_commands) => { + match config_commands { + config_commands::ConfigCommands::Init => { + if Path::new(&CONFIG_PATH).is_file() { + eprintln!("Config file is already initialized at '{CONFIG_PATH}'."); + eprintln!("If you want to reinitialize it with defaults, remove it:"); + eprintln!("rm '{CONFIG_PATH}'"); + } else { + let config = Config::default(); + let config_str = toml::to_string(&config) + .expect("Default config should be serializable"); + + if let Err(err) = std::fs::write(CONFIG_PATH, config_str) { + eprintln!("Error writing to file: {err}"); + } else { + println!("Initialized config file '{CONFIG_PATH}'"); + } + } + } + config_commands::ConfigCommands::Show => { + println!( + "{}", + toml::to_string(&*CONFIG) + .expect("Loaded config should always be serializable") + ); + } + config_commands::ConfigCommands::Defaults => { + println!( + "{}", + toml::to_string(&Config::default()) + .expect("Loaded config should always be serializable") + ); + } + } + return; + } } app.add_plugins(player::PlayerPlugin); From 44c0509dabb9c9816a16d5d87e5d5474fd526e75 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 16:02:14 +0100 Subject: [PATCH 05/16] Move commands --- src/server/config/commands.rs | 39 +++++++++++++++++++++++++++++ src/server/main.rs | 46 +++-------------------------------- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/server/config/commands.rs b/src/server/config/commands.rs index 3dee4758..bb3c74b2 100644 --- a/src/server/config/commands.rs +++ b/src/server/config/commands.rs @@ -1,5 +1,9 @@ +use std::path::Path; + use clap::Subcommand; +use crate::config::{Config, CONFIG, CONFIG_PATH}; + #[derive(Debug, Subcommand)] pub enum ConfigCommands { #[command(about = "Initialize config file with default settings")] @@ -9,3 +13,38 @@ pub enum ConfigCommands { #[command(about = "Show defaults")] Defaults, } + +pub fn perform_command(commands: &ConfigCommands) { + match commands { + ConfigCommands::Init => { + if Path::new(&CONFIG_PATH).is_file() { + eprintln!("Config file is already initialized at '{CONFIG_PATH}'."); + eprintln!("If you want to reinitialize it with defaults, remove it:"); + eprintln!("rm '{CONFIG_PATH}'"); + } else { + let config = Config::default(); + let config_str = + toml::to_string(&config).expect("Default config should be serializable"); + + if let Err(err) = std::fs::write(CONFIG_PATH, config_str) { + eprintln!("Error writing to file: {err}"); + } else { + println!("Initialized config file '{CONFIG_PATH}'"); + } + } + } + ConfigCommands::Show => { + println!( + "{}", + toml::to_string(&*CONFIG).expect("Loaded config should always be serializable") + ); + } + ConfigCommands::Defaults => { + println!( + "{}", + toml::to_string(&Config::default()) + .expect("Loaded config should always be serializable") + ); + } + } +} diff --git a/src/server/main.rs b/src/server/main.rs index 684860ba..4a99f92c 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -5,8 +5,6 @@ pub mod player; pub mod prelude; pub mod terrain; -use std::path::Path; - use bevy::app::TerminalCtrlCHandlerPlugin; use clap::{Parser, Subcommand}; @@ -18,10 +16,7 @@ pub mod gui; #[cfg(not(feature = "egui_layer"))] use bevy::log::LogPlugin; -use crate::{ - config::{Config, CONFIG, CONFIG_PATH}, - prelude::*, -}; +use crate::prelude::*; #[derive(Debug, Parser)] #[command(version)] @@ -62,46 +57,11 @@ fn main() { MainCommands::World(world_commands) => { match terrain::TerrainPlugin::from_command(world_commands) { Ok(terrain_plugin) => app.add_plugins(terrain_plugin), - Err(error) => { - eprintln!("Error: {}", error); - return; - } + Err(error) => return eprintln!("Error: {}", error), }; } MainCommands::Config(config_commands) => { - match config_commands { - config_commands::ConfigCommands::Init => { - if Path::new(&CONFIG_PATH).is_file() { - eprintln!("Config file is already initialized at '{CONFIG_PATH}'."); - eprintln!("If you want to reinitialize it with defaults, remove it:"); - eprintln!("rm '{CONFIG_PATH}'"); - } else { - let config = Config::default(); - let config_str = toml::to_string(&config) - .expect("Default config should be serializable"); - - if let Err(err) = std::fs::write(CONFIG_PATH, config_str) { - eprintln!("Error writing to file: {err}"); - } else { - println!("Initialized config file '{CONFIG_PATH}'"); - } - } - } - config_commands::ConfigCommands::Show => { - println!( - "{}", - toml::to_string(&*CONFIG) - .expect("Loaded config should always be serializable") - ); - } - config_commands::ConfigCommands::Defaults => { - println!( - "{}", - toml::to_string(&Config::default()) - .expect("Loaded config should always be serializable") - ); - } - } + config_commands::perform_command(&config_commands); return; } } From a21e97f080d4c69b28b7b9214c8d99b022e4c935 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 16:05:47 +0100 Subject: [PATCH 06/16] Update imports --- src/server/config/commands.rs | 5 +---- src/server/main.rs | 1 - src/server/prelude.rs | 2 ++ src/server/terrain/commands.rs | 5 ++--- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/server/config/commands.rs b/src/server/config/commands.rs index bb3c74b2..7ace5f99 100644 --- a/src/server/config/commands.rs +++ b/src/server/config/commands.rs @@ -1,9 +1,6 @@ +use crate::prelude::*; use std::path::Path; -use clap::Subcommand; - -use crate::config::{Config, CONFIG, CONFIG_PATH}; - #[derive(Debug, Subcommand)] pub enum ConfigCommands { #[command(about = "Initialize config file with default settings")] diff --git a/src/server/main.rs b/src/server/main.rs index 4a99f92c..5ac4be70 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -6,7 +6,6 @@ pub mod prelude; pub mod terrain; use bevy::app::TerminalCtrlCHandlerPlugin; -use clap::{Parser, Subcommand}; #[cfg(feature = "egui_layer")] use bevy::DefaultPlugins; diff --git a/src/server/prelude.rs b/src/server/prelude.rs index 66b62f15..45890417 100644 --- a/src/server/prelude.rs +++ b/src/server/prelude.rs @@ -29,6 +29,7 @@ pub use rayon::iter::IntoParallelIterator; pub use rayon::iter::IntoParallelRefMutIterator; pub use rayon::iter::ParallelIterator; +pub use clap::{Parser, Subcommand}; pub use lib::*; pub use noise::NoiseFn; pub use noise::Perlin; @@ -52,3 +53,4 @@ pub use crate::chat::resources as chat_resources; pub use crate::chat::systems as chat_systems; pub use crate::config::commands as config_commands; +pub use crate::config::{Config, CONFIG, CONFIG_PATH}; diff --git a/src/server/terrain/commands.rs b/src/server/terrain/commands.rs index ee072bfe..e946de10 100644 --- a/src/server/terrain/commands.rs +++ b/src/server/terrain/commands.rs @@ -1,7 +1,6 @@ -use clap::Subcommand; -use rand::RngCore; - +use crate::prelude::*; use crate::terrain::TerrainPlugin; +use rand::RngCore; #[derive(Debug, Subcommand)] pub enum WorldCommands { From 8130511294a97774a18ced28e3e548651ce3f5b4 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 17:10:19 +0100 Subject: [PATCH 07/16] Add world timers to config --- src/server/config/mod.rs | 6 ++++++ src/server/terrain/resources.rs | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index dfbb822d..25340d8f 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -33,15 +33,19 @@ use serde::Deserialize; use serde::Serialize; #[derive(Serialize, Deserialize, Default)] +#[serde(default)] pub struct Config { pub world: WorldConfig, } #[derive(Serialize, Deserialize)] +#[serde(default)] pub struct WorldConfig { pub backups_dir: String, pub worlds_dir: String, pub world_extension: String, + pub world_save_interval_seconds: i64, + pub world_backup_interval_seconds: i64, } impl Default for WorldConfig { @@ -50,6 +54,8 @@ impl Default for WorldConfig { backups_dir: String::from("backups/"), worlds_dir: String::from("worlds/"), world_extension: String::from(".rsmcw"), + world_save_interval_seconds: 30, + world_backup_interval_seconds: 180, } } } diff --git a/src/server/terrain/resources.rs b/src/server/terrain/resources.rs index 9f7591a1..64d88b1f 100644 --- a/src/server/terrain/resources.rs +++ b/src/server/terrain/resources.rs @@ -1,7 +1,7 @@ -use std::collections::VecDeque; - use crate::prelude::*; +use std::collections::VecDeque; + use chrono::{DateTime, TimeDelta, Utc}; use rand::distr::{Alphanumeric, SampleString}; use serde::{Deserialize, Serialize}; @@ -75,7 +75,7 @@ impl WorldBackupTimer { impl Default for WorldBackupTimer { fn default() -> Self { - Self(SaveTimer::new(TimeDelta::seconds(180))) + Self(SaveTimer::new(TimeDelta::seconds(CONFIG.world.world_backup_interval_seconds))) } } @@ -94,7 +94,7 @@ impl WorldSaveTimer { impl Default for WorldSaveTimer { fn default() -> Self { - Self(SaveTimer::new(TimeDelta::seconds(30))) + Self(SaveTimer::new(TimeDelta::seconds(CONFIG.world.world_save_interval_seconds))) } } From c840293e5f9f62a286848f6916eae42c359c4ee5 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 17:31:21 +0100 Subject: [PATCH 08/16] Move world config --- src/server/config/mod.rs | 27 +---- src/server/prelude.rs | 1 + src/server/terrain/config.rs | 149 +++++++++++++++++++++++++ src/server/terrain/mod.rs | 1 + src/server/terrain/resources.rs | 159 ++++----------------------- src/server/terrain/systems.rs | 4 +- src/server/terrain/util/generator.rs | 7 +- 7 files changed, 181 insertions(+), 167 deletions(-) create mode 100644 src/server/terrain/config.rs diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index 25340d8f..18ad6bfe 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -32,30 +32,11 @@ pub static CONFIG: LazyLock = LazyLock::new(|| { use serde::Deserialize; use serde::Serialize; +use crate::prelude::*; + #[derive(Serialize, Deserialize, Default)] #[serde(default)] pub struct Config { - pub world: WorldConfig, -} - -#[derive(Serialize, Deserialize)] -#[serde(default)] -pub struct WorldConfig { - pub backups_dir: String, - pub worlds_dir: String, - pub world_extension: String, - pub world_save_interval_seconds: i64, - pub world_backup_interval_seconds: i64, -} - -impl Default for WorldConfig { - fn default() -> Self { - Self { - backups_dir: String::from("backups/"), - worlds_dir: String::from("worlds/"), - world_extension: String::from(".rsmcw"), - world_save_interval_seconds: 30, - world_backup_interval_seconds: 180, - } - } + pub world: terrain_config::WorldConfig, + pub generator: terrain_config::TerrainGeneratorParams, } diff --git a/src/server/prelude.rs b/src/server/prelude.rs index 45890417..e864ca83 100644 --- a/src/server/prelude.rs +++ b/src/server/prelude.rs @@ -43,6 +43,7 @@ pub use crate::player::resources as player_resources; pub use crate::player::systems as player_systems; pub use crate::terrain::commands as terrain_commands; +pub use crate::terrain::config as terrain_config; pub use crate::terrain::events as terrain_events; pub use crate::terrain::resources as terrain_resources; pub use crate::terrain::systems as terrain_systems; diff --git a/src/server/terrain/config.rs b/src/server/terrain/config.rs new file mode 100644 index 00000000..6dd687f8 --- /dev/null +++ b/src/server/terrain/config.rs @@ -0,0 +1,149 @@ +use crate::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +#[serde(default)] +pub struct WorldConfig { + pub backups_dir: String, + pub worlds_dir: String, + pub world_extension: String, + pub world_save_interval_seconds: i64, + pub world_backup_interval_seconds: i64, +} + +impl Default for WorldConfig { + fn default() -> Self { + Self { + backups_dir: String::from("backups/"), + worlds_dir: String::from("worlds/"), + world_extension: String::from(".rsmcw"), + world_save_interval_seconds: 30, + world_backup_interval_seconds: 180, + } + } +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct HeightParams { + pub noise: NoiseFunctionParams, + pub splines: Vec, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct DensityParams { + pub noise: NoiseFunctionParams, + pub squash_factor: f64, + pub height_offset: f64, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct CaveParams { + pub noise: NoiseFunctionParams, + pub base_value: f64, + pub threshold: f64, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct HeightAdjustParams { + pub noise: NoiseFunctionParams, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct GrassParams { + pub frequency: u32, +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub struct NoiseFunctionParams { + pub octaves: u32, + pub height: f64, + pub lacuranity: f64, + pub frequency: f64, + pub amplitude: f64, + pub persistence: f64, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct TreeParams { + pub spawn_attempts_per_chunk: u32, + pub min_stump_height: u32, + pub max_stump_height: u32, + pub min_bush_radius: u32, + pub max_bush_radius: u32, +} + +#[derive(Clone, Serialize, Deserialize)] +pub struct TerrainGeneratorParams { + pub height: HeightParams, + pub height_adjust: HeightAdjustParams, + pub density: DensityParams, + pub cave: CaveParams, + pub tree: TreeParams, + pub grass: GrassParams, +} + +impl Default for TerrainGeneratorParams { + fn default() -> Self { + Self { + height: HeightParams { + splines: vec![ + Vec2::new(-1.0, 4.0), + Vec2::new(0.0, 0.0), + Vec2::new(0.0, 0.0), + Vec2::new(0.05, 20.0), + Vec2::new(1.0, 35.0), + ], + noise: NoiseFunctionParams { + octaves: 4, + height: 0.0, + lacuranity: 2.0, + frequency: 1.0 / 300.0, + amplitude: 30.0, + persistence: 0.5, + }, + }, + height_adjust: HeightAdjustParams { + noise: NoiseFunctionParams { + octaves: 4, + height: 0.0, + lacuranity: 2.0, + frequency: 1.0 / 120.0, + amplitude: 30.0, + persistence: 0.5, + }, + }, + density: DensityParams { + squash_factor: 1.0 / 100.0, + height_offset: -20.0, + noise: NoiseFunctionParams { + octaves: 4, + height: 0.0, + lacuranity: 2.0, + frequency: 1.0 / 60.0, + amplitude: 10.0, + persistence: 0.5, + }, + }, + cave: CaveParams { + noise: NoiseFunctionParams { + octaves: 2, + height: 0.0, + lacuranity: 0.03, + frequency: 1.0 / 20.0, + amplitude: 30.0, + persistence: 0.59, + }, + base_value: 0.0, + threshold: 0.25, + }, + tree: TreeParams { + spawn_attempts_per_chunk: 500, + min_stump_height: 2, + max_stump_height: 20, + min_bush_radius: 3, + max_bush_radius: 5, + }, + grass: GrassParams { frequency: 10 }, + } + } +} diff --git a/src/server/terrain/mod.rs b/src/server/terrain/mod.rs index 9f0b0e89..a18156e0 100644 --- a/src/server/terrain/mod.rs +++ b/src/server/terrain/mod.rs @@ -3,6 +3,7 @@ use std::io::ErrorKind::{NotFound, PermissionDenied}; use crate::{prelude::*, terrain::persistence::WorldSave}; pub mod commands; +pub mod config; pub mod events; pub mod resources; pub mod systems; diff --git a/src/server/terrain/resources.rs b/src/server/terrain/resources.rs index 64d88b1f..1455bcb6 100644 --- a/src/server/terrain/resources.rs +++ b/src/server/terrain/resources.rs @@ -1,4 +1,4 @@ -use crate::prelude::*; +use crate::{prelude::*, terrain::config::TerrainGeneratorParams}; use std::collections::VecDeque; @@ -75,7 +75,9 @@ impl WorldBackupTimer { impl Default for WorldBackupTimer { fn default() -> Self { - Self(SaveTimer::new(TimeDelta::seconds(CONFIG.world.world_backup_interval_seconds))) + Self(SaveTimer::new(TimeDelta::seconds( + CONFIG.world.world_backup_interval_seconds, + ))) } } @@ -94,7 +96,9 @@ impl WorldSaveTimer { impl Default for WorldSaveTimer { fn default() -> Self { - Self(SaveTimer::new(TimeDelta::seconds(CONFIG.world.world_save_interval_seconds))) + Self(SaveTimer::new(TimeDelta::seconds( + CONFIG.world.world_save_interval_seconds, + ))) } } @@ -123,6 +127,18 @@ pub struct Generator { pub params: TerrainGeneratorParams, } +impl Default for Generator { + fn default() -> Self { + Self::new(0) + } +} + +impl Generator { + pub fn with_seed(seed: u32) -> Self { + Self::new(seed) + } +} + #[derive(Clone)] pub struct Noise { pub seed: u32, @@ -170,143 +186,6 @@ impl<'de> Deserialize<'de> for Noise { } } -#[derive(Clone, Serialize, Deserialize)] -pub struct HeightParams { - pub noise: NoiseFunctionParams, - pub splines: Vec, -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct DensityParams { - pub noise: NoiseFunctionParams, - pub squash_factor: f64, - pub height_offset: f64, -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct CaveParams { - pub noise: NoiseFunctionParams, - pub base_value: f64, - pub threshold: f64, -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct HeightAdjustParams { - pub noise: NoiseFunctionParams, -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct GrassParams { - pub frequency: u32, -} - -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub struct NoiseFunctionParams { - pub octaves: u32, - pub height: f64, - pub lacuranity: f64, - pub frequency: f64, - pub amplitude: f64, - pub persistence: f64, -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct TreeParams { - pub spawn_attempts_per_chunk: u32, - pub min_stump_height: u32, - pub max_stump_height: u32, - pub min_bush_radius: u32, - pub max_bush_radius: u32, -} - -impl Default for Generator { - fn default() -> Self { - Self::new(0) - } -} - -impl Generator { - pub fn with_seed(seed: u32) -> Self { - Self::new(seed) - } -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct TerrainGeneratorParams { - pub height: HeightParams, - pub height_adjust: HeightAdjustParams, - pub density: DensityParams, - pub cave: CaveParams, - pub tree: TreeParams, - pub grass: GrassParams, -} - -impl Default for TerrainGeneratorParams { - fn default() -> Self { - Self { - height: HeightParams { - splines: vec![ - Vec2::new(-1.0, 4.0), - Vec2::new(0.0, 0.0), - Vec2::new(0.0, 0.0), - Vec2::new(0.05, 20.0), - Vec2::new(1.0, 35.0), - ], - noise: NoiseFunctionParams { - octaves: 4, - height: 0.0, - lacuranity: 2.0, - frequency: 1.0 / 300.0, - amplitude: 30.0, - persistence: 0.5, - }, - }, - height_adjust: HeightAdjustParams { - noise: NoiseFunctionParams { - octaves: 4, - height: 0.0, - lacuranity: 2.0, - frequency: 1.0 / 120.0, - amplitude: 30.0, - persistence: 0.5, - }, - }, - density: DensityParams { - squash_factor: 1.0 / 100.0, - height_offset: -20.0, - noise: NoiseFunctionParams { - octaves: 4, - height: 0.0, - lacuranity: 2.0, - frequency: 1.0 / 60.0, - amplitude: 10.0, - persistence: 0.5, - }, - }, - cave: CaveParams { - noise: NoiseFunctionParams { - octaves: 2, - height: 0.0, - lacuranity: 0.03, - frequency: 1.0 / 20.0, - amplitude: 30.0, - persistence: 0.59, - }, - base_value: 0.0, - threshold: 0.25, - }, - tree: TreeParams { - spawn_attempts_per_chunk: 500, - min_stump_height: 2, - max_stump_height: 20, - min_bush_radius: 3, - max_bush_radius: 5, - }, - grass: GrassParams { frequency: 10 }, - } - } -} - #[cfg(feature = "generator_visualizer")] pub use visualizer::*; diff --git a/src/server/terrain/systems.rs b/src/server/terrain/systems.rs index bfbd6ffc..5c6cdeec 100644 --- a/src/server/terrain/systems.rs +++ b/src/server/terrain/systems.rs @@ -145,9 +145,11 @@ mod visualizer { use renet::{DefaultChannel, RenetServer}; use rsmc::{Chunk, ChunkManager, NetworkingMessage, CHUNK_SIZE}; + use crate::terrain::config::NoiseFunctionParams; + use super::{ terrain_events, - terrain_resources::{self, NoiseFunctionParams, TextureType}, + terrain_resources::{self, TextureType}, }; fn map_range(value: f64, min: f64, max: f64, new_min: f64, new_max: f64) -> f64 { diff --git a/src/server/terrain/util/generator.rs b/src/server/terrain/util/generator.rs index c9fe1d8f..73c2c658 100644 --- a/src/server/terrain/util/generator.rs +++ b/src/server/terrain/util/generator.rs @@ -1,8 +1,9 @@ -use terrain_resources::{Generator, NoiseFunctionParams, TerrainGeneratorParams}; - use crate::{ prelude::*, - terrain::resources::{Noise, NoiseSample}, + terrain::{ + config::{NoiseFunctionParams, TerrainGeneratorParams}, + resources::{Generator, Noise, NoiseSample}, + }, }; macro_rules! for_each_chunk_coordinate { From 3c883ed109e7fb40b612c869ea6d251441affd53 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 17:39:06 +0100 Subject: [PATCH 09/16] Move spawn area distance --- src/server/terrain/config.rs | 2 ++ src/server/terrain/systems.rs | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/server/terrain/config.rs b/src/server/terrain/config.rs index 6dd687f8..9ebbd593 100644 --- a/src/server/terrain/config.rs +++ b/src/server/terrain/config.rs @@ -9,6 +9,7 @@ pub struct WorldConfig { pub world_extension: String, pub world_save_interval_seconds: i64, pub world_backup_interval_seconds: i64, + pub spawn_area_distance: IVec3 } impl Default for WorldConfig { @@ -19,6 +20,7 @@ impl Default for WorldConfig { world_extension: String::from(".rsmcw"), world_save_interval_seconds: 30, world_backup_interval_seconds: 180, + spawn_area_distance: IVec3::new(4, 3, 4), } } } diff --git a/src/server/terrain/systems.rs b/src/server/terrain/systems.rs index 5c6cdeec..0fa1187d 100644 --- a/src/server/terrain/systems.rs +++ b/src/server/terrain/systems.rs @@ -8,11 +8,10 @@ pub fn setup_world_system( mut chunk_manager: ResMut, generator: Res, ) { - let render_distance = IVec3::new(4, 3, 4); - info!("Generating chunks"); - let mut chunks = ChunkManager::instantiate_chunks(IVec3::ZERO, render_distance); + let mut chunks = + ChunkManager::instantiate_chunks(IVec3::ZERO, CONFIG.world.spawn_area_distance); chunks.par_iter_mut().for_each(|chunk| { info!("Generating chunk at {:?}", chunk.position); From 7cc7c9913fd663b7d59edb724bbac2a8e55ac86c Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 17:41:57 +0100 Subject: [PATCH 10/16] Fastcheck --- src/server/terrain/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/terrain/config.rs b/src/server/terrain/config.rs index 9ebbd593..2afe0542 100644 --- a/src/server/terrain/config.rs +++ b/src/server/terrain/config.rs @@ -9,7 +9,7 @@ pub struct WorldConfig { pub world_extension: String, pub world_save_interval_seconds: i64, pub world_backup_interval_seconds: i64, - pub spawn_area_distance: IVec3 + pub spawn_area_distance: IVec3, } impl Default for WorldConfig { From dcfee9990ea2b70a87e92547e7e921a2cafec24e Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 17:50:55 +0100 Subject: [PATCH 11/16] Improve error handling --- src/server/config/mod.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index 18ad6bfe..414a74eb 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -17,12 +17,19 @@ pub static CONFIG: LazyLock = LazyLock::new(|| { match std::fs::read_to_string(PathBuf::from(CONFIG_PATH)) { Ok(string) => match toml::from_str(&string) { Ok(config) => config, - Err(_) => panic!("Could not parse config file at '{CONFIG_PATH}'"), + Err(err) => { + use std::process; + + eprintln!("Could not parse config file at '{CONFIG_PATH}'"); + eprintln!("Err: {err}"); + process::exit(0); + }, }, - Err(_) => { + Err(err) => { eprintln!( "Could not read config file at '{CONFIG_PATH}', proceeding with defaults" ); + eprintln!("Err: {err}"); Config::default() } } From dd4a637bab60fd747fdd691e3fdaa5c1a7c05716 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 18:24:47 +0100 Subject: [PATCH 12/16] Refactor params config, improve errors --- src/server/config/mod.rs | 7 +- src/server/terrain/config.rs | 209 ++++++++++++++++++++--------------- 2 files changed, 125 insertions(+), 91 deletions(-) diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index 414a74eb..4edaeb54 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -10,6 +10,7 @@ pub static CONFIG: LazyLock = LazyLock::new(|| { Config::default() } + #[cfg(not(test))] { use std::path::PathBuf; @@ -22,8 +23,8 @@ pub static CONFIG: LazyLock = LazyLock::new(|| { eprintln!("Could not parse config file at '{CONFIG_PATH}'"); eprintln!("Err: {err}"); - process::exit(0); - }, + process::exit(1); + } }, Err(err) => { eprintln!( @@ -42,7 +43,7 @@ use serde::Serialize; use crate::prelude::*; #[derive(Serialize, Deserialize, Default)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct Config { pub world: terrain_config::WorldConfig, pub generator: terrain_config::TerrainGeneratorParams, diff --git a/src/server/terrain/config.rs b/src/server/terrain/config.rs index 2afe0542..f8877ff1 100644 --- a/src/server/terrain/config.rs +++ b/src/server/terrain/config.rs @@ -2,7 +2,7 @@ use crate::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct WorldConfig { pub backups_dir: String, pub worlds_dir: String, @@ -26,46 +26,119 @@ impl Default for WorldConfig { } #[derive(Clone, Serialize, Deserialize)] +#[serde(default, deny_unknown_fields)] +#[derive(Default)] +pub struct TerrainGeneratorParams { + pub height: HeightParams, + pub height_adjust: HeightAdjustParams, + pub density: DensityParams, + pub cave: CaveParams, + pub tree: TreeParams, + pub grass: GrassParams, +} + +#[derive(Clone, Serialize, Deserialize)] +#[serde(default, deny_unknown_fields)] pub struct HeightParams { pub noise: NoiseFunctionParams, pub splines: Vec, } +impl Default for HeightParams { + fn default() -> Self { + Self { + splines: vec![ + Vec2::new(-1.0, 4.0), + Vec2::new(0.0, 0.0), + Vec2::new(0.0, 0.0), + Vec2::new(0.05, 20.0), + Vec2::new(1.0, 35.0), + ], + noise: NoiseFunctionParams { + octaves: 4, + height: 0.0, + lacuranity: 2.0, + frequency: 1.0 / 300.0, + amplitude: 30.0, + persistence: 0.5, + }, + } + } +} + #[derive(Clone, Serialize, Deserialize)] +#[serde(default, deny_unknown_fields)] +pub struct HeightAdjustParams { + pub noise: NoiseFunctionParams, +} + +impl Default for HeightAdjustParams { + fn default() -> Self { + Self { + noise: NoiseFunctionParams { + octaves: 4, + height: 0.0, + lacuranity: 2.0, + frequency: 1.0 / 120.0, + amplitude: 30.0, + persistence: 0.5, + }, + } + } +} + +#[derive(Clone, Serialize, Deserialize)] +#[serde(default, deny_unknown_fields)] pub struct DensityParams { pub noise: NoiseFunctionParams, pub squash_factor: f64, pub height_offset: f64, } +impl Default for DensityParams { + fn default() -> Self { + DensityParams { + squash_factor: 1.0 / 100.0, + height_offset: -20.0, + noise: NoiseFunctionParams { + octaves: 4, + height: 0.0, + lacuranity: 2.0, + frequency: 1.0 / 60.0, + amplitude: 10.0, + persistence: 0.5, + }, + } + } +} + #[derive(Clone, Serialize, Deserialize)] +#[serde(default, deny_unknown_fields)] pub struct CaveParams { pub noise: NoiseFunctionParams, pub base_value: f64, pub threshold: f64, } -#[derive(Clone, Serialize, Deserialize)] -pub struct HeightAdjustParams { - pub noise: NoiseFunctionParams, -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct GrassParams { - pub frequency: u32, -} - -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub struct NoiseFunctionParams { - pub octaves: u32, - pub height: f64, - pub lacuranity: f64, - pub frequency: f64, - pub amplitude: f64, - pub persistence: f64, +impl Default for CaveParams { + fn default() -> Self { + Self { + noise: NoiseFunctionParams { + octaves: 2, + height: 0.0, + lacuranity: 0.03, + frequency: 1.0 / 20.0, + amplitude: 30.0, + persistence: 0.59, + }, + base_value: 0.0, + threshold: 0.25, + } + } } #[derive(Clone, Serialize, Deserialize)] +#[serde(default, deny_unknown_fields)] pub struct TreeParams { pub spawn_attempts_per_chunk: u32, pub min_stump_height: u32, @@ -74,78 +147,38 @@ pub struct TreeParams { pub max_bush_radius: u32, } +impl Default for TreeParams { + fn default() -> Self { + Self { + spawn_attempts_per_chunk: 500, + min_stump_height: 2, + max_stump_height: 20, + min_bush_radius: 3, + max_bush_radius: 5, + } + } +} + #[derive(Clone, Serialize, Deserialize)] -pub struct TerrainGeneratorParams { - pub height: HeightParams, - pub height_adjust: HeightAdjustParams, - pub density: DensityParams, - pub cave: CaveParams, - pub tree: TreeParams, - pub grass: GrassParams, +#[serde(deny_unknown_fields)] +pub struct GrassParams { + pub frequency: u32, } -impl Default for TerrainGeneratorParams { +impl Default for GrassParams { fn default() -> Self { - Self { - height: HeightParams { - splines: vec![ - Vec2::new(-1.0, 4.0), - Vec2::new(0.0, 0.0), - Vec2::new(0.0, 0.0), - Vec2::new(0.05, 20.0), - Vec2::new(1.0, 35.0), - ], - noise: NoiseFunctionParams { - octaves: 4, - height: 0.0, - lacuranity: 2.0, - frequency: 1.0 / 300.0, - amplitude: 30.0, - persistence: 0.5, - }, - }, - height_adjust: HeightAdjustParams { - noise: NoiseFunctionParams { - octaves: 4, - height: 0.0, - lacuranity: 2.0, - frequency: 1.0 / 120.0, - amplitude: 30.0, - persistence: 0.5, - }, - }, - density: DensityParams { - squash_factor: 1.0 / 100.0, - height_offset: -20.0, - noise: NoiseFunctionParams { - octaves: 4, - height: 0.0, - lacuranity: 2.0, - frequency: 1.0 / 60.0, - amplitude: 10.0, - persistence: 0.5, - }, - }, - cave: CaveParams { - noise: NoiseFunctionParams { - octaves: 2, - height: 0.0, - lacuranity: 0.03, - frequency: 1.0 / 20.0, - amplitude: 30.0, - persistence: 0.59, - }, - base_value: 0.0, - threshold: 0.25, - }, - tree: TreeParams { - spawn_attempts_per_chunk: 500, - min_stump_height: 2, - max_stump_height: 20, - min_bush_radius: 3, - max_bush_radius: 5, - }, - grass: GrassParams { frequency: 10 }, - } + Self { frequency: 10 } } } + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +#[serde(default, deny_unknown_fields)] +#[derive(Default)] +pub struct NoiseFunctionParams { + pub octaves: u32, + pub height: f64, + pub lacuranity: f64, + pub frequency: f64, + pub amplitude: f64, + pub persistence: f64, +} From 2f84fc9a8806c47e3d9e6523db6470bd94ebed89 Mon Sep 17 00:00:00 2001 From: Dani Bengl <53896675+cb341@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:25:39 +0100 Subject: [PATCH 13/16] Update src/server/config/commands.rs --- src/server/config/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/config/commands.rs b/src/server/config/commands.rs index 7ace5f99..b571b8a5 100644 --- a/src/server/config/commands.rs +++ b/src/server/config/commands.rs @@ -40,7 +40,7 @@ pub fn perform_command(commands: &ConfigCommands) { println!( "{}", toml::to_string(&Config::default()) - .expect("Loaded config should always be serializable") + .expect("Default config should always be serializable") ); } } From 8ebacdff5e41bdb8c4ec8c83609024d8b9cc947f Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 18:26:02 +0100 Subject: [PATCH 14/16] L --- src/server/config/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index 4edaeb54..08f3725e 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -10,7 +10,6 @@ pub static CONFIG: LazyLock = LazyLock::new(|| { Config::default() } - #[cfg(not(test))] { use std::path::PathBuf; From a49c3143f0e3e1fb4f85556e7e0bafc7b0e88f85 Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 18:33:55 +0100 Subject: [PATCH 15/16] Use config params --- src/server/terrain/util/generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/terrain/util/generator.rs b/src/server/terrain/util/generator.rs index 73c2c658..825d50e8 100644 --- a/src/server/terrain/util/generator.rs +++ b/src/server/terrain/util/generator.rs @@ -37,7 +37,7 @@ impl Generator { pub fn new(seed: u32) -> Generator { Generator { noise: Noise::new(seed), - params: TerrainGeneratorParams::default(), + params: CONFIG.generator.clone(), } } From fd9d26a2d58b908778319d411c6fa621281e95fc Mon Sep 17 00:00:00 2001 From: Daniel Bengl Date: Sun, 1 Feb 2026 18:35:27 +0100 Subject: [PATCH 16/16] L --- src/server/terrain/util/generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/terrain/util/generator.rs b/src/server/terrain/util/generator.rs index 825d50e8..9cc0d803 100644 --- a/src/server/terrain/util/generator.rs +++ b/src/server/terrain/util/generator.rs @@ -1,7 +1,7 @@ use crate::{ prelude::*, terrain::{ - config::{NoiseFunctionParams, TerrainGeneratorParams}, + config::NoiseFunctionParams, resources::{Generator, Noise, NoiseSample}, }, };