feat: data-oriented chunks optimization with tile registry

- Phase 1: Bit-packed standability (ChunkData with bitsets)
- Phase 2: Reactive connectivity (dirty chunks)
- Phase 3: Async terrain baking (AsyncComputeTaskPool)
- Pathfinding weight system (rock=50 preferred, bedrock=150 avoided)
- Movement speed affected by tile weight
- External tiles.toml for hot-reloadable tile definitions
- TileRegistry singleton for async-safe tile lookups
- Fixed world_to_chunk to use CHUNK_SIZE_TILE (128) not CHUNK_SIZE (8)
- Fixed infinite spawner with Local<bool> state guards
- Fixed spawn coordinate grid alignment

Note: Zigzag pathfinding bug introduced - needs investigation
This commit is contained in:
2026-03-19 19:15:36 +00:00
parent 50788af3c7
commit 9535d65bd7
14 changed files with 423 additions and 84 deletions
+50
View File
@@ -1,6 +1,8 @@
use bevy::prelude::Resource;
use serde::Deserialize;
use std::collections::HashMap;
use std::fs;
use std::sync::OnceLock;
#[derive(Debug, Deserialize, Clone, Resource)]
pub struct GameConfig {
@@ -21,3 +23,51 @@ impl GameConfig {
toml::from_str(&config_str).expect("Failed to parse config.toml")
}
}
static TILE_REGISTRY: OnceLock<TileRegistry> = OnceLock::new();
#[derive(Debug, Deserialize, Clone)]
pub struct TileRegistry {
pub floor_tiles: HashMap<String, FloorTileDef>,
pub fixture_tiles: HashMap<String, FixtureTileDef>,
}
#[derive(Debug, Deserialize, Clone, Copy)]
pub struct FloorTileDef {
pub id: u8,
pub can_stand_in: bool,
pub can_stand_on: bool,
pub transparent: bool,
pub astar_weight: u8,
}
#[derive(Debug, Deserialize, Clone, Copy)]
pub struct FixtureTileDef {
pub id: u32,
pub solid: bool,
}
impl TileRegistry {
pub fn load() -> Self {
let config_str = fs::read_to_string("tiles.toml").expect("Failed to find tiles.toml");
toml::from_str(&config_str).expect("Failed to parse tiles.toml")
}
pub fn global() -> &'static Self {
TILE_REGISTRY.get_or_init(|| Self::load())
}
pub fn floor(&self, name: &str) -> FloorTileDef {
*self
.floor_tiles
.get(name)
.unwrap_or_else(|| panic!("Unknown floor tile: {}", name))
}
pub fn fixture(&self, name: &str) -> FixtureTileDef {
*self
.fixture_tiles
.get(name)
.unwrap_or_else(|| panic!("Unknown fixture tile: {}", name))
}
}