Skip to main content

BlockRegistry

Struct BlockRegistry 

Source
pub struct BlockRegistry { /* private fields */ }
Expand description

Every block id in the pinned version, with every property’s legal values — plus, per block, which of those properties are shape-carrying.

Implementations§

Source§

impl BlockRegistry

Source

pub fn v1_21_11() -> &'static BlockRegistry

The pinned 1.21.11 registry, parsed once per process.

Source

pub fn renames(&self) -> &BTreeMap<String, BlockRename>

The derived rename table, keyed by the id that no longer exists.

Source

pub fn loaded_id_at(&self, name: &str, data_version: i32) -> LoadedId<'_>

Which id the game will actually load, for a template that declares data_version.

Minecraft datafixes every structure .nbt it loads against the file’s own DataVersion, so a pre-pin template’s id is written in an older vocabulary and nothing may judge it as a name at the pin without first resolving it. This is that resolution, and it is deliberately conservative: a rename applies only where the file is at or below the last DataVersion the old id existed at, so a file in the gap between that bound and the pin resolves to LoadedId::Unresolved and is refused rather than waved through.

Source

pub fn len(&self) -> usize

How many blocks the pinned version has. A binding count: a check that reports zero here examined nothing.

Source

pub fn ids(&self) -> impl Iterator<Item = &str>

Every block id in the pinned version, namespaced, in sorted order.

Source

pub fn is_empty(&self) -> bool

Never true for the pinned registry; present because len is public.

Source

pub fn has(&self, name: &str) -> bool

True if name (namespaced, e.g. minecraft:stone) is a block.

Source

pub fn validate( &self, name: &str, properties: &BTreeMap<String, String>, ) -> Result<(), BlockError>

Check an id plus its properties.

A non-minecraft: namespace is accepted without inspection: a datapack may legitimately define its own blocks, and this registry has nothing to say about them. A bare id is read as minecraft:-namespaced, which is how every emitter in this repo writes one.

Source

pub fn validate_state_string(&self, state: &str) -> Result<(), BlockError>

Check a name[k=v,...] state string.

Source

pub fn judge_at( &self, name: &str, properties: &BTreeMap<String, String>, data_version: i32, ) -> StateJudgement

Judge a state against the pin and the carrying file’s DataVersion. See StateJudgement for the rule and its derivation.

Source

pub fn properties(&self, name: &str) -> Option<&BTreeMap<String, Vec<String>>>

Every property of name with its legal values, or None for an id the pinned version does not have.

Source

pub fn default_state(&self, name: &str) -> Option<&BTreeMap<String, String>>

The block’s default state — what the game resolves each unwritten property to. None for an id the pinned version does not have; an empty map for a block that has no properties at all.

This table says what a reader must ASSUME, never what an emitter may WRITE. A reader that is not a running server — the review page, a diff, a walk — has to fill an omitted property from somewhere, and this is where. An emitter filling one from here is a different act: it turns a state that said nothing into a state that explicitly asserts the default, and for every connection property the default is disconnected. So a completion pass over a library would answer Self::omitted_shape_carrying with the empty set for every block, forever — the shape rule (DW0735) and its whole library sweep would go green by ceasing to bind, over a library whose walls are still isolated posts. What an emitter owes instead is the connection derived from the blocks beside the cell (prefabs/invariants/src/connections.rs), and tools/ci/check-structure-emitters.py is what holds every emitter to it.

Source

pub fn unwritten( &self, name: &str, written: &BTreeMap<String, String>, ) -> BTreeMap<String, String>

The properties written leaves out, each with the value the game would fill it with. Empty when the state is complete — and empty, too, for an id this registry does not know, which has no defaults to offer and is already an BlockError::UnknownBlock to Self::validate.

Broader than Self::omitted_shape_carrying on purpose, and the two answer different questions: that one asks whether the block’s model is assembled from parts the property selects, this one asks what a reader that is not a running server would have to fill in to know what the file means at all. Being broader is exactly why it is not the repair for the narrower one — see Self::default_state, whose table this reads.

Source

pub fn shape_carrying(&self, name: &str) -> &[String]

The shape-carrying properties of name — the properties its blockstate definition’s multipart selectors test. Empty for a block whose model is not assembled from parts, for a foreign namespace, and for an unknown id (the unknown-block diagnostic owns that case).

Source

pub fn values(&self, name: &str, property: &str) -> &[String]

The legal values of one property of one block, empty when either is unknown or the namespace is foreign.

Source

pub fn is_stairs(&self, name: &str) -> bool

True when name is a stair block, derived from the pinned registry rather than from a list: a stair is the block whose shape property takes vanilla’s five stair values, and nothing else in the game has one.

The derivation matters because the property it feeds (delvec::schem::stairs::derive_shape) tests any stair against any other — an oak stair mitres against a stone-brick one — so a hand-kept list would be wrong the day a version adds a stair, in the silent direction.

Source

pub fn omitted_properties( &self, name: &str, properties: &BTreeMap<String, String>, ) -> Vec<String>

Every property of name the state omits, sorted — the DW0737 predicate, and a superset of Self::omitted_shape_carrying.

