Version Migration
When component structure changes, the version migration system can automatically upgrade old version save data.
Register Migration Function
Section titled “Register Migration Function”import { VersionMigrationManager } from '@esengine/ecs-framework';
// Assume PlayerComponent v1 has hp field// v2 changes to health and maxHealth fields
// Register migration from version 1 to version 2VersionMigrationManager.registerComponentMigration( 'Player', 1, // From version 2, // To version (data) => { // Migration logic const newData = { ...data, health: data.hp, maxHealth: data.hp, }; delete newData.hp; return newData; });Using Migration Builder
Section titled “Using Migration Builder”import { MigrationBuilder } from '@esengine/ecs-framework';
new MigrationBuilder() .forComponent('Player') .fromVersionToVersion(2, 3) .migrate((data) => { // Migrate from version 2 to version 3 data.experience = data.exp || 0; delete data.exp; return data; });Scene-Level Migration
Section titled “Scene-Level Migration”// Register scene-level migrationVersionMigrationManager.registerSceneMigration( 1, // From version 2, // To version (scene) => { // Migrate scene structure scene.metadata = { ...scene.metadata, migratedFrom: 1 }; return scene; });Check Migration Path
Section titled “Check Migration Path”// Check if migration is possibleconst canMigrate = VersionMigrationManager.canMigrateComponent( 'Player', 1, // From version 3 // To version);
if (canMigrate) { // Safe to migrate scene.deserialize(oldSaveData);}
// Get migration pathconst path = VersionMigrationManager.getComponentMigrationPath('Player');console.log('Available migration versions:', path); // [1, 2, 3]Migration Chain Example
Section titled “Migration Chain Example”When migrating across multiple versions, the system automatically chains migrations:
// Register v1 -> v2VersionMigrationManager.registerComponentMigration('Player', 1, 2, (data) => { data.health = data.hp; delete data.hp; return data;});
// Register v2 -> v3VersionMigrationManager.registerComponentMigration('Player', 2, 3, (data) => { data.stats = { health: data.health, mana: 100 }; delete data.health; return data;});
// When loading v1 data, it will automatically execute v1 -> v2 -> v3Best Practices
Section titled “Best Practices”1. Always Maintain Backward Compatibility
Section titled “1. Always Maintain Backward Compatibility”// Document data structure changes for each version// v1: { hp: number }// v2: { health: number, maxHealth: number }// v3: { stats: { health: number, mana: number } }2. Test Migration Paths
Section titled “2. Test Migration Paths”// Test all possible migration pathsconst testData = { hp: 100 };const migrated = VersionMigrationManager.migrateComponent('Player', testData, 1, 3);expect(migrated.stats.health).toBe(100);3. Keep Backup of Original Data
Section titled “3. Keep Backup of Original Data”// Backup before migrationconst backup = JSON.parse(JSON.stringify(saveData));try { scene.deserialize(saveData);} catch (e) { // Restore on migration failure console.error('Migration failed:', e);}API Reference
Section titled “API Reference”| Method | Description |
|---|---|
registerComponentMigration(type, from, to, fn) | Register component migration function |
registerSceneMigration(from, to, fn) | Register scene migration function |
canMigrateComponent(type, from, to) | Check if migration is possible |
getComponentMigrationPath(type) | Get component’s migration version path |
migrateComponent(type, data, from, to) | Execute component data migration |