Streaming System
The ChunkStreamingSystem automatically manages chunk loading and unloading based on StreamingAnchorComponent positions.
import { ChunkManager, ChunkStreamingSystem, ChunkLoaderComponent, StreamingAnchorComponent} from '@esengine/world-streaming';
// Create and configure chunk managerconst chunkManager = new ChunkManager(512);chunkManager.setScene(scene);chunkManager.setDataProvider(myProvider);
// Create streaming systemconst streamingSystem = new ChunkStreamingSystem();streamingSystem.setChunkManager(chunkManager);scene.addSystem(streamingSystem);
// Create loader entity with configurationconst loaderEntity = scene.createEntity('ChunkLoader');const loader = loaderEntity.addComponent(new ChunkLoaderComponent());loader.chunkSize = 512;loader.loadRadius = 2;loader.unloadRadius = 4;Streaming Anchor
Section titled “Streaming Anchor”The StreamingAnchorComponent marks entities as chunk loading anchors. Chunks are loaded around all anchors.
// Create player as streaming anchorconst playerEntity = scene.createEntity('Player');const anchor = playerEntity.addComponent(new StreamingAnchorComponent());
// Update position each framefunction update() { anchor.x = player.worldX; anchor.y = player.worldY;}Anchor Properties
Section titled “Anchor Properties”| Property | Type | Default | Description |
|---|---|---|---|
x | number | 0 | World X position |
y | number | 0 | World Y position |
weight | number | 1.0 | Load radius multiplier |
bEnablePrefetch | boolean | true | Enable prefetch for this anchor |
Multiple Anchors
Section titled “Multiple Anchors”// Main player - full load radiusconst playerAnchor = player.addComponent(new StreamingAnchorComponent());playerAnchor.weight = 1.0;
// Camera preview - smaller radiusconst cameraAnchor = camera.addComponent(new StreamingAnchorComponent());cameraAnchor.weight = 0.5; // Half the load radiuscameraAnchor.bEnablePrefetch = false;Loader Configuration
Section titled “Loader Configuration”The ChunkLoaderComponent configures streaming behavior.
const loader = entity.addComponent(new ChunkLoaderComponent());
// Chunk dimensionsloader.chunkSize = 512; // World units per chunk
// Loading radiusloader.loadRadius = 2; // Load chunks within 2 chunks of anchorloader.unloadRadius = 4; // Unload beyond 4 chunks
// Performance tuningloader.maxLoadsPerFrame = 2; // Max async loads per frameloader.maxUnloadsPerFrame = 1; // Max unloads per frameloader.unloadDelay = 3000; // MS before unloading
// Prefetchloader.bEnablePrefetch = true; // Enable movement-based prefetchloader.prefetchRadius = 1; // Extra chunks to prefetchCoordinate Helpers
Section titled “Coordinate Helpers”// Convert world position to chunk coordinatesconst coord = loader.worldToChunk(1500, 2300);
// Get chunk boundsconst bounds = loader.getChunkBounds(coord);Prefetch System
Section titled “Prefetch System”When enabled, the system prefetches chunks in the movement direction:
Movement Direction →
[ ][ ][ ] [ ][P][P] P = Prefetch [L][L][L] → [L][L][L] L = Loaded [ ][ ][ ] [ ][ ][ ]// Enable prefetchloader.bEnablePrefetch = true;loader.prefetchRadius = 2; // Prefetch 2 chunks ahead
// Per-anchor prefetch controlanchor.bEnablePrefetch = true; // Enable for main playercameraAnchor.bEnablePrefetch = false; // Disable for cameraSystem Processing
Section titled “System Processing”The system runs each frame and:
- Updates anchor velocities
- Requests loads for chunks in range
- Cancels unloads for chunks back in range
- Requests unloads for chunks outside range
- Processes load/unload queues
// Access the chunk manager from systemconst system = scene.getSystem(ChunkStreamingSystem);const manager = system?.chunkManager;
if (manager) { console.log('Loaded:', manager.loadedChunkCount);}Priority-Based Loading
Section titled “Priority-Based Loading”Chunks are loaded with priority based on distance:
| Distance | Priority | Description |
|---|---|---|
| 0 | Immediate | Player’s current chunk |
| 1 | High | Adjacent chunks |
| 2-4 | Normal | Nearby chunks |
| 5+ | Low | Distant chunks |
| Prefetch | Prefetch | Movement direction |
Events
Section titled “Events”chunkManager.setEvents({ onChunkLoaded: (coord, entities) => { // Chunk ready - spawn NPCs, enable collision for (const entity of entities) { entity.getComponent(ColliderComponent)?.enable(); } }, onChunkUnloaded: (coord) => { // Cleanup - save state, release resources }});