Skip to main content

PrefabMeta

Struct PrefabMeta 

Source
pub struct PrefabMeta {
Show 13 fields pub prefab_id: String, pub structure: Option<StructureMeta>, pub structure_set: Option<TileSet>, pub anchors: BTreeMap<String, Anchor>, pub connectors: Vec<Connector>, pub lighting: Option<Lighting>, pub license: Option<License>, pub walk_y: Option<i32>, pub waterline_y: Option<i32>, pub shown_faces: Vec<String>, pub spatial_contract: Option<SpatialContract>, pub footprint_class: Option<String>, pub extra: BTreeMap<String, Value>,
}
Expand description

A prefab’s sibling metadata file.

Fields§

§prefab_id: String

The DSL prefab id, prefab/<id>.

§structure: Option<StructureMeta>

The structure-template reference, for a piece whose blocks fit one template.

Exactly one of this and Self::structure_set is present — see the type’s own note on the two packagings, and Self::from_json, which is where “exactly one” is enforced.

§structure_set: Option<TileSet>

The tile set, for a piece whose blocks did not fit one template.

Packaging, not authoring. A zone past the 48-per-axis structure cap ships as several .nbt files plus this manifest; everything else about the document — the id, the zone-local anchors, the connectors, the one lighting block, the one provenance row — is what it is for a single-template piece, because it describes the same building. Nothing that refers to a piece may ask which of the two it is: read Self::templates.

This was a second document type (TileSetMeta, in the schem crate), field-for-field this one with structure swapped for structure_set. The copy had already lost waterline_y, so a tiled shore could not declare the waterline the ocean-horizon invariant (DW0344) keys off and went silently unchecked. One document is what makes that class of drift unrepresentable.

§anchors: BTreeMap<String, Anchor>

Named anchors, keyed by DSL anchor name. {} for a piece that declares none.

§connectors: Vec<Connector>

Jigsaw sockets. [] for a piece that is placed directly rather than drawn from a pool.

§lighting: Option<Lighting>

The lighting declaration.

Absent means legacy metadata that predates the field, which is a different claim from {"profile": "unmeasured"} — the positive statement that a measurement is owed.

The block’s own shape is Lighting, and it is the one part of this document that still refuses a key it does not know. Its job is a rule about values — a measured profile must carry its measurement, an unmeasured one must not — so a misspelled measurement key there is a claim quietly becoming its own absence, which the profile/measurement agreement alone does not catch for rationale or method. The cost is real and is stated where an author will meet it (docs/reference/prefab-procedure.md §9): a key added inside lighting is a hard parse failure for an older engine, so adding one is a dsl_version matter rather than a metadata edit.

§license: Option<License>

Licence, provenance prose, and the machine-readable provenance row.

§walk_y: Option<i32>

The local y of this piece’s own walk plane — the cell a body’s feet occupy when it stands on the piece’s principal floor (spec-0060 §4).

This is the number an area’s origin is DERIVED from on a horizon whose datum is a walk plane: an ocean world’s walk plane is SEA_LEVEL + 1, so an area seating this piece is placed at walk_ref_y - walk_y and the piece stands one block above the sea, which is the vanilla-normal beach relationship. A keep interior declaring 1 is seated at 62 and stands dry at 63; an island piece declaring 3 is seated at 60.

It has no default, and that is the decision (spec-0060 §4.1). A default is the retired global datum wearing a different name: it would be right for the one tileset it was copied from and silently wrong for every other, and the piece that lands under the sea because of it floods on boot with nothing looking. A piece a campaign seats without one is DW0886.

It is a MEASUREMENT of the piece, so it is written by the generator that built the piece and never typed by hand (CLAUDE.md: a census derivable from the object is never hand-written).

§waterline_y: Option<i32>

The local y of this piece’s top authored water block — its waterline — for open-air pieces built to a tileset convention that authors a sea.

Two rules read it, and they ask different questions. DW0887 asks whether the claim is TRUE — whether the piece’s own bytes put a water block at that plane and none above it — and refuses a declaration that is a fiction wherever the document and its .nbt are read together. DW0344 asks whether the PLACEMENT honours it: in a horizon: ocean world the declared waterline must land at world sea level.

Absent for pieces that author no sea, which neither rule then judges. A piece that authors water and declares nothing is not refused by DW0887; under ocean its placement is DW0344’s subject and under void its runoff is DW0318’s.

§shown_faces: Vec<String>

The sides of this piece the player is meant to see — the piece’s own claim that a given face is finished exterior surface rather than the cut edge of something that belongs inside a hill.

