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
+22 -9
View File
@@ -3,6 +3,7 @@ use crate::constants::TILE_SIZE;
use crate::constants::*;
use crate::entities::item::{spawn_prefab, MiscPrefab};
use crate::entities::shared_components::Ambulatory;
use crate::game::SpawnDelay;
use crate::world::tiles::tilemap;
use crate::world::VisibleGameEntity;
use bevy::prelude::*;
@@ -36,7 +37,7 @@ impl Pig {
},
transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)),
visibility: Visibility::Hidden,
drop_timer: PigDropTimer(Timer::from_seconds(5.0, TimerMode::Repeating)), // NEW
drop_timer: PigDropTimer(Timer::from_seconds(5.0, TimerMode::Repeating)),
}
}
}
@@ -49,18 +50,30 @@ pub fn spawn_pigs(
asset_server: Res<AssetServer>,
mut rng_q: Query<&mut WyRand, With<GlobalRng>>,
config: Res<GameConfig>,
mut delay: ResMut<SpawnDelay>,
mut has_spawned: Local<bool>,
) {
if *has_spawned {
return;
}
if delay.0 < 60 {
delay.0 += 1;
return;
}
*has_spawned = true;
if let Ok(mut rng) = rng_q.single_mut() {
for _ in 0..config.spawn_counts.pigs {
let raw_x = rng.random_range(-32.0f32..32.0f32);
let raw_y = rng.random_range(-32.0f32..32.0f32);
let grid_x = (raw_x / TILE_SIZE).round() * TILE_SIZE;
let grid_y = (raw_y / TILE_SIZE).round() * TILE_SIZE;
let grid_z = 35.0 * TILE_SIZE;
let pig = commands
.spawn(Pig::new(
&asset_server,
Vec3::new(
rng.random_range(-32.0f32..32.0f32).round(),
rng.random_range(-32.0f32..32.0f32).round(),
35.0,
) * TILE_SIZE,
))
.spawn(Pig::new(&asset_server, Vec3::new(grid_x, grid_y, grid_z)))
.id();
commands.entity(pig).insert(VisibleGameEntity);
}