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>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# 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](scene.md) and [reflection.md](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`](reflection.md):
|
||||
|
||||
> "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
|
||||
|
||||
- [`ComponentSpec`] — `{ type_name, ron }`: one component to attach. Build it
|
||||
from a value with [`ComponentSpec::of`] (serializes to RON) or from a raw
|
||||
string with [`ComponentSpec::new`].
|
||||
- [`Prefab`] — `{ name, components }`: the node name plus the specs to apply.
|
||||
Built fluently with [`Prefab::new`] + [`Prefab::with`].
|
||||
- [`PrefabRegistry`] — prefabs keyed by name; the source for an add-menu.
|
||||
|
||||
Every spawned entity already carries the node-baked `Node`, `Transform`, and
|
||||
`Layer` (auto-attached by [`Scene::spawn`](scene.md)); 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
|
||||
|
||||
```rust
|
||||
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`.
|
||||
|
||||
[`ComponentSpec`]: ../engine/src/prefab.rs
|
||||
[`ComponentSpec::of`]: ../engine/src/prefab.rs
|
||||
[`ComponentSpec::new`]: ../engine/src/prefab.rs
|
||||
[`Prefab`]: ../engine/src/prefab.rs
|
||||
[`Prefab::new`]: ../engine/src/prefab.rs
|
||||
[`Prefab::with`]: ../engine/src/prefab.rs
|
||||
[`PrefabRegistry`]: ../engine/src/prefab.rs
|
||||
[`PrefabRegistry::spawn`]: ../engine/src/prefab.rs
|
||||
[`PrefabRegistry::unknown_specs`]: ../engine/src/prefab.rs
|
||||
Reference in New Issue
Block a user