From 2366b1087236ec520192d946c26414e0d10fc0d0 Mon Sep 17 00:00:00 2001 From: Jamie Wells Date: Wed, 28 Oct 2026 01:07:03 +0000 Subject: [PATCH 1/3] docs: document scene lifecycle APIs in every script language --- content/engine/scene-system.md | 8 +- docs/Scripting/sceneObjects.md | 6 +- docs/scene-lifecycle.md | 217 +++++++++++++++++++++++++-------- lib/api-docs.ts | 46 +++++++ lib/api-reference-markdown.ts | 10 +- lib/api-reference.ts | 8 ++ lib/docs-catalog.ts | 3 +- 7 files changed, 240 insertions(+), 58 deletions(-) diff --git a/content/engine/scene-system.md b/content/engine/scene-system.md index 07e6f37..f74cc14 100644 --- a/content/engine/scene-system.md +++ b/content/engine/scene-system.md @@ -18,11 +18,11 @@ The current scene schema is version 2. Version 1 migrates in memory; future sche ## Editor and runtime ownership -Rust hosts can use [`SceneManager`](/docs/guides/scene-lifecycle) to explicitly -load worlds, switch only to loaded worlds, and drop worlds on unload. Loading +Scripts use [`game.scene`](/docs/guides/scene-lifecycle) to load scenes, switch +only to loaded scenes, and unload their worlds and runtime resources. Loading does not activate a scene; unloading the active scene clears the selection. -This API manages world ownership; hosts coordinate scripting, physics, audio -and rendering separately. +Global scripts remain available across transitions. Rust hosts can also use +`engine_world::SceneManager` for lower-level ECS world ownership. The editor owns the authored document. Play starts from an immutable staged snapshot and creates a separate runtime world. Stopping Play does not automatically overwrite the authored scene; the runtime-change review/apply operation is explicit and undoable. diff --git a/docs/Scripting/sceneObjects.md b/docs/Scripting/sceneObjects.md index 7c4b7de..d9b08bd 100644 --- a/docs/Scripting/sceneObjects.md +++ b/docs/Scripting/sceneObjects.md @@ -32,8 +32,10 @@ return { to return to the authored scene, or use the editor's runtime-change workflow when you want to retain supported changes. -Only the currently loaded scene is accessible. Referring to another scene does -not load it. Names are case-sensitive. Paths are resolved when a call applies; +Only the active scene is accessible through object paths. Other loaded scenes +retain their state until selected with `game.scene.switchTo(name)`. Use the +[scene lifecycle API](/docs/guides/scene-lifecycle) to load and unload them. +Referring to another scene does not load it. Names are case-sensitive. Paths are resolved when a call applies; if you rename or reparent an object, use its new path in subsequent calls. These functions edit engine attributes, not another script's public properties or arbitrary user-defined functions. diff --git a/docs/scene-lifecycle.md b/docs/scene-lifecycle.md index c70d567..5892e65 100644 --- a/docs/scene-lifecycle.md +++ b/docs/scene-lifecycle.md @@ -1,55 +1,172 @@ -# Load, unload and switch scenes (Rust) - -`engine_world::SceneManager` owns explicitly loaded scene worlds. Use this API -in a Rust host with a path dependency on `crates/engine-world`. It is not exposed -as a Lua, JavaScript, C, C++, C# or Python script function. No script attachment -is required. Editor Play still uses its existing single-scene runtime. - -```rust -use engine_world::{SceneManager, SceneManagerError}; - -fn main() -> Result<(), SceneManagerError> { - let mut scenes = SceneManager::new(); - let menu = scenes.load_file("assets/menu.rscene")?; - let level = scenes.load_file("assets/level.rscene")?; - scenes.switch(menu)?; - scenes.switch(level)?; - scenes.unload(menu)?; - assert!(!scenes.is_loaded(menu)); - assert!(scenes.switch(menu).is_err()); - assert_eq!(scenes.active_id(), Some(level)); - Ok(()) +# Load, unload and switch scenes + +Use `game.scene` to manage scenes from Lua 5.4, Luau, JavaScript, Python, C++, +C#, Java, PHP and HTML with inline JavaScript. C uses `Game.scene`. +The scene open when Play starts is already loaded and active. + +## Set up and run + +1. Save two scenes with unique document names, such as **Menu** and **Level**. + Save Level as `scene/level.scene` (legacy `scenes/*.rscene` also works). + Scene names and scene IDs must both be unique among loaded scenes. +2. Open Menu. Create a **Global Startup Script** through the Programming menu + and select a language. Paste the matching example into its Start/on_start + callback, keeping the generated imports and callback registration. + Object component and scene startup scripts can call these APIs too; they + belong to their scene and end when that scene is unloaded. Global scripts + remain alive and can load a scene even when none is active. +3. Save all target scenes before pressing **Play**. Play snapshots include scene + files from `scene/` and `scenes/`; keeping a file on disk does not load its + world into runtime memory. Edits made on disk after Play starts require a + new Play session. The initially open scene includes its current editor state. +4. Run the example. Level becomes the active scene on the next scene transition + boundary. Menu is unloaded, its scene/object scripts are destroyed, and its + world, physics, decoded audio, capture state and script runtimes are released. + Level must contain a camera to produce a camera view. + +```lua +return { + Start = function() + local level = game.scene.load('scene/level.scene') + assert(game.scene.isLoaded(level)) + game.scene.switchTo(level) + game.scene.unload('Menu') + assert(not game.scene.isLoaded('Menu')) + end, +} +``` + +```javascript +// JavaScript, or inside a