Prefab loading
A prefab is a JSON file at data/<namespace>/prefabs/<id>.json describing a reusable in-world structure — block volumes, anchors, lobby zones, sub-prefab references, screens, labels. The Prefab record is the typed shape after parsing; PrefabElement is the sealed list of element kinds; PrefabMigrations runs forward-migration steps on older files so the codec only ever sees the current schema.
When to use it
Section titled “When to use it”- You want game geometry defined in data files, not Java.
- You want one prefab template to spawn at many sites with different bindings.
- You want
/reloadto re-instantiate edited prefabs without restarting.
package me.zlex.conduit.prefab;
public record Prefab(int schema, Map<String, Integer> params, List<PrefabElement> elements) { public static final int SCHEMA_VERSION_CURRENT = 2;
public record Id(Identifier identifier) { public static Id of(String namespace, String path); }
public static final Codec<Prefab> CODEC;}
public sealed interface PrefabElement { String type();
record BlockVolume(BlockVolumeShape shape, String blockState, IntVec3 from, IntVec3 to) implements PrefabElement {}
// Anchor, Zone, Screen, Label, SubPrefab — see PrefabElement source.}
public final class PrefabMigrations { public static JsonObject upgrade(JsonObject root);}SceneStore is the loader — it discovers, parses, and registers every prefab on server start and on /reload. You don’t usually call the codec yourself.
Example
Section titled “Example”A minimal prefab JSON:
{ "schema": 2, "params": { "xMin": -8, "xMax": 8, "zMin": -8, "zMax": 8, "yFloor": 100, "yCeiling": 105 }, "elements": [ { "type": "block-volume", "shape": "cuboid", "block": "minecraft:barrier", "from": ["@xMin", "@yFloor", "@zMin"], "to": ["@xMax", "@yFloor", "@zMax"] }, { "type": "block-volume", "shape": "walls", "block": "minecraft:barrier", "from": ["@xMin", "@yFloor + 1", "@zMin"], "to": ["@xMax", "@yCeiling", "@zMax"] } ]}Loaded by the engine via:
import me.zlex.conduit.prefab.Prefab;import me.zlex.conduit.prefab.SceneStore;
Prefab.Id id = Prefab.Id.of("my-mod", "arena-room");Prefab prefab = SceneStore.prefab(id); // null if not loadedschemais a required integer field; the engine refuses files with a schema newer thanSCHEMA_VERSION_CURRENT.- Migration
v1 → v2swapped the cardinalfacingstring on screen/label elements for an integeryawDegreesfield. The scaffold runs in order so future migrations don’t have to bev1 → vNjumps. - The codec validates ordering —
from/tocorners are normalised at instantiation time, not at parse time.