Spatial chunk management for the Suon world.
This crate groups world positions into chunk entities and provides the runtime data needed to answer three core spatial questions:
- which chunk owns a given world-space
[
suon_position::position::Position] - which chunk currently contains a given entity
- which floor-position pairs inside a chunk are occupied
Responsibilities
[Chunks] is the global registry that maps world positions to chunk entities.
[Chunk] marks entities that act as chunk containers and automatically carries
an [Occupancy] store. [content::AtChunk] is the relationship component that
links an entity back to the chunk that currently contains it.
The crate treats [suon_position::position::Position] as the source of truth
for chunk ownership. [ChunkPlugin] uses lifecycle observers on
[suon_position::position::Position] to synchronize [content::AtChunk] and
to resynchronize occupied tiles using
[suon_position::previous_position::PreviousPosition].
Runtime flow
A typical end-to-end flow looks like this:
- Chunk entities are created with [
Chunk]. - The world populates [
Chunks] with the positions owned by each chunk. - Game entities receive a [
suon_position::position::Position] and optionally an [occupancy::occupied::Occupied] marker. - [
ChunkPlugin] derives [content::AtChunk] automatically from the current [suon_position::position::Position]. - Occupied entities register their current tile in the destination chunk's
[
Occupancy] map. - When an occupied entity moves, the crate releases the previous tile and registers the new one.
Modules
- [
chunks]: chunk registry and chunk-key derivation - [
content]: entity-to-chunk relationship components - [
loader]: placeholder resource for chunk loading orchestration - [
occupancy]: per-chunk blocked-tile tracking and synchronization - [
terrain]: per-chunk passability state synchronized from occupied tiles
At the moment, the end-to-end runtime flow is centered on [Chunks],
[content::AtChunk], [Occupancy], and [terrain::Navigation].
Examples
use bevy::prelude::*;
use suon_chunk::{Chunk, ChunkPlugin, chunks::Chunks, content::AtChunk};
use suon_position::position::Position;
let mut app = App::new();
app.add_plugins(MinimalPlugins);
app.add_plugins(ChunkPlugin);
let chunk = app.world_mut().spawn(Chunk).id();
app.insert_resource(Chunks::from_iter([(Position { x: 4, y: 4 }, chunk)]));
let entity = app.world_mut().spawn(Position { x: 4, y: 4 }).id();
app.update();
let at_chunk = app.world().get::<AtChunk>(entity).unwrap();
assert_eq!(at_chunk.entity(), chunk);