pub enum BodyRef<'a> {
Npc(&'a Npc),
Actor(&'a Actor),
}Expand description
One object class that has a body the compiler stages: a declared position, a declared species, and a compiler-emitted route.
A sum type rather than a flattened tuple, so adding a body class is a compile error at every consumer until each one says what it does with it. The alternative — each rule walking the classes it happens to remember — is the defect class CLAUDE.md names: a hand-rolled walk that enumerated three of five effect roots.
Keyed to the object, not to the verb that first needed it. This type was
introduced for BodyTraversal and read, for a while, as “one consumer of
BodyTraversal” — which is why its only enumeration
(body_traversal_sites) was filtered to bodies declaring a traversal, and
why the second property a body carries, its NpcSkin, had no enumeration
at all: the bake walked the stage-2 npc list by hand, and an actor’s skin was
emitted into the summon, never baked into the pack, and never refused.
A body’s properties belong to the body. body_sites is the unfiltered
walk; a per-property enumeration is a filter over it, never a second walk.
Deliberately NOT a member: WaveMob. A wave mob has a body and a position,
but it is driven by native vanilla AI, never by a compiler-emitted route,
so the compiler makes no claim about the moves it makes and a locomotion
declaration on it could change no verdict. It declares no skin either — the
exclusion holds for both properties, and the schema says so
(crates/dsl/tests/body_skin_sites.rs). It becomes a member the day the lane
proof reasons about how its bodies move — and it joins here, through this
same type, rather than through a field of its own.
Variants§
Npc(&'a Npc)
A stage-2 NPC, walked by move-npc.
Actor(&'a Actor)
A stage-5 scripted actor, walked by move-actor.
Implementations§
Source§impl<'a> BodyRef<'a>
impl<'a> BodyRef<'a>
Sourcepub const ALL_CLASSES: [&'static str; 2]
pub const ALL_CLASSES: [&'static str; 2]
Every body class, by schema name. The closed set, stated once.
Sourcepub fn stage(self) -> &'static str
pub fn stage(self) -> &'static str
The declaring stage’s wire name (npcs / quests) — also the stage
whose dsl_version fences this body’s declaration.
Sourcepub fn declared_entity(self) -> &'a str
pub fn declared_entity(self) -> &'a str
The entity id written on the body. Not necessarily the body that
ships: a skin re-dresses it as a minecraft:mannequin — see
Self::worn_entity.
Sourcepub fn worn_entity(self) -> &'a str
pub fn worn_entity(self) -> &'a str
The entity id the body ships as: minecraft:mannequin when it
declares a skin, else the declared entity. The one authority for that
rule — the compiler’s geometric proofs (nav::npc_body_entity,
nav::actor_body_entity) and the equipment fit rule (DW0898) all read
it.
Sourcepub fn mark(self) -> Mark
pub fn mark(self) -> Mark
The mark this body is placed on — the anchor and offset the engine summons it at, for every class alike (spec-0066).
A body’s placement is a property of the body, not of the stage list that
happens to declare it: a mark is a cell, and a cell holds one body. The
rule that reads this ([crate::compiler]’s DW0896, via
body_sites) therefore quantifies over npcs and actors in one pass
rather than over actors[], which is where the seven-men-one-anchor
muster came from.
Sourcepub fn area(self) -> Option<&'a AreaId>
pub fn area(self) -> Option<&'a AreaId>
The area whose anchor table resolves Self::mark’s anchor first, when this
class declares one.
A stage-2 npc names its area and is resolved inside it; a stage-5 actor
names none and is resolved across every placed piece, exactly as an
open-gate / move-actor destination is. Stated here so the resolution
rule is one rule over both classes and not a per-call-site habit.
Sourcepub fn at_world_init(self) -> bool
pub fn at_world_init(self) -> bool
Whether this body stands on its mark from world init, with no effect having to fire.
A stage-2 npc does unless it is deferred; a stage-5 actor never does —
a puppet exists only from the spawn-actor that summons it, which is why
an actor no spawn-actor names never exists at all.
Sourcepub fn killable_by_players(self) -> bool
pub fn killable_by_players(self) -> bool
Whether a player can end this body’s life.
An npc body is emitted Invulnerable:1b unconditionally, so nothing a
player does removes it; an actor’s puppet is Invulnerable unless it
declares Actor::vulnerable. A body a player can kill is one whose
lifetime the compiler cannot bound, which is the whole of what this
answers.
Sourcepub fn traversal(self) -> Option<&'a BodyTraversal>
pub fn traversal(self) -> Option<&'a BodyTraversal>
This body’s traversal declaration, if it carries one.
Sourcepub fn skin(self) -> Option<&'a NpcSkin>
pub fn skin(self) -> Option<&'a NpcSkin>
This body’s skin declaration, if it carries one.
A skinned body of either class ships as a minecraft:mannequin
whose profile.texture resolves to delvewright:npc/<campaign_id>/<texture_id>,
so either one owes the same skins/<texture_id>.png under the same refusal
(DW0309). Answering it here is what stops the bake from being a
property of one class.