Local side names, in the piece’s own frame, from the same six-word vocabulary ContractFace::dir uses: east west up down south north. They turn with the placement, so a piece rotated a quarter turn shows the side it was built to show.

It is the third thing a piece says about its own outside, and the three are different claims about the same object rather than one claim written three ways: Self::waterline_y says where the piece meets the sea, SpatialContract::faces says where a body crosses a side, and this says which sides are finished. None of the others can stand in for it — a cave with a mouth declares one walk face and is still a block of rock on the other five — which is why DW0885 reads this and not them.

Absent means no side is shown, and that is the load-bearing default: a piece authored to be buried is exactly a piece that writes nothing here, so the silence has to be the strict answer or the defect declares itself by omission. What discharges the obligation for such a piece is the world burying it, which is geometry the declaration cannot fake.

§spatial_contract: Option<SpatialContract>

The piece’s spatial contract, when it declares one.

Absent means legacy metadata — the piece makes no spatial claim — exactly as an absent lighting block differs from unmeasured.

§footprint_class: Option<String>

The size class of box this piece is built to fill — a name from the metrics table’s size-class.* ladder (spec-0050 §5).

Optional for the library at large, and that is deliberate rather than lax: every piece in the library predates the field, and DW0848 binds only where the claim is made. What is not optional is the claim being true — a piece declaring a class its own bytes could serve no box of is refused at admission and again wherever a detail plan consumes it, so a pre-check-era piece cannot be consumed unjudged.

Absent means what absence means everywhere in this document: the claim is not made. A piece bound by a details[] row is still checked for exact frame equality (DW0843) whether or not it declares — that is the consumer’s exact check, and this is the library’s approximate one.

§extra: BTreeMap<String, Value>

Every top-level key this version does not model, kept verbatim so that reading and writing the document is not the same as editing it.

A reader that wants to report one has it in hand; a reader that does not care carries it through. Emitted after the modelled keys, in key order.

Implementations§

Source§

impl PrefabMeta

Source

pub fn from_json(text: &str) -> Result<PrefabMeta, String>

Parse metadata from JSON text.

The one reader of both packagings. “Which shape is this” has exactly two answers and no third, so a document declaring neither block, or both, is refused here rather than handed half-read to a step that will place some of its blocks. A tile set is validated as it is read (TileSet::validate) for the same reason: a manifest that does not tile its own volume reassembles into a building with a hole in it and reports success.

Source

pub fn templates(&self) -> Vec<PieceTemplate<'_>>

Every structure template this piece’s blocks arrive in, in a deterministic order (grid order for a tile set).

Empty only for a value built in code that declares neither block, which Self::from_json refuses — nothing read from disk is in that state.

Source

pub fn size(&self) -> [i32; 3]

The piece’s extent [x, y, z] — the WHOLE building, whichever packaging its blocks arrived in. [0, 0, 0] only for the value Self::templates documents as unreachable from disk.

Source

pub fn data_version(&self) -> Option<i32>

The MC data version the piece’s templates target (ADR-0009), when it declares one.

Source

pub fn is_tiled(&self) -> bool

True when the piece’s blocks arrive as several templates — a fact about packaging that only a tool reporting on packaging may ask.

Source

pub fn base(&self) -> &str

The filename stem the piece’s files are named from — the single template’s id, or the tile set’s base. They are the same concept under two keys, so a diagnostic that wants to name the piece’s document asks here rather than reaching into one packaging.

Source

pub fn grid(&self) -> [i32; 3]

The tile grid [x, y, z]; [1, 1, 1] for a piece that fit one template. Packaging, like Self::is_tiled.

Source

pub fn read(path: &Path) -> Result<Option<PrefabMeta>, String>

Read the document at path, or Ok(None) when there is no file there.

Source

pub fn beside_nbt(nbt_path: &Path) -> Result<Option<PrefabMeta>, String>

Load <nbt_path>.json (the sibling metadata), or Ok(None) when absent.

Source

pub fn to_json(&self) -> String

Serialize as canonical pretty JSON with a trailing newline.

Source

pub fn schema() -> Value

The JSON Schema of this document, for delvec schema --stage prefab-metadata.

Deliberately not part of --stage all. all is the campaign DSL’s staged documents, and the gallery’s coverage gate enumerates its units from exactly that export: a library-asset document folded into it would demand a gallery stage-document binding for every field of a file no stage document contains. A prefab’s declarations are proven where they are read — shown_faces by the exposure ledger, walk_y and waterline_y by the seating and waterline bindings — which is a binding a schema unit could not give them.

