Dojo Model Generation Create Dojo models that define your game's state using Entity Component System (ECS) patterns. When to Use This Skill "Add a Position model" "Create a Player entity with health and level" "Generate an Inventory model" "Define a model for [game concept]" What This Skill Does Generates Cairo model structs with:
[dojo::model]
attribute Required trait derivations ( Drop , Serde ) Key field configuration (
[key]
) Field types appropriate to your data Quick Start Interactive mode: "Add a model for player positions" I'll ask about: Model name Key fields (what makes it unique) Data fields and their types Direct mode: "Create a Position model with player as key and x, y coordinates" Essential Imports for Models 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); Model Structure 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 system Serde - Serialization for on-chain storage Optional traits: Copy - Add when you need to copy values (for primitive types) Model Patterns Player-Owned Model 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. Composite Keys 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)); Global Singleton 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() }); ECS Composition 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 Rules At least one key required - Every model needs a
[key]
field Keys must come first - All key fields before data fields Keys are not stored - Used only for indexing/lookup All keys required for read - Composite keys must all be provided Model API Get the world storage in your system: use dojo::model::{ModelStorage, ModelValueStorage}; let mut world = self.world(@"my_namespace"); Write a Model world.write_model(@Position { player, vec: Vec2 { x: 0, y: 0 } }); Read a Model let position: Position = world.read_model(player); Read with Composite Key let resource: GameResource = world.read_model((player, location)); Generate Unique ID let entity_id = world.uuid(); world.write_model(@Health { id: entity_id, health: 100 }); Field Types u8 , u16 , u32 , u64 , u128 , u256 - Unsigned integers felt252 - Field elements bool - Booleans ContractAddress - Starknet addresses Custom structs - Must derive Introspect Custom enums - Must derive Introspect Next Steps After creating models: Use dojo-system skill to create systems that use your models Use dojo-test skill to test model read/write operations Use dojo-config skill to configure permissions