Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions content/engine/scene-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ 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
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.

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.

For a scene-format change, test round trips, deterministic ordering, old-version migration, unknown data, invalid components, failed saves, and backup recovery. Update both the engine-local guide and published documentation when user-visible behavior changes.
55 changes: 55 additions & 0 deletions docs/scene-lifecycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 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(())
}
```

Replace the paths with valid saved scene files. The example leaves the level
active and loaded, and releases the menu world. `load(SceneDocument)` also
accepts an owned document created or loaded by the host.

| Operation | Result |
| --- | --- |
| `load(document)` / `load_file(path)` | Build a world and return its scene ID, without selecting it. |
| `switch(id)` | Select a loaded world. An unknown or unloaded ID returns `NotLoaded`. |
| `unload(id)` | Drop that world and its entities/components. Unsaved edits are discarded. |
| `is_loaded(id)` / `loaded_ids()` | Inspect the worlds currently owned by the manager. |
| `active_id()` / `active_world()` / `active_world_mut()` | Inspect or edit the selected world; initially `None`. |
| `world(id)` / `world_mut(id)` | Borrow any loaded world by ID. |

Switching retains loaded worlds and their edits. Switching to the current world
is allowed. Unloading the active world clears the selection, even if other worlds
remain loaded. Load or switch another world explicitly. Duplicate loads return
`AlreadyLoaded`; unloading an unknown ID returns `NotLoaded`. Failed operations
preserve the loaded set and selection.

The manager retains no unloaded entry, document, serialized bytes, or world cache.
Reloading reads the file again and builds a fresh world. File loading rejects
incompatible versions, damaged data and checksum mismatches, and does not read
backup files. Inspect `SceneManagerError` for I/O, parsing or world validation
failures; open and save externally edited scenes in the editor to refresh their
checksum before runtime loading.

The host must tick and render the selected world, and coordinate script callbacks,
physics, audio and GPU resources separately. The manager owns ECS world data only;
assets or resources retained elsewhere in the host are outside its ownership.
Loading a document does not execute its startup scripts. Save authored changes
explicitly before unloading if they should survive.
1 change: 1 addition & 0 deletions lib/docs-catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type DocGroup = { label: string; docs: DocEntry[] };

const categoryGroups: DocGroup[] = [
{ label: "Start here", docs: [
{ slug: "guides/scene-lifecycle", title: "Load, unload and switch scenes (Rust)", description: "Explicit ownership and active selection of loaded scene worlds in Rust hosts.", source: "docs/scene-lifecycle.md" },
{ slug: "engine", title: "Using Rustic Engine", description: "Create a game, attach scripts, and learn how to use the editor and gameplay API.", source: "content/engine.md" },
{ slug: "tutorials/first-playable-scene", title: "First playable scene", description: "Create an object, attach Lua and test the startup callback.", source: "content/tutorials/first-playable-scene.md" },
{ slug: "api/overview", title: "API overview", description: "Rustic API concepts, language support, and execution rules.", source: "api:overview" },
Expand Down
Loading