It is exported anyway, and for the reason the walk record is: this is the command an author is told to run to see the shape of a document they must write, and a piece’s metadata is one of those.

Source

pub fn unknown_keys(&self) -> Vec<(&str, &str)>

Every key of this document — top level and per anchor — that this version does not model, as (where, key) pairs in a stable order.

where is "" for a top-level key and the anchor’s name for an anchor key. A reader that wants to say something about a key it kept asks here; nothing has to re-open the file to find out.

Source

pub fn skeleton( id: &str, size: [i32; 3], data_version: i32, generator: &str, license: License, ) -> PrefabMeta

A minimal skeleton for a freshly admitted external piece.

Source

pub fn edit_anchor(&mut self, name: &str, edit: AnchorEdit)

Annotate a named anchor’s place and purpose, creating the anchor when it is not there yet.

An anchor is an object, not a value. A tool that names where the anchor is has said nothing about the hardware the prefab wired at it (Anchor::dispenser, Anchor::trigger_block), about which contract element an exporter resolved it into (Anchor::resolves_to), or about any key this version has never heard of (Anchor::extra) — so none of those is touched. Replacing the whole anchor instead is the same silent deletion this type exists to prevent at the top level, one level down, and on the block of the document that has grown most often.

The place itself is one property expressed two ways — a cell or a region — so an edit redeclares all four of its fields together and a pos does supersede a stale region.

The role is a fifth field and not a fifth way of saying where: what an anchor is for is a property of the anchor, so it is written when the edit speaks about it, cleared when the edit says it has none, and left alone when the edit says nothing (AnchorEdit::role).

Source

pub fn gate_anchor(&self, name: &str) -> Result<Option<GateAnchor>, String>

The ONE authority on the region and block a gate anchor names, in piece-local coordinates.

A gate anchor is declared in one of two forms, and the compiler must read both identically:

  • explicitly — the anchor carries its own region and block, which is how a hand-authored piece has always written one;
  • through the piece’s spatial contract — the anchor carries a resolves_to of bar:<region>, which is what an exporter writes. The cells and the block already live in that edge’s ContractBar, so repeating them on the anchor would be a second authority for one fact, and the exporter rightly does not.

Nothing derived either form from the other, and the whole compiler read only the first. A piece declaring its gates the second way therefore had no gate at all: the anchor resolved to a bare point, every verb that fills or clears a gate was refused (DW0343), and the information the refusal asked for was sitting in the same document.

Both readers ask this function and nothing else — the planner, which resolves the anchor to world cells, and AnchorRegistry’s prefab implementation, which answers whether the compiler can fill it — so the two cannot come to disagree about what a gate is or where it stands.

Three answers, and the third is the one that earns the Result:

  • Ok(None) — not a gate anchor. A point anchor, a trap anchor, or an anchor whose resolves_to names a space, a no_body region, a via volume or a way. None of those is a thing content fills or clears.
  • Ok(Some(gate)) — a gate, and here is the box and the block.
  • Err(why) — declared as a gate and not resolvable to one fillable box. Refused rather than guessed, because every alternative writes blocks somewhere the document did not ask for. why is a clause the caller folds into its own diagnostic.

A way is deliberately not a gate here. Its opens is a direction — laid cells are absent as built and appear when opened, cleared cells stand and are voided — and the single-region gate model carries no direction to put it in. Reading one as a gate would silently pick a direction for the author.

Source

pub fn add_connector(&mut self, c: Connector)

Append a socket connector (idempotent by local_pos + facing).

Trait Implementations§

Source§

impl Clone for PrefabMeta

Source§

fn clone(&self) -> PrefabMeta

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PrefabMeta

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for PrefabMeta

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl JsonSchema for PrefabMeta

Source§

fn schema_name() -> Cow<'static, str>

The name of the generated JSON Schema. Read more
Source§

fn schema_id() -> Cow<'static, str>

Returns a string that uniquely identifies the schema produced by this type. Read more
Source§

fn json_schema(generator: &mut SchemaGenerator) -> Schema

Generates a JSON Schema for this type. Read more
Source§

fn inline_schema() -> bool

Whether JSON Schemas generated for this type should be included directly in parent schemas, rather than being re-used where possible using the $ref keyword. Read more
Source§

impl PartialEq for PrefabMeta

Source§

fn eq(&self, other: &PrefabMeta) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for PrefabMeta

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for PrefabMeta

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.