dojo-model

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Dojo Model Generation

Dojo 模型生成

Create Dojo models that define your game's state using Entity Component System (ECS) patterns.
创建采用Entity Component System(ECS)模式定义游戏状态的Dojo模型。

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]"
  • "添加Position模型"
  • "创建包含生命值和等级的Player实体"
  • "生成Inventory模型"
  • "为[游戏概念]定义模型"

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
生成具备以下特性的Cairo模型结构体:
  • #[dojo::model]
    属性
  • 必需的trait派生(
    Drop
    Serde
  • 键字段配置(
    #[key]
  • 与数据匹配的字段类型

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"
交互模式:
"添加玩家位置模型"
我会询问以下信息:
  • 模型名称
  • 键字段(用于标识唯一性的字段)
  • 数据字段及其类型
直接模式:
"创建以player为键、包含x和y坐标的Position模型"

Model Structure

模型结构

Models are Cairo structs annotated with
#[dojo::model]
. They act as a key-value store where
#[key]
fields define the lookup key.
cairo
#[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)
模型是带有
#[dojo::model]
注解的Cairo结构体。它们作为键值存储,其中
#[key]
字段用于定义查找键。
cairo
#[derive(Drop, Serde)]
#[dojo::model]
struct Moves {
    #[key]
    player: ContractAddress,
    remaining: u8,
}
必需的trait:
  • Drop
    - Cairo所有权系统特性
  • Serde
    - 用于链上存储的序列化特性
可选的trait:
  • Copy
    - 当你需要复制值时添加(适用于原始类型)

Model Patterns

模型模式

Player-Owned Model

玩家所属模型

Models keyed by player address:
cairo
#[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.
以玩家地址为键的模型:
cairo
#[derive(Drop, Serde)]
#[dojo::model]
struct Position {
    #[key]
    player: ContractAddress,
    vec: Vec2,
}

#[derive(Drop, Copy, Serde, Introspect)]
struct Vec2 {
    x: u32,
    y: u32,
}
自定义嵌套结构体必须派生
Introspect
,以便Dojo能够识别其结构。

Composite Keys

复合键

Multiple keys for relationships (all keys must be provided when reading):
cairo
#[derive(Copy, Drop, Serde)]
#[dojo::model]
struct GameResource {
    #[key]
    player: ContractAddress,
    #[key]
    location: ContractAddress,
    balance: u8,
}
Read with tuple of all keys:
cairo
let resource: GameResource = world.read_model((player, location));
用于关联关系的多个键(读取时必须提供所有键):
cairo
#[derive(Copy, Drop, Serde)]
#[dojo::model]
struct GameResource {
    #[key]
    player: ContractAddress,
    #[key]
    location: ContractAddress,
    balance: u8,
}
使用所有键的元组进行读取:
cairo
let resource: GameResource = world.read_model((player, location));

Global Singleton

全局单例

Constant key for global settings:
cairo
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()
});
用于全局设置的常量键:
cairo
const RESPAWN_DELAY: u128 = 9999999999999;

#[derive(Copy, Drop, Serde)]
#[dojo::model]
struct GameSetting {
    #[key]
    setting_id: u128,
    setting_value: felt252,
}

// 用法
world.write_model(@GameSetting {
    setting_id: RESPAWN_DELAY,
    setting_value: (10 * 60).into()
});

ECS Composition

ECS组合

Small, focused models that can be combined on entities:
cairo
#[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)
可在实体上组合使用的小型、专注的模型:
cairo
#[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,
}

// 人类拥有Position + Health + Potions
// 兽人拥有Position + Health(无Potions)

Key Rules

键规则

  1. At least one key required - Every model needs a
    #[key]
    field
  2. Keys must come first - All key fields before data fields
  3. Keys are not stored - Used only for indexing/lookup
  4. All keys required for read - Composite keys must all be provided
  1. 至少需要一个键 - 每个模型都需要一个
    #[key]
    字段
  2. 键必须排在最前面 - 所有键字段都要放在数据字段之前
  3. 键不会被存储 - 仅用于索引/查找
  4. 读取时需要所有键 - 复合键必须全部提供

Model API

模型API

Get the world storage in your system:
cairo
use dojo::model::{ModelStorage, ModelValueStorage};

let mut world = self.world(@"my_namespace");
在你的系统中获取世界存储:
cairo
use dojo::model::{ModelStorage, ModelValueStorage};

let mut world = self.world(@"my_namespace");

Write a Model

写入模型

cairo
world.write_model(@Position { player, vec: Vec2 { x: 0, y: 0 } });
cairo
world.write_model(@Position { player, vec: Vec2 { x: 0, y: 0 } });

Read a Model

读取模型

cairo
let position: Position = world.read_model(player);
cairo
let position: Position = world.read_model(player);

Read with Composite Key

使用复合键读取

cairo
let resource: GameResource = world.read_model((player, location));
cairo
let resource: GameResource = world.read_model((player, location));

Generate Unique ID

生成唯一ID

cairo
let entity_id = world.uuid();
world.write_model(@Health { id: entity_id, health: 100 });
cairo
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
  • u8
    ,
    u16
    ,
    u32
    ,
    u64
    ,
    u128
    ,
    u256
    - 无符号整数
  • felt252
    - 域元素
  • bool
    - 布尔值
  • ContractAddress
    - Starknet地址
  • 自定义结构体 - 必须派生
    Introspect
  • 自定义枚举 - 必须派生
    Introspect

Next Steps

后续步骤

After creating models:
  1. Use
    dojo-system
    skill to create systems that use your models
  2. Use
    dojo-test
    skill to test model read/write operations
  3. Use
    dojo-config
    skill to configure permissions
创建模型后:
  1. 使用
    dojo-system
    技能创建使用这些模型的系统
  2. 使用
    dojo-test
    技能测试模型的读写操作
  3. 使用
    dojo-config
    技能配置权限

Related Skills

相关技能

  • dojo-system: Create systems that use these models
  • dojo-test: Test your models
  • dojo-init: Initialize project first
  • dojo-review: Review model design
  • dojo-system:创建使用这些模型的系统
  • dojo-test:测试你的模型
  • dojo-init:先初始化项目
  • dojo-review:审核模型设计