iwoplaza / typed-binary

Describe binary structures with full TypeScript support. Encode and decode into pure JavaScript objects.
MIT License
18 stars 1 forks source link

Feature request for usage in multiplayer game engine #3

Open amir-arad opened 2 years ago

amir-arad commented 2 years ago

This library looks really cool! I love the typescript support. In order to use this library for my game, I'm currently missing these features:

iwoplaza commented 6 months ago

Hi! Thank you for your interest in typed-binary. The library has gone through a few updates since your issue was posted, and the patch encode and decode functionality could really enhance this library's usefulness.

I am thinking of connecting this idea with something I have been thinking of recently: partial updates. I have been inspired by what immer.js is doing, and that would allow the code to look as if we were just mutating a POJO, but under the hood it would apply those mutations to the binary representation and record the changes that were made. In addition, there would be an alternative ISerialOutput implementation, maybe DiffRecorder that would record every change to the underlying buffer and represent that. This part of the solution is already possible, you'd have to create a class that implements ISerialOutput and wraps another ISerialOutput that actually does the writing.

//
// defining the schemas

export const Vertex = object({
  x: i32,
  y: i32,
  z: i32,
});

export const Polygon = object({
  vertices: tupleOf(Vertex, 3),
});

export const Mesh = object({
  faces: arrayOf(Polygon),
});

//
// creating a buffer to store the binary representation of the mesh

const buffer = new ArrayBuffer(Mesh.measure(MaxValue).size);

//
// writing the initial value

Mesh.write(new BufferWriter(buffer), {
  faces: [
    {
      vertices: [
        { x: 0, y: 0, z: 0 },
        { x: 1, y: 1, z: 1 },
        { x: 2, y: 2, z: 2 }
      ],
    },
  ],
});

//
// applying a partial update

const bufferWriter = new BufferWriter(buffer);
const diffedWriter = new DiffRecorder(bufferWriter);

Mesh.update(
  diffedWriter,
  (mesh) => {
    mesh.faces[0].vertices[0].x = 1;
  },
);

diffedWriter.mutations; // the list of recorded mutations that were done to the underlying binary.