Files
dorf/src/world/mod.rs
T
popertots f9a74ed432 feat: migrate quilter rendering to Bevy TilemapChunk
Replaces the CPU pixel-baking quilter system (QuiltCache, TerrainSprite,
pixel_buffers) with Bevy's native TilemapChunk GPU-index-lookup API.

Architecture:
- TilemapChunk entities replace TerrainSprite entities per (chunk, z, layer)
- Tileset PNG stacked vertically as texture_2d_array (11 rows: 6 floor + 5 fixture)
- populate_chunk_tiles reads TileMap HashMap directly; no ECS FloorTile entities
- Chunk spawn deferred to apply_terrain_blobs (after TileMap data exists)
- Dirty key system triggers repopulate on occlusion/camera-z changes

Bug fixes:
- populate_chunk_tiles: add chunk_pos offset to world tile lookups (was always (0,0))
- spawn_tilemap_chunks: offset Transform by -TILE_SIZE/2 (tile-centre vs bottom-left)
- spawn_tilemap_chunks: AlphaMode2d::Blend (was Opaque, blocking DF fade)
- update_tilemap_chunk_visibility: actually mutate Visibility (was read-only)
- handle_tile_occlusion_updates: mark dirty keys inline (was double-reading events)
- TilemapChunkSpawner: deduplicate pending queue and guard stale registry

Performance:
- ~115K FloorTile ECS entities eliminated
- GPU memory: O(tile_data) instead of O(CHUNK_TILES² × z_levels × pixel_bytes)
- Z-scroll: only TilemapChunkTileData repopulates (no entity re-spawn)
- Benchmarks via TilemapBenchmark resource (F9 to report)
2026-03-20 14:02:04 +00:00

82 lines
2.7 KiB
Rust

use crate::{
camera,
config::GameConfig,
world::generation::{
generate_chunk_fauna, generate_chunk_foliage, generate_chunk_forrestry,
generate_chunk_weathering_and_precipitation, apply_terrain_blobs, spawn_terrain_tasks,
TerrainBlobStorage,
},
};
use bevy::prelude::*;
pub mod chunks;
pub mod generation;
pub mod textures;
pub mod tiles;
pub use chunks::management::*;
pub use textures::management::*;
pub use tiles::{prefabs::*, rendering::*, visibility::*};
pub struct WorldPlugin;
impl Plugin for WorldPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<ChunkMap>()
.init_resource::<TerrainBlobStorage>()
.init_resource::<tiles::TilemapBenchmark>()
.init_resource::<tiles::TilemapChunkRegistry>()
.init_resource::<tiles::TilemapChunkSpawner>()
.add_message::<GenerateChunkEvent>()
.add_message::<ChunkTerrainEvent>()
.add_message::<ChunkWeatheringAndPrecipitationEvent>()
.add_message::<ChunkForrestryEvent>()
.add_message::<ChunkFoliageEvent>()
.add_message::<ChunkFaunaEvent>()
.add_message::<TileOcclusionEvent>()
.add_systems(Startup, (setup_chunk_system, setup_initial_chunks).chain())
.add_systems(
FixedUpdate,
(
handle_chunk_events,
update_chunk_connectivity,
tiles::despawn_tilemap_chunks,
spawn_terrain_tasks,
apply_terrain_blobs,
generate_chunk_weathering_and_precipitation,
generate_chunk_forrestry,
generate_chunk_foliage,
generate_chunk_fauna,
),
)
.add_systems(
Update,
(
compute_visibility_of_game_entities
.after(crate::entities::item::item_tile_management_system),
tiles::track_benchmark,
tiles::render_bench_report_system,
handle_tile_occlusion_updates,
tiles::spawn_tilemap_chunks,
tiles::on_camera_z_changed,
tiles::update_tilemap_chunk_visibility,
tiles::populate_tilemap_chunk_data,
),
);
}
}
fn setup_initial_chunks(
mut event_writer: MessageWriter<GenerateChunkEvent>,
config: Res<GameConfig>,
) {
let radius = config.initial_chunk_radius;
for x in -radius..=radius {
for y in -radius..=radius {
event_writer.write(GenerateChunkEvent {
chunk_position: IVec2::new(x, y),
});
}
}
}