بنقرة واحدة
dojo-model
// Create Dojo models for storing game state with proper key definitions, trait derivations, and ECS patterns. Use when defining game entities, components, or state structures.
// Create Dojo models for storing game state with proper key definitions, trait derivations, and ECS patterns. Use when defining game entities, components, or state structures.
Integrate Dojo with game clients for JavaScript, Unity, Unreal, Rust, and other platforms. Generate typed bindings and connection code. Use when connecting frontends or game engines to your Dojo world.
Deploy Dojo worlds to local Katana, testnet, or mainnet. Configure Katana sequencer and manage deployments with sozo. Use when deploying your game or starting local development environment.
Create Dojo systems that implement game logic, modify model state, and handle player actions. Use when implementing game mechanics, player commands, or automated logic.
Implement, deploy, and index ERC20 and ERC721 tokens in Dojo. Use when adding token contracts, deploying them, or configuring Torii to index balances and transfers.
Set up and configure Torii indexer for GraphQL queries, gRPC subscriptions, and SQL access. Use when indexing your deployed world for client queries or real-time updates.
Configure Scarb.toml, dojo profiles, world settings, and dependencies. Use when setting up project configuration, managing dependencies, or configuring deployment environments.
| name | dojo-model |
| description | Create Dojo models for storing game state with proper key definitions, trait derivations, and ECS patterns. Use when defining game entities, components, or state structures. |
| allowed-tools | Read, Write, Edit, Glob, Grep |
Create Dojo models that define your game's state using Entity Component System (ECS) patterns.
Generates Cairo model structs with:
#[dojo::model] attributeDrop, Serde)#[key])Interactive mode:
"Add a model for player positions"
I'll ask about:
Direct mode:
"Create a Position model with player as key and x, y coordinates"
In your model file (e.g., models.cairo):
use starknet::ContractAddress;
// For nested structs that aren't models
use dojo::meta::Introspect;
In systems that use models:
// Import your models
use my_project::models::{Player, Position, Inventory};
// Import Dojo storage traits
use dojo::model::{ModelStorage, ModelValueStorage};
Reading/Writing models in a system:
// Get world storage
let mut world = self.world_default();
// Read - provide all #[key] values
let player: Player = world.read_model(player_address);
// Write - model must contain all keys and data
world.write_model(@player);
Models are Cairo structs annotated with #[dojo::model].
They act as a key-value store where #[key] fields define the lookup key.
#[derive(Drop, Serde)]
#[dojo::model]
struct Moves {
#[key]
player: ContractAddress,
remaining: u8,
}
Required traits:
Drop - Cairo ownership systemSerde - Serialization for on-chain storageOptional traits:
Copy - Add when you need to copy values (for primitive types)Models keyed by player address:
#[derive(Drop, Serde)]
#[dojo::model]
struct Position {
#[key]
player: ContractAddress,
vec: Vec2,
}
#[derive(Drop, Copy, Serde, Introspect)]
struct Vec2 {
x: u32,
y: u32,
}
Custom nested structs must derive Introspect for Dojo to understand their structure.
Multiple keys for relationships (all keys must be provided when reading):
#[derive(Copy, Drop, Serde)]
#[dojo::model]
struct GameResource {
#[key]
player: ContractAddress,
#[key]
location: ContractAddress,
balance: u8,
}
Read with tuple of all keys:
let resource: GameResource = world.read_model((player, location));
Constant key for global settings:
const RESPAWN_DELAY: u128 = 9999999999999;
#[derive(Copy, Drop, Serde)]
#[dojo::model]
struct GameSetting {
#[key]
setting_id: u128,
setting_value: felt252,
}
// Usage
world.write_model(@GameSetting {
setting_id: RESPAWN_DELAY,
setting_value: (10 * 60).into()
});
Small, focused models that can be combined on entities:
#[derive(Copy, Drop, Serde)]
#[dojo::model]
struct Position {
#[key]
id: u32,
x: u32,
y: u32,
}
#[derive(Copy, Drop, Serde)]
#[dojo::model]
struct Health {
#[key]
id: u32,
health: u8,
}
// Human has Position + Health + Potions
// Orc has Position + Health (no Potions)
#[key] fieldGet the world storage in your system:
use dojo::model::{ModelStorage, ModelValueStorage};
let mut world = self.world(@"my_namespace");
world.write_model(@Position { player, vec: Vec2 { x: 0, y: 0 } });
let position: Position = world.read_model(player);
let resource: GameResource = world.read_model((player, location));
let entity_id = world.uuid();
world.write_model(@Health { id: entity_id, health: 100 });
u8, u16, u32, u64, u128, u256 - Unsigned integersfelt252 - Field elementsbool - BooleansContractAddress - Starknet addressesIntrospectIntrospectAfter creating models:
dojo-system skill to create systems that use your modelsdojo-test skill to test model read/write operationsdojo-config skill to configure permissions