This page summarizes the ExoJS refactors that examples and integration code need to follow.
The normal rendering flow is now:
Applicationowns frame presentation.Scene.update(delta)mutates state.Scene.draw(runtime)submits drawables.Applicationcallsdisplay()on the active render runtime.
Use this in scene code:
public draw(runtime: SceneRenderRuntime): void {
this.root.render(runtime);
}The root container is a structural scene-graph entry point, not an implicit full-scene render. Scenes still keep explicit control over which subtree renders:
public draw(runtime: SceneRenderRuntime): void {
this.world.render(runtime);
this.ui.render(runtime);
}Do not use:
renderManager.draw(...)renderManager.display()from scene code
Use drawable submission instead:
drawable.render(runtime)root.render(runtime)
View switching now has a stable runtime convenience:
app.renderManager.setView(view);This forwards to the current render target:
app.renderManager.renderTarget.setView(view);new Application() now defaults to automatic backend selection:
- prefer WebGPU when available
- fall back to WebGL2 when WebGPU is unavailable or initialization fails
Explicit backend selection still works:
new Application({ backend: { type: 'webgpu' } });
new Application({ backend: { type: 'webgl2' } });
new Application({ backend: { type: 'auto' } });IApplicationOptions->ApplicationOptionsIWebGl2BackendConfig->WebGl2BackendConfigIWebGpuBackendConfig->WebGpuBackendConfigIAutoBackendConfig->AutoBackendConfigISceneData->SceneData
IRenderBackend->SceneRenderRuntimeIRenderManager->SceneRenderRuntimeIRenderer->RendererIWebGpuRenderAccess->WebGpuRenderAccessIWebGl2RenderBackend->WebGl2RendererRuntime
IDatabase->DatabaseIResourceFactory->ResourceFactoryIMedia->MediaIAbstractMediaInitialState->AbstractMediaInitialState
ICloneable->CloneableIDestroyable->DestroyableIWithBoundingBox->HasBoundingBoxICollidable->CollidableICollisionResponse->CollisionResponseIShape->ShapeLikeIPoint->PointLikeILine->LineLikeIRectangle->RectangleLikeICircle->CircleLikeIEllipse->EllipseLikeIPolygon->PolygonLikeIPlaybackOptions->PlaybackOptions
IAudioAnalyserOptions->AudioAnalyserOptionsILoaderOptions->LoaderOptionsIResourceQueueItem->ResourceQueueItemIResourceTypeMap->ResourceTypeMapIFontFactoryOptions->FontFactoryOptionsICreateCanvasOptions->CreateCanvasOptionsITextStyleOptions->TextStyleOptionsISamplerOptions->SamplerOptionsISpritesheetFrame->SpritesheetFrameISpritesheetData->SpritesheetDataIShaderRuntime->ShaderRuntimeIRenderBufferRuntime->RenderBufferRuntimeIVertexArrayObjectRuntime->VertexArrayObjectRuntimeIParticleProperties->ParticlePropertiesIParticleEmitter->ParticleEmitterIParticleAffector->ParticleAffector
Non-input public enum members now use PascalCase consistently.
Examples and integrations should update member access accordingly:
BlendModes.NormalRendererType.SpriteRenderingPrimitives.TrianglesScaleModes.LinearWrapModes.ClampToEdgeApplicationStatus.Running
The input layer now uses ordered GamepadDefinition[] resolution.
Use:
gamepadDefinitions
Do not use the removed older gamepad mapping/profile configuration path.
Canonical generic gamepad channel names are now the intended public surface:
ButtonSouthButtonEastButtonWestButtonNorthLeftStickXRightStickY
Avoid platform-specific alias naming in new examples.