LoadWorldAsync lets a game continue updating and rendering its
current world while Blitz3D+ reads and prepares another one. The returned
handle is a normal world handle, but it cannot be selected, rendered, updated,
or used for audio until WorldReady is true. Loading is independent
of the GUI event system.
loadingWorld=CreateWorld()
SetWorld loadingWorld
camera=CreateCamera()
PositionEntity camera,0,0,-5
spinner=CreateCube()
nextWorld=LoadWorldAsync("levels/level2.world")
While Not WorldReady(nextWorld)
state=WorldLoadState(nextWorld)
If state=WORLD_LOAD_FAILED Then RuntimeError WorldLoadError(nextWorld)
If state=WORLD_LOAD_CANCELLED Then RuntimeError "Load cancelled"
TurnEntity spinner,.4,.8,.2
UpdateWorld
RenderWorld
Text 20,20,"Loading "+(WorldLoadProgress(nextWorld)/10.0)+"%"
Text 20,44,WorldLoadStage(nextWorld)
Flip
Wend
SetWorld nextWorld
SetAudioWorld nextWorld
FreeWorld loadingWorld
Flip, FlipCanvas, Delay, and
WaitTimer service budgeted main-thread finalization automatically.
Loops without those commands can call UpdateAsyncLoads. The
automatic calls share one deadline for the current presentation or wait
boundary. The default finalization budget is 2 milliseconds and can be changed with
SetAsyncLoadBudget.
By default the runtime permits 8 simultaneous world loads and caps aggregate
in-flight source data at 256 MiB, decoded CPU data at 512 MiB, upload staging at
128 MiB, and ready resources at 512 MiB on Win32 or 1 GiB on Win64. Deployments
and automated stress tests may override those values before startup with
BLITZ3D_ASYNC_MAX_LOADS, BLITZ3D_ASYNC_SOURCE_BYTES,
BLITZ3D_ASYNC_DECODED_BYTES,
BLITZ3D_ASYNC_UPLOAD_STAGING_BYTES, and
BLITZ3D_ASYNC_READY_BYTES. Memory values are byte counts. A load
that would exceed a limit fails with the requested, retained, and limit values
in WorldLoadError.
| Constant | Meaning |
|---|---|
WORLD_LOAD_READY (0) | The world is fully published and selectable. |
WORLD_LOAD_QUEUED (1) | The worker request has been accepted. |
WORLD_LOAD_READING (2) | The source manifest is being read and validated. |
WORLD_LOAD_DECODING (3) | Required assets are being decoded. |
WORLD_LOAD_FINALIZING (4) | Main-thread resources and entities are being created under the time budget. |
WORLD_LOAD_FAILED (5) | The load ended with an actionable error. |
WORLD_LOAD_CANCELLED (6) | Cancellation completed without publishing a partial world. |
WORLD_LOAD_DEFAULT is 0 and
WORLD_LOAD_NO_STREAMING is 1. Asset-kind queries return
WORLD_ASSET_KIND_MODEL (1), TEXTURE (2),
HEIGHTMAP (3), SOUND (4), or SHADER
(5). Use the named constants in programs; the numeric values are documented for
logs, tools, and saved diagnostics.
CancelWorldLoad is cooperative. Poll until the state becomes
cancelled, or call FreeWorld to invalidate a loading handle
immediately and release its work when the worker unwinds. A failed or cancelled
load never changes the selected graphics or audio world.
A .world file is strict UTF-8 JSON. Relative asset paths are
resolved from the file containing them, not from the process working
directory. A document can contain placed entities, an asset-only preload list,
or both.
{
"format": "blitz3d.world",
"version": 1,
"id": "level.castle",
"settings": {
"ambient": [64,72,96],
"collisions": [
{"sourceType":1,"destinationType":11,
"method":"polygon","response":"slide"}
]
},
"assets": [
{"id":"height","kind":"heightmap","source":"height.bmp","loading":"required"},
{"id":"ground","kind":"texture","source":"ground.jpg","loading":"required"},
{"id":"castle","kind":"model","source":"castle.glb","loading":"required"}
],
"entities": [
{
"id":"land",
"transform":{"position":[-1000,-100,-1000],"scale":[7.8125,100,7.8125]},
"components":[
{"type":"terrain","heightmap":"height","detail":750,"morph":true,
"shading":true,"material":{"mode":"legacy","texture":"ground",
"textureScale":[10,10]}},
{"type":"collision","entityType":11,"pickMode":"polygon"}
]
},
{"id":"keep","components":[{"type":"model","asset":"castle"}]}
],
"extensions": {}
}
World sources use Blitz3D's native left-handed local coordinate space:
positive X is right, positive Y is up, and positive Z is forward. Values are
ordinary Blitz units; version 1 performs no hidden unit conversion. A transform
defaults to position [0,0,0], scale [1,1,1], and an
identity quaternion [0,0,0,1]. Quaternion order is
x,y,z,w; the loader rejects a zero/non-finite quaternion and
normalizes every valid one. Scale follows ScaleEntity, including
finite zero or negative components.
Model assets are decoded in their normal Blitz import space and do not
inherit the mutable process-wide LoaderMatrix setting. Put an
editor-authored conversion in the entity transform instead. This keeps a world
deterministic even when its worker starts later than submission.
| Kind | Version 1 preparation |
|---|---|
model | B3D, X, 3DS, glTF, or GLB geometry and dependencies; use options.animated for an animated hierarchy. |
texture | CPU image decode followed by main-thread canvas creation; options.flags matches LoadTexture. |
heightmap | Immutable 16-bit samples used to construct an independent mutable terrain. |
sound | RIFF/WAVE decode; options.spatial selects 3D sound behavior. |
shader | Source/dependency preparation on a worker and pipeline creation on the main thread. |
loading is required, streaming, or
manual. Required assets gate WorldReady and may be
referenced by placed entities. Streaming assets start automatically after the
manifest is prepared and are reported by WorldStreaming. Manual
assets begin when FindWorldAsset first resolves them; poll
WorldAssetReady and WorldAssetError before using a
typed accessor.
Entities have stable IDs, optional parent IDs, local position/rotation/scale,
visibility, enabled state, string metadata, and components. Version 1 supports
model, terrain, camera, light, listener, collision, and marker components.
FindWorldEntity returns a published entity by ID.
WorldEntityMetadata reads authoring metadata without scanning entity
names.
Terrain supports a required heightmap, detail, morphing, shading, LOD ranges,
legacy texture scaling, and layered terrain materials. Once the world is ready,
the result is an ordinary terrain: TerrainY,
TerrainHeight, collisions, and ModifyTerrain work as
normal. A material uses either the legacy members
(texture and a positive textureScale) or the
layers members, never both. Layered materials contain one to four
textures with positive uvScale values. Version 1 maps these to the
uniform scale accepted by TerrainLayer, so both components must
match. More than one layer requires a splatMap. Sharing a heightmap
never shares later terrain deformation.
preload=LoadWorldAsync("asset-preload.world")
While Not WorldReady(preload)
If WorldLoadState(preload)=WORLD_LOAD_FAILED Then RuntimeError WorldLoadError(preload)
Flip
Wend
modelAsset=FindWorldAsset(preload,"ship")
textureAsset=FindWorldAsset(preload,"ship-paint")
ship=CreateWorldAsset(modelAsset)
paint=WorldAssetTexture(textureAsset)
EntityTexture ship,paint
Typed texture, sound, and shader accessors return ordinary public handles.
They remain valid after the source world is freed and must be released with the
matching FreeTexture, FreeSound, or
FreeShader. A created model entity belongs to its destination world.
Compatible texture loads and compatible assets requested by several worlds
reuse ready shared data where their options match.
WorldReady does not wait for assets declared
streaming. Use WorldStreaming and
WorldStreamingProgress if the game wants to show their progress.
Pass WORLD_LOAD_NO_STREAMING to disable automatic optional
streaming. Required content and manually requested assets are unaffected.
The shipped b3dworldc command validates the same format used by
the runtime:
b3dworldc level.world b3dworldc --no-files editor-draft.world b3dworldc --quiet worlds/*.world
The machine-readable contract is installed as
world/world-v1.schema.json. Runtime validation additionally rejects
duplicate keys, malformed UTF-8, non-finite values, excessive nesting and
document sizes, invalid references, parent cycles, unsupported required
extensions, and missing dependencies.
An editor may normalize whitespace and property order, but it must preserve
the order of asset, entity, component, layer, and collision arrays because that
order is observable. It must keep explicit IDs stable, retain unknown optional
properties and the complete JSON value of every unknown optional namespaced
extension, and refuse to silently discard an unknown extension whose
required member is true.
Keep relative asset paths relative to the .world file; do not
replace them with workstation-specific absolute paths. Emit strict UTF-8 JSON,
finite numbers, unique object keys, and quaternion components in
x,y,z,w order. Saving must not copy runtime terrain deformation or
other gameplay state back into the authoring source. Run b3dworldc
after every save and treat the runtime validator as authoritative where JSON
Schema cannot express duplicate keys, finite-number rules, path resolution, or
cross-reference semantics.
SetWorld, SetAudioWorld, update, render, or entity creation against a loading handle. Poll it first.WorldLoadError contains the dependency or validation summary for a failure.UpdateAsyncLoads -1 so main-thread finalization is not starved.samples/worlds/Async_Loading_Castle.bb loads the classic Castle terrain and static environment while an animated loading world remains responsive.samples/worlds/Asset_Only_Preload.bb consumes an asset-only manifest through stable IDs and demonstrates public-handle lifetime.