use constants better

This commit is contained in:
2026-03-21 17:51:05 +00:00
parent f96c71b61b
commit cabe944f1b
19 changed files with 47 additions and 52 deletions
+5 -5
View File
@@ -12,11 +12,11 @@ src/
├── config.rs # GameConfig, TileRegistry resources ├── config.rs # GameConfig, TileRegistry resources
├── constants.rs # Tile size, structural constants ├── constants.rs # Tile size, structural constants
├── entities/ ├── entities/
│ ├── item/magic_numbers.rs # Item sprite constants │ ├── item/constants.rs # Item sprite constants
│ ├── livestock/ │ ├── livestock/
│ ├── sentient/ │ ├── sentient/
│ └── shared_systems/ │ └── shared_systems/
│ ├── magic_numbers.rs # Pathfinding + dig constants │ ├── constants.rs # Pathfinding + dig constants
│ ├── occupancy.rs │ ├── occupancy.rs
│ └── pathfinding.rs │ └── pathfinding.rs
├── game.rs # ZIndex resource, frame timing ├── game.rs # ZIndex resource, frame timing
@@ -24,12 +24,12 @@ src/
└── world/ └── world/
├── chunks/ # ChunkMap, chunk loading/unloading, connectivity ├── chunks/ # ChunkMap, chunk loading/unloading, connectivity
├── generation/ ├── generation/
│ ├── forestry/magic_numbers.rs # Tree constants │ ├── forestry/constants.rs # Tree constants
│ ├── terrain/magic_numbers.rs # Terrain + cave constants │ ├── terrain/constants.rs # Terrain + cave constants
│ ├── forestry.rs │ ├── forestry.rs
│ └── terrain.rs │ └── terrain.rs
└── tiles/ └── tiles/
├── magic_numbers.rs # A*, benchmark constants ├── constants.rs # A*, benchmark constants
├── chunk_data.rs ├── chunk_data.rs
├── rendering.rs ├── rendering.rs
├── tilemap.rs ├── tilemap.rs
@@ -1,3 +1,2 @@
// Items
/// Z offset applied to item sprites to prevent z-fighting with the floor tile below. /// Z offset applied to item sprites to prevent z-fighting with the floor tile below.
pub const ITEM_Z_FIGHTING_OFFSET: f32 = 0.1; pub const ITEM_Z_FIGHTING_OFFSET: f32 = 0.1;
+1 -1
View File
@@ -52,7 +52,7 @@ impl DropTable {
} }
} }
// MAGIC Splitmix64-style hash of world SEED + tile position. // Splitmix64-style hash of world SEED + tile position.
// Constants are from the splitmix64 finaliser (Sebastiano Vigna, 2018): // Constants are from the splitmix64 finaliser (Sebastiano Vigna, 2018):
// 0x9e3779b97f4a7c15 — fractional bits of the golden ratio (Fibonacci hashing) // 0x9e3779b97f4a7c15 — fractional bits of the golden ratio (Fibonacci hashing)
// 0x6c62272e07bb0142 — high-bit-density prime for y-axis mixing // 0x6c62272e07bb0142 — high-bit-density prime for y-axis mixing
+1 -1
View File
@@ -1,8 +1,8 @@
pub mod constants;
pub mod container; pub mod container;
pub mod core; pub mod core;
pub mod decorations; pub mod decorations;
pub mod drop_table; pub mod drop_table;
pub mod magic_numbers;
pub mod material; pub mod material;
pub mod perishable; pub mod perishable;
pub mod prefabs; pub mod prefabs;
@@ -1,6 +1,6 @@
use bevy::prelude::*; use bevy::prelude::*;
use crate::entities::item::magic_numbers::ITEM_Z_FIGHTING_OFFSET; use crate::entities::item::constants::ITEM_Z_FIGHTING_OFFSET;
use crate::entities::item::{ use crate::entities::item::{
Item, ItemBundle, ItemDecorations, ItemRotationState, ItemType, Material, Quality, Item, ItemBundle, ItemDecorations, ItemRotationState, ItemType, Material, Quality,
}; };
+4 -4
View File
@@ -46,16 +46,16 @@ impl ItemType {
ToolType::Shovel => 1.5, ToolType::Shovel => 1.5,
ToolType::Axe => 1.75, ToolType::Axe => 1.75,
ToolType::Hammer => 1.0, ToolType::Hammer => 1.0,
ToolType::Anvil => 50.0, // MAGIC ~50kg — intentionally immovable in practice ToolType::Anvil => 50.0, // ~50kg — intentionally immovable in practice
ToolType::Furnace => 100.0, // MAGIC ~100kg — structure, not a carried item ToolType::Furnace => 100.0, // ~100kg — structure, not a carried item
}, },
ItemType::Food(_) => 0.2, ItemType::Food(_) => 0.2,
ItemType::Drink(_) => 0.3, ItemType::Drink(_) => 0.3,
ItemType::Medicine => 0.1, ItemType::Medicine => 0.1,
ItemType::RawMaterial => 0.5, ItemType::RawMaterial => 0.5,
ItemType::Gem => 0.1, ItemType::Gem => 0.1,
ItemType::Coin => 0.01, // MAGIC ~1g coin, negligible individual weight ItemType::Coin => 0.01, // ~1g coin, negligible individual weight
ItemType::Container => 1.0, // MAGIC empty container only, not contents ItemType::Container => 1.0, // empty container only, not contents
ItemType::Book => 0.5, ItemType::Book => 0.5,
ItemType::Toy => 0.2, ItemType::Toy => 0.2,
ItemType::Decoration => 0.3, ItemType::Decoration => 0.3,
+1 -1
View File
@@ -1,8 +1,8 @@
use crate::config::GameConfig; use crate::config::GameConfig;
use crate::constants::*; use crate::constants::*;
use crate::entities::shared_components::Ambulatory; use crate::entities::shared_components::Ambulatory;
use crate::entities::shared_systems::constants::DEFAULT_DIG_INTERVAL_SECS;
use crate::entities::shared_systems::digging::Digger; use crate::entities::shared_systems::digging::Digger;
use crate::entities::shared_systems::magic_numbers::DEFAULT_DIG_INTERVAL_SECS;
use crate::game::SpawnDelay; use crate::game::SpawnDelay;
use crate::world::VisibleGameEntity; use crate::world::VisibleGameEntity;
use bevy::prelude::*; use bevy::prelude::*;
@@ -1,4 +1,3 @@
// Pathfinding + digging
/// Number of future path steps validated each tick before an entity moves. /// Number of future path steps validated each tick before an entity moves.
pub const PATHFINDER_VALIDATE_STEPS: usize = 3; pub const PATHFINDER_VALIDATE_STEPS: usize = 3;
/// Ticks between path validation checks per entity. /// Ticks between path validation checks per entity.
+1 -1
View File
@@ -1,4 +1,4 @@
pub mod constants;
pub mod digging; pub mod digging;
pub mod magic_numbers;
pub mod occupancy; pub mod occupancy;
pub mod pathfinding; pub mod pathfinding;
+2 -2
View File
@@ -63,7 +63,7 @@ use crate::constants::{
ITILE_SIZE, PATHFINDER_HIERARCHICAL_THRESHOLD_CHUNKS, PATHFINDER_MAX_NODES, ITILE_SIZE, PATHFINDER_HIERARCHICAL_THRESHOLD_CHUNKS, PATHFINDER_MAX_NODES,
PATHFINDER_PROVISIONAL_NODE_LIMIT, PIXEL_RATIO, TILE_SIZE, PATHFINDER_PROVISIONAL_NODE_LIMIT, PIXEL_RATIO, TILE_SIZE,
}; };
use crate::entities::shared_systems::magic_numbers::{ use crate::entities::shared_systems::constants::{
CONVOY_DOT_THRESHOLD, ES_DIRECTION_THRESHOLD, HEAD_ON_DOT_THRESHOLD, OCCUPANCY_CROWD_THRESHOLD, CONVOY_DOT_THRESHOLD, ES_DIRECTION_THRESHOLD, HEAD_ON_DOT_THRESHOLD, OCCUPANCY_CROWD_THRESHOLD,
PATHFINDER_DIRTY_LOOKAHEAD, PATHFINDER_VALIDATE_STEPS, PATHFINDER_VALIDATION_COOLDOWN, PATHFINDER_DIRTY_LOOKAHEAD, PATHFINDER_VALIDATE_STEPS, PATHFINDER_VALIDATION_COOLDOWN,
WALK_SPEED_DIVISOR, WALK_SPEED_DIVISOR,
@@ -1073,7 +1073,7 @@ fn directional_chunk_waypoint(
// goal varies per entity (each has a different random wander target). // goal varies per entity (each has a different random wander target).
// Together they produce unique spread values for entities even when // Together they produce unique spread values for entities even when
// heading through the same chunk, without needing to pass entity ID. // heading through the same chunk, without needing to pass entity ID.
// MAGIC Small primes spread entity starting positions across waypoint edge tiles. // Small primes spread entity starting positions across waypoint edge tiles.
// Different values per axis prevent aliasing when positions are on a regular grid. // Different values per axis prevent aliasing when positions are on a regular grid.
let entropy = (cur_tile.x.unsigned_abs() as usize) let entropy = (cur_tile.x.unsigned_abs() as usize)
.wrapping_mul(1619) .wrapping_mul(1619)
+2 -2
View File
@@ -1,4 +1,4 @@
pub mod magic_numbers; pub mod constants;
use bevy::prelude::*; use bevy::prelude::*;
use bevy_platform::collections::HashSet; use bevy_platform::collections::HashSet;
use bevy_platform::sync::Mutex; use bevy_platform::sync::Mutex;
@@ -11,7 +11,7 @@ use std::hash::{Hash, Hasher};
use crate::{ use crate::{
constants::{SEED, TILE_SIZE}, constants::{SEED, TILE_SIZE},
world::generation::forestry::magic_numbers::{ world::generation::forestry::constants::{
TREE_LEAF_BASE_RADIUS, TREE_LEAF_RADIUS_OFFSET, TREE_LEAF_RADIUS_VARIATION, TREE_LEAF_BASE_RADIUS, TREE_LEAF_RADIUS_OFFSET, TREE_LEAF_RADIUS_VARIATION,
TREE_MIN_DISTANCE_TILES, TREE_SPAWN_CHANCE, TREE_TRUNK_EXTRA_HEIGHT, TREE_TRUNK_MIN_HEIGHT, TREE_MIN_DISTANCE_TILES, TREE_SPAWN_CHANCE, TREE_TRUNK_EXTRA_HEIGHT, TREE_TRUNK_MIN_HEIGHT,
}, },
@@ -1,4 +1,3 @@
// Forestry
/// Minimum distance between tree trunks in tile units. Prevents overlapping canopies. /// Minimum distance between tree trunks in tile units. Prevents overlapping canopies.
pub const TREE_MIN_DISTANCE_TILES: f32 = 7.0; pub const TREE_MIN_DISTANCE_TILES: f32 = 7.0;
/// 1-in-N chance per eligible grass tile of spawning a tree. /// 1-in-N chance per eligible grass tile of spawning a tree.
+7 -7
View File
@@ -1,4 +1,4 @@
pub mod magic_numbers; pub mod constants;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::tasks::AsyncComputeTaskPool; use bevy::tasks::AsyncComputeTaskPool;
use bevy_platform::time::Instant; use bevy_platform::time::Instant;
@@ -10,15 +10,15 @@ use crate::entities::item::drop_table::DropTableRegistry;
use crate::{ use crate::{
config::TileRegistry, config::TileRegistry,
constants::{SEED, TILE_SIZE}, constants::{SEED, TILE_SIZE},
world::generation::terrain::magic_numbers::{ world::generation::terrain::constants::{
CAVE_DEPTH_THRESHOLD, CAVE_NOISE_FREQUENCY, CAVE_ROCK_THRESHOLD, CAVE_VOID_THRESHOLD, CAVE_DEPTH_THRESHOLD, CAVE_NOISE_FREQUENCY, CAVE_ROCK_THRESHOLD, CAVE_VOID_THRESHOLD,
TERRAIN_AMPLITUDE_PERSISTENCE, TERRAIN_BASE_FREQUENCY, TERRAIN_AMPLITUDE_PERSISTENCE, TERRAIN_BASE_FREQUENCY, TERRAIN_FREQUENCY_LACUNARITY,
TERRAIN_FREQUENCY_LACUNARITY, TERRAIN_HEIGHT_SCALE, TERRAIN_HEIGHT_SCALE,
}, },
world::{ world::{
tiles::{ChunkData, FloorTileData, TileMap}, tiles::{ChunkData, FloorTileData, TileMap},
ChunkForrestryEvent, ChunkMap, ChunkTerrainEvent, TileOcclusionEvent, ChunkForrestryEvent, ChunkMap, ChunkTerrainEvent, TileOcclusionEvent, CHUNK_SIZE, Z_ABOVE,
CHUNK_SIZE, Z_ABOVE, Z_BELOW, Z_BELOW,
}, },
}; };
@@ -68,7 +68,7 @@ pub fn generate_surface_terrain(x: i32, y: i32) -> f32 {
amplitude *= TERRAIN_AMPLITUDE_PERSISTENCE; amplitude *= TERRAIN_AMPLITUDE_PERSISTENCE;
frequency *= TERRAIN_FREQUENCY_LACUNARITY; frequency *= TERRAIN_FREQUENCY_LACUNARITY;
} }
(noise_value * TERRAIN_HEIGHT_SCALE as f64) as f32 (noise_value * TERRAIN_HEIGHT_SCALE) as f32
} }
/// Async terrain generation - runs on AsyncComputeTaskPool. /// Async terrain generation - runs on AsyncComputeTaskPool.
@@ -1,4 +1,3 @@
// Terrain generation
/// Noise frequency for the coarsest octave of surface terrain height. /// Noise frequency for the coarsest octave of surface terrain height.
pub const TERRAIN_BASE_FREQUENCY: f64 = 0.008; pub const TERRAIN_BASE_FREQUENCY: f64 = 0.008;
/// Amplitude multiplier per noise octave (persistence). 0.6 = moderate detail. /// Amplitude multiplier per noise octave (persistence). 0.6 = moderate detail.
@@ -6,7 +5,7 @@ pub const TERRAIN_AMPLITUDE_PERSISTENCE: f64 = 0.6;
/// Frequency multiplier per noise octave (lacunarity). /// Frequency multiplier per noise octave (lacunarity).
pub const TERRAIN_FREQUENCY_LACUNARITY: f64 = 1.8; pub const TERRAIN_FREQUENCY_LACUNARITY: f64 = 1.8;
/// Scale applied to summed octave noise to set terrain height range in tile units. /// Scale applied to summed octave noise to set terrain height range in tile units.
pub const TERRAIN_HEIGHT_SCALE: f32 = 2.5; pub const TERRAIN_HEIGHT_SCALE: f64 = 2.5;
/// Noise frequency for cave generation (applied to all three axes). /// Noise frequency for cave generation (applied to all three axes).
pub const CAVE_NOISE_FREQUENCY: f64 = 0.05; pub const CAVE_NOISE_FREQUENCY: f64 = 0.05;
/// Cave noise value below which a tile becomes open air. /// Cave noise value below which a tile becomes open air.
+2 -2
View File
@@ -17,7 +17,7 @@ use bevy::prelude::*;
use crate::constants::ITILE_SIZE; use crate::constants::ITILE_SIZE;
use crate::world::chunks::{CHUNK_SIZE, Z_ABOVE, Z_BELOW}; use crate::world::chunks::{CHUNK_SIZE, Z_ABOVE, Z_BELOW};
use crate::world::tiles::magic_numbers::ASTAR_DEFAULT_WEIGHT; use crate::world::tiles::constants::ASTAR_DEFAULT_WEIGHT;
/// Number of z-levels in a chunk (Z_BELOW + Z_ABOVE + 1 for inclusive range). /// Number of z-levels in a chunk (Z_BELOW + Z_ABOVE + 1 for inclusive range).
/// Terrain generation uses -Z_BELOW..=Z_ABOVE (inclusive at both ends). /// Terrain generation uses -Z_BELOW..=Z_ABOVE (inclusive at both ends).
@@ -274,7 +274,7 @@ impl ChunkData {
self.stand_in_fixture.fill(0); self.stand_in_fixture.fill(0);
self.stand_on_fixture.fill(0); self.stand_on_fixture.fill(0);
self.tile_ids.fill(0); self.tile_ids.fill(0);
// MAGIC ASTAR_DEFAULT_WEIGHT matches normal grass/traversable tile weight — cleared // ASTAR_DEFAULT_WEIGHT matches normal grass/traversable tile weight — cleared
// chunks present as passable rather than impassable walls to pathfinding. // chunks present as passable rather than impassable walls to pathfinding.
self.astar_weights.fill(ASTAR_DEFAULT_WEIGHT); self.astar_weights.fill(ASTAR_DEFAULT_WEIGHT);
} }
@@ -1,4 +1,3 @@
// Tiles
/// Default A* weight returned for out-of-bounds or unloaded positions. /// Default A* weight returned for out-of-bounds or unloaded positions.
/// Matches normal traversable tile weight so pathfinding degrades gracefully. /// Matches normal traversable tile weight so pathfinding degrades gracefully.
pub const ASTAR_DEFAULT_WEIGHT: u8 = 100; pub const ASTAR_DEFAULT_WEIGHT: u8 = 100;
+1 -1
View File
@@ -1,6 +1,6 @@
pub mod benchmark; pub mod benchmark;
pub mod chunk_data; pub mod chunk_data;
pub mod magic_numbers; pub mod constants;
pub mod rendering; pub mod rendering;
pub mod tile_changed; pub mod tile_changed;
pub mod tilemap; pub mod tilemap;
+1 -1
View File
@@ -35,7 +35,7 @@ use super::chunk_data::ChunkData;
use crate::constants::ITILE_SIZE; use crate::constants::ITILE_SIZE;
use crate::entities::item::drop_table::DropTable; use crate::entities::item::drop_table::DropTable;
use crate::world::chunks::{world_to_chunk, CHUNK_SIZE, Z_ABOVE, Z_BELOW}; use crate::world::chunks::{world_to_chunk, CHUNK_SIZE, Z_ABOVE, Z_BELOW};
use crate::world::tiles::magic_numbers::ASTAR_DEFAULT_WEIGHT; use crate::world::tiles::constants::ASTAR_DEFAULT_WEIGHT;
/// Packed floor tile data for efficient storage. ~35 bytes vs 76 bytes tuple. /// Packed floor tile data for efficient storage. ~35 bytes vs 76 bytes tuple.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
+2 -2
View File
@@ -9,7 +9,7 @@ use crate::constants::{ITILE_SIZE, TILE_PIXELS, TILE_SIZE};
use crate::game::ZIndex; use crate::game::ZIndex;
use crate::world::chunks::{CHUNK_SIZE, CHUNK_SIZE_TILE, Z_BELOW, Z_TOTAL}; use crate::world::chunks::{CHUNK_SIZE, CHUNK_SIZE_TILE, Z_BELOW, Z_TOTAL};
use crate::world::textures::TilemapTileset; use crate::world::textures::TilemapTileset;
use crate::world::tiles::magic_numbers::{BYTES_PER_MB, Z_CHANGE_HISTORY_LEN}; use crate::world::tiles::constants::{BYTES_PER_MB, Z_CHANGE_HISTORY_LEN};
use crate::world::tiles::{FloorTileData, TileMap}; use crate::world::tiles::{FloorTileData, TileMap};
pub const LAYER_FLOOR: u8 = 0; pub const LAYER_FLOOR: u8 = 0;
@@ -140,7 +140,7 @@ fn tile_for_depth(real_index: u16, z_diff: i32) -> TileData {
} }
fn is_tile_visible_at_z(tile_data: &FloorTileData, z_index: usize) -> bool { fn is_tile_visible_at_z(tile_data: &FloorTileData, z_index: usize) -> bool {
// MAGIC u8::MAX + 1; z_index stored as u8 in layer key so this is out-of-range // u8::MAX + 1; z_index stored as u8 in layer key so this is out-of-range
if z_index >= 256 { if z_index >= 256 {
return false; return false;
} }