Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 0 additions & 158 deletions client/pages/getting-started/basics/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -397,161 +397,3 @@ mod tests {
}
```

### Testing Traits and Methods

```cairo
#[test]
fn test_is_rare() {
let mut potion = PotionTrait::new_potion(1);

potion.rarity = Rarity::VeryRare;
assert_eq!(potion.is_rare(), true, "VeryRare should return true");

potion.rarity = Rarity::Rare;
assert_eq!(potion.is_rare(), true, "Rare should return true");

potion.rarity = Rarity::Uncommon;
assert_eq!(potion.is_rare(), false, "Uncommon should return false");
}
```

## Special Model Patterns

### Game Settings with Constant Keys

For global values or settings:

```cairo
const GAME_SETTINGS_ID: u32 = 9999999999999;

#[derive(Copy, Drop, Serde)]
#[dojo::model]
struct GameSettings {
#[key]
game_settings_id: u32,
combat_cool_down: u32,
}

// Usage:
world.read_model(GAME_SETTINGS_ID);
```

### Type-Safe Entity IDs

To avoid ID collisions:

```cairo
const HUMAN: felt252 = 'HUMAN';
const GOBLIN: felt252 = 'GOBLIN';

// Create unique IDs:
let human_id = poseidon_hash_span([id, HUMAN].span());
let goblin_id = poseidon_hash_span([goblin_count, GOBLIN].span());
```

## Upgrading Models and Data Migration

Upgrading models is safe as long as changes don't affect the existing data layout and schema.

### Safe Upgrades

Adding a new field without modifying existing ones:

```cairo
// Original model
#[dojo::model]
struct Player {
#[key]
player_id: u64,
username: String,
score: u32,
}

// Upgraded model (safe)
#[dojo::model]
struct Player {
#[key]
player_id: u64,
username: String,
score: u32,
level: u8, // New field
}
```

### Incompatible Upgrades

Changes that alter the existing layout will fail:
- Removing or reordering fields
- Changing field types
- Changing key structure

## Best Practices for Model Design

### Keep Models Small and Focused

Follow ECS principles by keeping models small and focused on a single aspect of an entity:

```cairo
// Good: Separate models for different aspects
#[dojo::model]
struct Health {
#[key]
id: u32,
health: u8,
}

#[dojo::model]
struct Position {
#[key]
id: u32,
x: u32,
y: u32
}

// Avoid: Large monolithic models
#[dojo::model]
struct Character {
#[key]
id: u32,
health: u8,
max_health: u8,
mana: u8,
max_mana: u8,
x: u32,
y: u32,
inventory_slots: u8,
// ... many more fields
}
```

### Use Appropriate Types

Choose types based on data needs:
- `u8` for small integers (0-255)
- `u16`, `u32`, etc. for larger integers
- `felt252` for names and identifiers
- Custom structs and enums for complex data

### Implement Validation Logic

Use traits and assertions to validate model state:

```cairo
fn assert_valid_health(self: @Health) {
assert(self.health > 0, 'Health must be positive');
assert(self.health <= self.max_health, 'Health cannot exceed max');
}
```

### Plan for Upgrades

Design models with future upgrades in mind:
- Consider which fields might need to change
- Use `IntrospectPacked` only when necessary
- Document expected upgrade paths

## Conclusion

Models are the core of game state management in Dojo Engine, defining how data is structured and stored on Starknet. By combining models with **entities** and **systems** in the **ECS** pattern, you can build dynamic, decentralized games.

Use the examples and patterns in this guide as a starting point for your own model designs, and experiment with the different approaches to find what works best for your game's needs.
Loading