A mod's own capability
A mod can define a capability of its own, as Mekanism defines chemicals: a resource type and a key, published from its root crate (Dependencies between trait mods) for other mods to use.
#![allow(unused)] fn main() { // The chemistry mod's root crate #[derive(Clone, PartialEq)] pub struct Chemical(pub String); pub const CHEMICALS: CapabilityKey<dyn ResourceHandler<Chemical>> = CapabilityKey::new("chem_api:chemical"); }
A mod that names it under [dependencies] builds against the same Chemical and CHEMICALS, so its providers,
r.block_entity_capability(&chem_api::CHEMICALS, &vat, …) (where vat is a declared type key or
r.block_entity_type_key("chem_pipe:vat")), answer the same capability, and
level.capability(host, &chem_api::CHEMICALS, pos, side) finds either mod's handler. move_resources moves a
chemical as it moves items, in the caller's transaction. The game has no answer of its own for a mod's key, so only
the mods' providers do, and a lookup with none registered costs one table check. A handler that keeps its amount in
its block entity's saved data (BlockEntityRef::merge_data) is covered by the game's journal, so an aborted
transaction puts it back. ItemCapabilityKey::new and EntityCapabilityKey::new define item and entity
capabilities the same way.
A key is known by its name, which must be namespaced (chem_api:chemical), and a name has one handler type. Two
mods that each declare their own Chemical under one name, rather than sharing the defining mod's, would never see
each other's handlers. So the game refuses that at startup, naming both mods and both types, and it refuses a key whose name has no
namespace. Both checks run once, when the mods register.