From book
Manages Dojo world migrations, handles breaking changes, and upgrades Dojo versions. Use when updating deployed worlds, migrating schemas, or handling version changes.
npx claudepluginhub dojoengine/bookThis skill is limited to using the following tools:
Handle world migrations, upgrades, and breaking changes when updating deployed Dojo worlds.
Deploys Dojo worlds to local Katana sequencer, Sepolia testnet, or Starknet mainnet using sozo. Starts and configures Katana, manages network profiles, and verifies deployments for game dev.
Orchestrates full migration workflows from current state analysis through planning, incremental implementation, and verification for technologies, platforms, and architecture patterns with rollback planning.
Orchestrates complete migration workflows for frameworks (e.g., Vue 2→3, Express→Fastify), databases (MySQL→PostgreSQL), and architectures (REST→GraphQL, monolith→microservices) with analysis, incremental execution, and rollback.
Share bugs, ideas, or general feedback.
Handle world migrations, upgrades, and breaking changes when updating deployed Dojo worlds.
Manages migration workflows:
Update existing world:
"Migrate my changes to the deployed world"
Version upgrade:
"Upgrade my project to Dojo v1.8.0"
sozo inspect
Shows:
sozo build
sozo test
# Deploy with default dev profile
sozo migrate
# Deploy with specific profile
sozo migrate --profile sepolia
Adding new model:
// New model - safe to add
#[derive(Copy, Drop, Serde)]
#[dojo::model]
pub struct NewFeature {
#[key]
pub player: ContractAddress,
pub data: u32,
}
Adding new system:
// New system - safe to add
#[dojo::contract]
pub mod new_system {
// Implementation
}
Adding model field:
// Adding field - existing data will have default (zero) value
struct Position {
#[key] player: ContractAddress,
x: u32,
y: u32,
z: u32, // New field
}
Changing key fields:
// Old
struct Position {
#[key] player: ContractAddress,
x: u32, y: u32,
}
// New - BREAKING! Different key structure
struct Position {
#[key] entity_id: u32, // Changed key
x: u32, y: u32,
}
Removing fields:
// Old
struct Stats {
#[key] player: ContractAddress,
health: u8,
mana: u8,
}
// New - BREAKING! Data loss
struct Stats {
#[key] player: ContractAddress,
health: u8,
// mana removed
}
Changing field types:
// Old
struct Position {
#[key] player: ContractAddress,
x: u32,
y: u32,
}
// New - BREAKING! Type incompatible
struct Position {
#[key] player: ContractAddress,
x: u128, // Changed type
y: u128,
}
Deploy fresh world with different seed:
# dojo_dev.toml
[world]
seed = "my_game_v2" # Different seed = new world address
sozo build && sozo migrate
Keep both old and new versions:
// Keep old model
#[derive(Copy, Drop, Serde)]
#[dojo::model]
pub struct PositionV1 {
#[key] player: ContractAddress,
x: u32, y: u32,
}
// Add new model
#[derive(Copy, Drop, Serde)]
#[dojo::model]
pub struct PositionV2 {
#[key] entity_id: u32,
x: u32, y: u32, z: u32,
}
Create a migration system to transform data:
#[dojo::contract]
pub mod migrator {
fn migrate_positions(ref self: ContractState, players: Array<ContractAddress>) {
let mut world = self.world_default();
for player in players {
// Read old format
let old_pos: PositionV1 = world.read_model(player);
// Transform to new format
let new_pos = PositionV2 {
entity_id: world.uuid(),
x: old_pos.x,
y: old_pos.y,
z: 0,
};
// Write new format
world.write_model(@new_pos);
}
}
}
Scarb.toml:[dependencies]
dojo = "1.8.0"
[dev-dependencies]
dojo_cairo_test = "1.8.0"
Review changelog for breaking changes
Build and test:
sozo build
sozo test
sozo migrate
sozo inspectsozo build)sozo test)sozo migrate)# 1. Add model to code
# 2. Build
sozo build
# 3. Migrate
sozo migrate
# 4. Verify
sozo inspect
# 1. Update system code
# 2. Build and test
sozo build
sozo test
# 3. Migrate (redeploys system)
sozo migrate
# 4. Test updated system
sozo execute my_game-actions spawn
sozo build firsttarget/ directory and rebuildsozo inspect outputAfter migration:
sozo build --typescript)dojo-indexer skill)