Vanilla’s BlockState codec fills an omitted property from the block’s default state, so a partial state is a legal thing to write and the game resolves it correctly. Nothing else can: a renderer, a review image, a navigation walk or a diff has to guess, and the guesses disagree with each other and with the server. The shape half of that (DW0735) drops geometry outright and is the harder error; this is the whole class, and it is the rule an AUTHORED program is held to — a state whose meaning only a running server knows cannot be reviewed before it runs.

Empty for a propertyless block, for a foreign namespace and for an id the pin does not know (the unknown-block diagnostics own that case).

Source

pub fn omitted_shape_carrying( &self, name: &str, properties: &BTreeMap<String, String>, ) -> Vec<String>

The shape-carrying properties a state omits, sorted. Empty when the state is complete, when the block has none, and when the id is foreign or unknown at the pin.

Source

pub fn oriented_mismatch( &self, name: &str, properties: &BTreeMap<String, String>, local_to_world: [usize; 3], reflected: [bool; 3], ) -> Option<String>

The first property of a state that lands wrong when the state is written under the frame local_to_world / reflected without being rewritten — the DW0736 predicate.

A frame has two halves and the check needs both. local_to_world[i] is the world axis index (0 = X, 1 = Y, 2 = Z) that a scope’s local axis i names; reflected[i] says local axis i runs backwards along it. A grammar frame permutes and reflects the geometry a rule describes and never touches block-state properties (crates/delvec/src/grammar/orient.rs), so a literal facing/axis/ connection property is correct only if the frame fixes the direction it names. The check transforms the state through the frame — mapping direction-valued properties, axis-valued properties, direction-named connection flags and two-direction orientation values, all derived from the registry’s own value vocabulary — and reports the first property whose transform differs from its literal, in key order (deterministic, ADR-0006).

A reflection is a sign on the axis, so it is exactly what the existing (axis, sign) vocabulary already speaks: local north under a reflected local Z is world south. An axis-valued property carries no sign and is therefore untouched by a reflection — axis=x means the same pillar either way. rotation (the 16-step yaw of signs, skulls and banners), hinge and a non-straight stair shape are facing-relative or sub-cardinal and cannot be transformed by axis vocabulary; they are the minimal, documented residue and count as mismatched whenever the frame moves or reflects a horizontal axis. A reflection is the case that matters most for hinge and a corner shape: those are chiral, and a mirror is what a rotation cannot reproduce.

None for the identity frame (nothing moves and nothing reflects), for a foreign namespace, and for an id or property the pin does not know (the unknown-state diagnostics own those).

Source

pub fn frame_sensitive( &self, name: &str, properties: &BTreeMap<String, String>, frames: impl IntoIterator<Item = ([usize; 3], [bool; 3])>, ) -> Vec<String>

The same question asked of a set of frames instead of one: which properties of this state ANY of frames would land wrong.

Self::oriented_mismatch answers “does this state survive THIS frame”, and its first act is to return None for the identity. That is correct, and it is also why a None from it is two different facts wearing one answer: judged against a frame and found sound, or never judged at all. Telling those apart is not a question about the state alone either — it is a question about which frames the scope could have stood in, which is why the caller supplies them (delvec::grammar::orient::FrameSet).

The answer is the union of what oriented_mismatch reports over frames, so the two can never disagree about what frame-sensitivity means. That matters more than the cost of asking 48 times: a hand-kept list of sensitive property NAMES would call a symmetric run of bars sensitive (its east moves to south, and the state already gives south the same value, so no frame lands it wrong), would call an axis=y pillar sensitive under a request that pins the vertical, and would go stale the moment the pin adds a block. Asking the judge is what keeps the two definitions one definition.

Each frame is (local_to_world, reflected), exactly as oriented_mismatch reads them. Sorted key=value, deterministic (ADR-0006). Empty for a state none of these frames disturbs — a plain minecraft:stone, a waterlogged slab, a symmetric pane — for a foreign namespace and for an id the pin does not know.

Source

pub fn permuted_properties( &self, name: &str, properties: &BTreeMap<String, String>, local_to_world: [usize; 3], reflected: [bool; 3], ) -> Result<BTreeMap<String, String>, String>

The same transform, applied instead of judged: the image of properties when the state was written in a scope’s own axis names and the scope’s frame is local_to_world / reflected.

Self::oriented_mismatch asks whether a state written for the world frame survives this one; it computes the intended state to answer, and throws it away. This returns it. Both go through one classifier, so a property either has an image both of them agree on or has none, and there is no state the judge calls wrong that the resolver quietly writes anyway. That is the whole reason the classifier is a single function: a judge and a rewriter derived from two tables would disagree exactly where it matters, and the disagreement would be invisible.

Err names the first property (as key=value, in key order) whose image the pinned vocabulary does not determine — a yaw or a chirality under any frame but a pure turn about the vertical, a top/bottom half under a frame that moves or reverses the vertical, a direction whose image is not a legal value of the block, a rail’s direction-composed shape. A refusal, never a best guess: a local-frame state that cannot be resolved has no correct block to write.

Unchanged for the identity frame, for a foreign namespace and for an id the pin does not know (the unknown-block diagnostics own that).

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> 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, 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.