Events
Events play a pivotal role in decoding the dynamics of a Dojo world. Every time there's an update to a Model
, the World
contract emits these events. What's even more exciting is that you can craft your own custom events to fit specific needs! Moreover, thanks to Torii, all these events are seamlessly indexed, ensuring easy and efficient querying.
Model Events
Consider this example of a Moves
model:
struct Moves {
#[key]
player: Address,
remaining: u32,
}
When this model is updated, the World
contract will emit an event with the following structure:
#[derive(Drop, starknet::Event)]
struct StoreSetRecord {
table: felt252, // Moves
keys: Span<felt252>, // [player]
offset: u8, // offset for the value in the table
value: Span<felt252>, // [remaining]
}
This will then be captured by Torii and indexed for querying. This will allow you to then reconstruct the state of your world.
Similarly, when a model is deleted, the World
contract will emit an event with the following structure:
#[derive(Drop, starknet::Event)]
struct StoreDelRecord {
table: felt252,
keys: Span<felt252>,
}
World Events
The World
contract also emits events when it's initialized and when new models and contracts are registered. These events are emitted with the following structures:
#[derive(Drop, starknet::Event)]
struct WorldSpawned {
address: ContractAddress,
caller: ContractAddress
}
#[derive(Drop, starknet::Event)]
struct ModelRegistered {
name: felt252,
class_hash: ClassHash,
prev_class_hash: ClassHash
}
#[derive(Drop, starknet::Event)]
struct ContractDeployed {
salt: felt252,
class_hash: ClassHash,
address: ContractAddress,
}
#[derive(Drop, starknet::Event)]
struct ContractUpgraded {
class_hash: ClassHash,
address: ContractAddress,
}
These events are also captured by Torii and indexed for querying.
Custom Events
Within your game, emitting custom events can be highly beneficial. Fortunately, there's a handy emit!
command that lets you release events directly from your world. These events are indexed by Torii.
Use it like so:
emit!(world, Moved { address, direction });
Include this in your contract and it will emit an event with the following structure:
#[derive(Drop, starknet::Event)]
struct Moved {
address: felt252,
direction: felt252,
}
Now a full example using a custom event:
fn move(ctx: Context, direction: Direction) {
let (mut position, mut moves) = get !(world, caller, (Position, Moves));
moves.remaining -= 1;
let next = next_position(position, direction);
set !(world, (moves, next));
emit !(world, Moved { address: caller, direction });
}
Note: Read about the
get!
andset!
macros in Commands.