Files
Oxide/docs/prefabs.md
T
Homer Simpson 9eead719b0 Import Oxide engine (Stages 0–10) under MIT license
Full project snapshot migrated to new Gitea remote without history:
engine, editor, physics, script, examples, tests, docs, and assets.
Relicensed from GPLv3 to MIT and updated repo URLs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 20:41:02 +02:00

3.7 KiB

Prefabs

oxide_engine::prefab provides named spawn templates. A prefab is a thing you can "drop into the scene" that already carries a set of components — a Cube, a Camera, a Directional Light — without the editor or game code hard-coding one spawn path per kind of object.

An entity is its components — a prefab is just data

Oxide has no parallel "object type" system. An entity is its set of components (see scene.md and reflection.md). A Prefab is therefore nothing more than a name plus a list of (component name, RON value) specs, applied on spawn through the TypeRegistry:

"Spawn a Cube" = spawn an entity, then set its MeshRenderer to a cube.

Because a spec is the same name-keyed RON the editor and scripts already use, prefabs are pure data: serializable, dual-editable, and free of bespoke code. This is what lets the editor's add-menu be data-driven — it lists the prefabs in a PrefabRegistry instead of one hard-coded button per type.

The types

Every spawned entity already carries the node-baked Node, Transform, and Layer (auto-attached by Scene::spawn); a prefab's specs are layered on top. A spec named "Transform" overrides the identity transform spawn starts with, so a prefab can place itself.

Spawning

use oxide_engine::prelude::*;
use oxide_engine::prefab::{ComponentSpec, Prefab, PrefabRegistry};
use oxide_engine::reflect::TypeRegistry;

// A registry that knows how to round-trip MeshRenderer by name.
let mut types = TypeRegistry::new();
types.register_reflected::<MeshRenderer>("MeshRenderer");

// A "Cube" prefab: a default MeshRenderer (shape = Cube).
let mut prefabs = PrefabRegistry::new();
prefabs.register(
    Prefab::new("Cube")
        .with(ComponentSpec::of("MeshRenderer", &MeshRenderer::default()).unwrap()),
);

let mut scene = Scene::new();
let cube = prefabs.spawn("Cube", &mut scene, &types).unwrap();        // root entity
let child = prefabs.spawn_child("Cube", cube, &mut scene, &types);    // parented

PrefabRegistry::spawn returns the new entity, or None if the name isn't registered. Application is best-effort: a spec whose type isn't registered or whose RON doesn't parse is skipped (the entity is still created with whatever applied). Validate a prefab against a registry up front with PrefabRegistry::unknown_specs, which lists the type names the registry doesn't know — handy for catching authoring typos.

Relationship to "multiple of the same component"

Prefabs spawn one entity. Because an archetypal ECS allows only one component of a given type per entity, a prefab that needs several of a thing (e.g. multiple meshes) composes them as child entities — spawn the prefab, then spawn_child the extras (each a real, gizmo-movable node). See the component-multiplicity notes in PLAN.md.