Open gotexis opened 1 year ago
Would be good to include a serialization guide like the one in this library: https://github.com/NateTheGreatt/bitECS/blob/master/src/Serialize.js
Hi I played around with it. I use simple JSON.stringify combined with pako delfate
import { World } from 'miniplex';
import { Inflate, deflate, inflate } from 'pako';
import { Entity } from '../components';
interface SerializedWorldData {
entities: Entity[];
}
class WorldSerializer {
constructor(public readonly world: World<Entity>) {}
public toJSON(): SerializedWorldData {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { entities } = this.world as any;
return {
entities: entities
};
}
static fromJSON(json: SerializedWorldData): World<Entity> {
const instance = new WorldSerializer(new World<Entity>(json.entities));
return instance.world;
}
}
/**
* Serializes the world and chunks the array buffer. Uses pako deflate
* @param world
* @param chunkSize
* @returns array of buffers
*/
export function serializeWorld(world: World<Entity>, chunkSize: number): ArrayBuffer[] {
const deflated = deflate(JSON.stringify(new WorldSerializer(world)));
const buffers: ArrayBuffer[] = [];
for (let i = 0; i < deflated.byteLength; i += chunkSize) {
const chunk = deflated.slice(i, i + chunkSize);
buffers.push(chunk);
}
return buffers;
}
/**
* Deserializes the world from chunks. Uses pako inflate from provided chunks
* @param buffers
* @param maxEntities
* @returns world
*/
export function deserializeWorld(buffers: ArrayBuffer[] | undefined): World<Entity> {
let world: World<Entity>;
// Use pako to inflate the chunks
if (buffers && buffers.length !== 0) {
const inflate = new Inflate({ to: 'string' });
for (let i = 0; i < buffers.length; i++) {
const chunk = buffers[i];
if (i >= buffers.length) {
inflate.push(chunk, true);
} else {
inflate.push(chunk, false);
}
}
if (inflate.err) {
console.error(inflate.err);
throw new Error(inflate.msg);
}
// Deserialize the world from the inflate buffer
if (inflate.result) {
world = WorldSerializer.fromJSON(JSON.parse(inflate.result as string));
} else {
throw new Error('Fatal error: Inflate result is null during loading.');
}
} else {
world = new World<Entity>();
}
return world;
}
It is optimized for both performance and low memory footprint.
Would be good to include a serialization guide like the one in this library: https://github.com/NateTheGreatt/bitECS/blob/master/src/Serialize.js