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
impl BlockRegistry
Sourcepub fn v1_21_11() -> &'static BlockRegistry
pub fn v1_21_11() -> &'static BlockRegistry
The pinned 1.21.11 registry, parsed once per process.
Sourcepub fn renames(&self) -> &BTreeMap<String, BlockRename>
pub fn renames(&self) -> &BTreeMap<String, BlockRename>
The derived rename table, keyed by the id that no longer exists.
Sourcepub fn loaded_id_at(&self, name: &str, data_version: i32) -> LoadedId<'_>
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.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
How many blocks the pinned version has. A binding count: a check that reports zero here examined nothing.
Sourcepub fn ids(&self) -> impl Iterator<Item = &str>
pub fn ids(&self) -> impl Iterator<Item = &str>
Every block id in the pinned version, namespaced, in sorted order.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Never true for the pinned registry; present because len is public.
Sourcepub fn has(&self, name: &str) -> bool
pub fn has(&self, name: &str) -> bool
True if name (namespaced, e.g. minecraft:stone) is a block.
Sourcepub fn validate(
&self,
name: &str,
properties: &BTreeMap<String, String>,
) -> Result<(), BlockError>
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.
Sourcepub fn validate_state_string(&self, state: &str) -> Result<(), BlockError>
pub fn validate_state_string(&self, state: &str) -> Result<(), BlockError>
Check a name[k=v,...] state string.
Sourcepub fn judge_at(
&self,
name: &str,
properties: &BTreeMap<String, String>,
data_version: i32,
) -> StateJudgement
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.
Sourcepub fn properties(&self, name: &str) -> Option<&BTreeMap<String, Vec<String>>>
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.
Sourcepub fn default_state(&self, name: &str) -> Option<&BTreeMap<String, String>>
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.
Sourcepub fn unwritten(
&self,
name: &str,
written: &BTreeMap<String, String>,
) -> BTreeMap<String, String>
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.
Sourcepub fn shape_carrying(&self, name: &str) -> &[String]
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).
Sourcepub fn values(&self, name: &str, property: &str) -> &[String]
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.
Sourcepub fn is_stairs(&self, name: &str) -> bool
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.
Sourcepub fn omitted_properties(
&self,
name: &str,
properties: &BTreeMap<String, String>,
) -> Vec<String>
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).
Sourcepub fn omitted_shape_carrying(
&self,
name: &str,
properties: &BTreeMap<String, String>,
) -> Vec<String>
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.
Sourcepub fn oriented_mismatch(
&self,
name: &str,
properties: &BTreeMap<String, String>,
local_to_world: [usize; 3],
reflected: [bool; 3],
) -> Option<String>
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).
Sourcepub fn frame_sensitive(
&self,
name: &str,
properties: &BTreeMap<String, String>,
frames: impl IntoIterator<Item = ([usize; 3], [bool; 3])>,
) -> Vec<String>
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.
Sourcepub fn permuted_properties(
&self,
name: &str,
properties: &BTreeMap<String, String>,
local_to_world: [usize; 3],
reflected: [bool; 3],
) -> Result<BTreeMap<String, String>, String>
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).