| id | geometrystreaminggsystem |
|---|---|
| title | Geometry Streaming System |
| sidebar_position | 13 |
UntoldEngine streams large worlds through a manifest-driven tiled scene pipeline.
The public rule is simple:
| Use case | API |
|---|---|
| Streamed world geometry | setEntityStreamScene(entityId:manifest:) |
| Always-resident assets | setEntityMeshAsync(entityId:filename:withExtension:) |
GeometryStreamingSystem manages the runtime once a streamed scene is loaded. It is not a public component-authoring workflow for standalone entities.
let sceneRoot = createEntity()
setEntityName(entityId: sceneRoot, name: "city")
setEntityStreamScene(entityId: sceneRoot, manifest: "city", withExtension: "json") { success in
setSceneReady(success)
}let sceneRoot = createEntity()
setEntityName(entityId: sceneRoot, name: "city")
if let url = URL(string: "https://cdn.example.com/city/city.json") {
setEntityStreamScene(entityId: sceneRoot, url: url) { success in
setSceneReady(success)
}
}Legacy overloads —
loadTiledScene(manifest:)andloadTiledScene(url:)remain available for backwards compatibility. They create an internal root entity automatically. PrefersetEntityStreamScene(entityId:...)when you need a stable handle to the scene.
Remote manifests are downloaded and cached locally. Tile, HLOD, and per-tile LOD URLs are resolved relative to the manifest URL and fetched on demand.
The engine uses multiple geometry layers:
- Full tile: the main tile payload loaded by
loadTile() - Per-tile LOD: intermediate meshes shown while the full tile is still out of range
- HLOD: coarse far-distance proxy
- OCC sub-mesh stubs: fine-grained
StreamingComponententities created internally inside large tiles
StreamingComponent is internal to the tile-owned OCC path. External callers should not attach it manually or rely on enableStreaming(...).
These are the important fields for geometry streaming:
| Field | Meaning |
|---|---|
streaming_radius |
Full tile display zone |
unload_radius |
Tile teardown threshold |
prefetch_radius |
Background parse threshold before the tile becomes visible |
priority |
Tile load ordering when many tiles compete |
hlod_levels |
Optional far proxy meshes |
lod_levels |
Optional per-tile intermediate LOD meshes |
file_size_bytes |
Parse-budget hint used by the runtime gate |
If prefetch_radius is omitted, the engine computes it automatically from the gap between streaming_radius and unload_radius.
Each update tick, GeometryStreamingSystem:
- Queries the octree within
maxQueryRadius. - Chooses tile parse candidates using predictive camera motion and a frustum gate.
- Parses up to
maxConcurrentTileLoadstiles, subject totileParseMemoryBudgetMB. - Streams OCC child meshes inside loaded tiles using
maxConcurrentLoads. - Unloads tiles, LODs, HLODs, and OCC meshes when they leave range or memory pressure requires eviction.
Important defaults:
maxConcurrentTileLoads = 2maxConcurrentLoads = 3maxConcurrentLODLoads = 4maxConcurrentHLODLoads = 4updateInterval = 0.1burstTickInterval = 0.016
GeometryStreamingSystem.shared.maxConcurrentTileLoads = 2
GeometryStreamingSystem.shared.maxConcurrentLoads = 3
GeometryStreamingSystem.shared.enableFrustumGate = true
GeometryStreamingSystem.shared.tileFrustumGatePadding = 20.0
GeometryStreamingSystem.shared.maxQueryRadius = 500.0Use maxQueryRadius large enough to cover the farthest unload_radius in the scene, or out-of-range tiles may not be discovered for teardown.
- Texture streaming:
setEntityStreamScene(...)automatically aligns texture distance bands to the manifest radii. - Batching: full-load tiles, per-tile LODs, and HLODs notify
BatchingSystemautomatically. OCC sub-mesh uploads join batching incrementally through normal residency events. - Memory pressure: texture quality is shed first; geometry eviction follows only when geometry pressure remains high.
- Increase
GeometryStreamingSystem.shared.tileFrustumGatePadding - Keep
enableFrustumGate = true
- Increase the gap between
streaming_radiusandunload_radius - Increase or explicitly author
prefetch_radius
- Lower
maxConcurrentTileLoads - Reduce per-tile file sizes in the exported manifest
- Verify you loaded the scene through
setEntityStreamScene(...) - Verify the manifest radii are reasonable for your scene scale
- Do not expect standalone
StreamingComponententities to stream; tile ownership is enforced