Skip to content

Snapshot Deserialization Output #204

@ben-zabloski

Description

@ben-zabloski

Issue

When using the snapshot deserializer, is it expected to see empty component array elements set to NaN?

Description

When using the snapshot deserializer, component array elements that aren't populated with entity data will be populated with NaN when deserialized.

// Serialize...
const world1 = createWorld();
const Position1 = { x: f32([]), y: f32([]), r: f32([]) };
const Velocity1 = { x: f32([]), y: f32([]) };
const components1 = [Position1, Velocity1];

const entityId1 = addEntity(world1);
addComponents(world1, entityId1, [Position1]);

Position1.x[entityId1] = 1;
Position1.y[entityId1] = 2;

const entityId2 = addEntity(world1);
addComponents(world1, entityId2, [Velocity1]);

Velocity1.x[entityId2] = 3;
Velocity1.y[entityId2] = 4;

console.log('components1', components1.length);
console.log(components1);
// components1 2
// [
//   { x: [ <1 empty item>, 1 ], y: [ <1 empty item>, 2 ], r: [] },
//   { x: [ <2 empty items>, 3 ], y: [ <2 empty items>, 4 ] }
// ]

const snapshotSerializer = createSnapshotSerializer(world1, components1);

// Deserialize...
const world2 = createWorld();
const Position2 = { x: f32([]), y: f32([]) };
const Velocity2 = { x: f32([]), y: f32([]) };
const components2 = [Position2, Velocity2];

const snapshotDeserializer = createSnapshotDeserializer(
    world2,
    components2,
);

const serialized = snapshotSerializer();
const map = snapshotDeserializer(serialized);

console.log('components2', components2.length);
console.log(components2);
// components2 2
// [
//   { x: [ <1 empty item>, 1, NaN ], y: [ <1 empty item>, 2, NaN ], r: [ <1 empty item>, NaN, NaN ] },
//   { x: [ <1 empty item>, NaN, 3 ], y: [ <1 empty item>, NaN, 4 ] }
// ]

This isn't a big problem as anyone can write code to protect against NaN data, but that code can get verbose, or add function overhead by using utility methods to parse the data.

For example - if Physicsbody.angularDamping[entityId] is empty, undefined, or null, this could work:

bodyDef.angularDamping =
  PhysicsBody.angularDamping[entityId] ?? bodyDef.angularDamping;

If the value is NaN, code turns into this:

const value = PhysicsBody.angularDamping[entityId];
if (Number.isFinite(value)) {
  bodyDef.angularDamping = value;
}

Or maybe:

const value = PhysicsBody.angularDamping[entityId];
bodyDef.angularDamping =
  Number.isFinite(value) ? value : bodyDef.angularDamping;

Or perhaps:

bodyDef.angularDamping = parse(PhysicsBody.angularDamping[entityId]);

Alternatives

I probably should just write a utility that will work for reading and applying component data through a map!

Any suggestions would be welcome! 😊

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions