Перейти до вмісту

Item data

Цей контент ще не доступний вашою мовою.

Unstable: everything in this chapter needs the unstable feature and may change in any release (Stability).

Item data is what a mod attaches to one item: a ring’s rolled bonus, the name engraved on a sword, the owner of a staff. Each piece belongs to a kind with an id <mod>:<name> and a value type of the mod’s choosing. The item_data module reads and writes it.

use enshwick::Entity;
use enshwick::inventory::ItemInstance;
#[derive(serde::Serialize, serde::Deserialize)]
struct Bonus {
fire: i16,
}
fn init(load: &mut enshwick::Load<'_>) -> Result<(), enshwick::Off> {
// `<this mod>:bonus`; another mod opens it as "<this mod>:bonus".
let bonus = load.item_data::<Bonus>("bonus")?;
let ring = ItemInstance { pide: Entity(900), item: enshwick::ItemId::new(0x5e01) };
if bonus.get(ring).is_none() {
let _set = bonus.set(ring, &Bonus { fire: 12 });
}
Ok(())
}

Only an item with an entity of its own, its PIDE, carries data: weapons, armour and other items with durability or a level, and items with a meter. An ItemInstance is that entity and the item id it holds; ItemInstance::of(&slot) takes it from an inventory slot, or gives None for an empty slot or an item without an entity of its own.

Within a session the value stays with the item across moves between inventories and trades. Once the entity holds another item, the value reads as missing, and the server drops it when the world saves. When the game destroys the item, as a craft that uses it up does, the server drops its values after that step and tells the clients.

A load numbers item entities anew, as it does every entity. When the world saves, the server keeps each value under the item’s place: the placed container, which of its inventories, and the slot. After the next load the value finds the item in that slot again, if it holds the same item. An item in a player’s inventory has no such place: its value lasts while its player plays. When the player leaves, or the server stops while they play, the value goes aside in the world’s file, kept but attached to nothing.

load.item_data::<T>(id) opens a kind during init, on both sides:

  • name is the mod’s own kind, <mod>:<name>;
  • mod:name is any mod’s kind. Every mod that opens one id shares its values, which is how mods share item data without depending on each other. The value types must match; a value that does not decode as T reads as None.

The mod side of an id is a mod id; the name side is 1 to 64 of [a-z0-9_-]. A value is encoded with postcard and takes at most 512 bytes.

CallDoes
get(item)The item’s value, or None. Any thread.
set(item, &value)Sets the item’s value. On the server, or a client while it hosts, once the world has loaded.
remove(item)Removes it. As for set.

set and remove return a SetError: the value does not encode or is too long, the call came from a client alone, or the world has not loaded.

The server keeps the values in mod-data/enshwick/worlds/<key>/attachments.bin, written when the world saves and when the server stops, never in the game’s save: removing the mods leaves the world vanilla. Every change goes to the clients that run Enshwick, and a client that joins gets every value, so get on a client answers from what its server sent. A vanilla client gets nothing.

Data on entities other than items is entity data, kept in the same file.

What a player should see on the item itself belongs in its meter, which the game draws, or in its tooltip lines, which are the same for every item of its type.