# BSP Chunk Streaming Design Minecraft-style infinite procedural world using BSP geometry. The world is a grid of BSP chunks that generate and stream as the player explores. Both interior (dungeons, courtyards) and exterior (hills, cliffs) terrain use BSP representation. ## Chunk Addressing `ChunkId::Bsp(u32)` becomes `ChunkId::Bsp { cx: i32, cz: i32 }`. Each chunk covers a 16x16 cell region (1024x1024 world units). World-space origin of chunk `(cx, cz)` is `(cx * 1024.0, cz * 1024.0)`. The `ChunkMessage` transport header already has `cx/cy/cz` fields (currently unused) — we start populating them. The `id` field becomes `hash(cx, cz)` for fragment assembly deduplication. ## Procgen — Biome Selection The server holds a `world_seed: u64`. For each chunk at `(cx, cz)`: 1. Sample noise at `(cx * scale, cz * scale)` with the world seed 2. Map noise value to biome: - **Dungeon** (noise < -0.2): Indoor rooms with corridors, walls, ceiling. Existing `generate_rooms` logic. - **Courtyard** (noise -0.2 to 0.2): Central open area with wing rooms. Existing `generate_courtyard` logic. - **Exterior** (noise > 0.2): Open terrain with height variation, no ceiling, cliff walls at steep changes. 3. Per-chunk seed: `hash(world_seed, cx, cz)` for deterministic RNG. 4. All vertex positions emitted in world space: offset by `(cx * 1024.0, cz * 1024.0)`. ## Procgen — Exterior Terrain New `generate_exterior` function: - Each cell gets a floor height from fine-grained noise at world-space position - All cells open (no ceiling) - Walls emitted between adjacent cells with height difference > 32 units (cliff faces) - No walls at chunk edges — floor extends to boundary, noise is continuous across chunks - Single directional light (sunlight) instead of per-room point lights - Materials 7/8/9 (ground/cliff/grass) ## Server Streaming Track player's chunk coordinate: `chunk_cx = floor(player.x / 1024)`, `chunk_cz = floor(player.z / 1024)`. Each tick, compute 3x3 ring around player vs `ClientChunkState.known`: - **New chunks in range**: Generate lazily, queue for streaming - **Chunks leaving range**: No action — client LRU handles eviction - **Active chunk**: The chunk the player stands in. `CHUNK_ENTER` sent when it changes. Streaming priority: player's chunk bursts at 64 fragments/tick, neighbors at 8 fragments/tick. ## Client — Multi-Chunk Rendering & Collision **World struct**: Add `loaded_chunks[9]` array for the 3x3 ring. `active_chunk` remains the player's chunk (collision). **Sync**: Iterate chunk cache for the 3x3 ring around player's chunk coordinate. Populate `loaded_chunks`. **Rendering**: Iterate `loaded_chunks`, call `pxl8_bsp_render` for each. Vertices are in world space — no transform needed. Frustum-cull entire chunks before BSP rendering (chunk AABB: 1024x128x1024). **Collision**: `pxl8_sim_trace` checks `active_chunk` BSP. Swap active chunk when player crosses boundary. Cross-chunk collision is a future refinement. **BSP render state**: Store `pxl8_bsp_render_state*` inside each `pxl8_world_chunk`, created on arrival, destroyed on eviction. ## Wire Protocol No new message types. Existing messages gain spatial meaning: - `ChunkMessage.cx/cz`: populated with grid coordinates - `CHUNK_ENTER`: repacked payload as `cx: i32, cz: i32` (8 bytes) - Fragment assembly keyed by `(cx, cz)` instead of `id` ## Removals - `generate_connected`, `LayoutMode::Connected` — replaced by biome system - `remap_bsp_materials` — each biome sets its own materials - `carve_corridor_h_offset` / `carve_corridor_v_offset` — no more combined grids - `main.rs` single-BSP generation on spawn — replaced by streaming around player position ## What Stays - `generate_rooms` / `generate_courtyard` — used as chunk-level biome generators - Door system (`pxl8_sim_door`, `door_angle`, `entities.fnl`) — chunk-local feature - `grid_to_bsp` pipeline — gains `origin_x/origin_z` parameter for world-space offset - `grid_to_bsp` heights parameter for exterior terrain elevation - BSP PVS, cell portals — per-chunk visibility still works - Chunk cache (512 entries), fragment assembly, UDP transport