Skip to content

State Patching

The @shell/serialization package supports two modes of state application: apply() for authoritative live patching and load() for full state replacement.

load()apply()
LifecycleStops, restartsNo interruption
Existing entitiesWipedPatched (spawns missing, updates existing, despawns stale)
Use caseScene loading, save filesNetworking, live state sync

apply() treats incoming data as the desired world state and reconciles the live world:

serializer.apply(data);
// Scoped authority — only managed entities can be despawned
serializer.apply(data, serverOwnedEntities);

Only serializable components are candidates for removal. Non-serializable components (tags, internal state managed by systems/plugins) are left untouched.

await serializer.load(data);
await serializer.load(data, { restartLifecycle: false });

Wipes all entities, deserializes, commits, and optionally restarts the lifecycle.

Instance and Object store types are skipped during serialization unless a custom FieldSerializer is provided on the component.

import { Define, StoreType } from '@shell/ecs';
const MyComponent = Define.component('MyComponent')
.withSchema({
data: { type: StoreType.Instance() },
})
.serializable()
.withFieldSerializer('data', {
serialize: (value) => ({ key: value.key }),
deserialize: (data) => new MyData(data.key),
});