Skip to content

Latest commit

 

History

History
104 lines (70 loc) · 4.76 KB

codecs.md

File metadata and controls

104 lines (70 loc) · 4.76 KB

Codecs

Codecs are responsible for encoding your events data into ArrayBuffer that will be transmitted over the binary websocket connection and decoded back into usable data on the other side.

You will probably need to write your own codecs but a few standard needs are alreay adressed by the simple codecs that follow:

Packaged codecs

Packaged codecs are available in the netcode/server and netcode/client packages or as source code in netcode/src/encoder/codec folder (see [Note on packaging](#Note on packaging))

Class Data format Example Size (in byte)
Codec No data (just send the event name) ['pause', new Codec()]
send('pause')
0
BooleanCodec true|false ['active', new BooleanCodec()]
send('active', true)
1
StringCodec String up to 255 characters ['player:name', new StringCodec()]
send('player:name', 'DarkShadow73')
1 + (String length * 2)
LongStringCodec String up to 65536 characters ['url', new LongStringCodec()]
send('url', 'https://my.long.url/hash/xxx...')
2 + (String length * 2)
Int8Codec Integer from 0 to 255 ['id', new Int8Codec()]
send('id', 42)
1
Int16Codec Integer from 0 to 65536 ['score', new Int16Codec()]
send('score', 9999)
2
Int32Codec Integer from 0 to 4294967295 ['position', new Int32Codec()]
send('position', 4294967295)
4
LongIntCodec(byteLength) Integer encoded as string ['timestamp', new LongIntCodec(13)]
send('timestamp', Date.now())
byteLength

Custom codecs

Some of your events will certainly have more complex data structure that just one of the above single scalar example. Good news is you can write your own codecs!

Your custom codec must extends the Codec class of Netcode and implement the 3 following methods:

  • getByteLength(data): return the number of byte in the event for the given data (your event byte length may vary over the data, like for abitrary strings for example).
  • encode(buffer, offset, data) encode the given data into the provided buffer, starting at the given offset (in byte).
  • decode(buffer, offset): read and return the data contained in the provided buffer, starting at the given offset.

Let's say we want to send an event with the given format:

send('position', { id: player.id, x: 12345, y: 2354 });

We'll need to rite a codec that can transmit these values in an ArrayBuffer.

For this example, I'm gonna chose to encode:

  • The player ID as an unsigned integer on 1 byte (UInt8)
  • The x and y position on 2 byte each (Uint16)

So the byte length of my event is fixed: 1 + 2 + 2 = 5 bytes.

Full working example using composition:

import { Codec, Int8Codec, Int16Codec } from 'netcode/src/encoder/codec';

export default class PositionCodec extends Codec {
    constructor() {
        super();

        this.int8Codec = new Int8Codec();
        this.int16Codec = new Int16Codec();
    }

    /**
     * @type {Number}
     */
    getByteLength() {
        return this.int8Codec.getByteLength() + this.int16Codec.getByteLength() * 2;
    }

    /**
     * {@inheritdoc}
     */
    encode(buffer, offset, data) {
        const { id, x, y } = data;

        this.int8Codec.encode(buffer, offset, id);

        offset += this.int8Codec.getByteLength();

        this.int16Codec.encode(buffer, offset, x);

        offset += this.int16Codec.getByteLength();

        this.int16Codec.encode(buffer, offset, y);
    }

    /**
     * {@inheritdoc}
     */
    decode(buffer, offset) {
        const id = this.int8Codec.decode(buffer, offset);

        offset += this.int8Codec.getByteLength();

        const duration = this.int16Codec.decode(buffer, offset);

        offset += this.int16Codec.getByteLength();

        const position = this.int8Codec.decode(buffer, offset);

        return { id, x, y };
    }
}

Debugging

The BinaryEncoder should emit errors if anything wrong happen durring encoding or decoding, but even so, working with binary data can be tricky. You can replace your BinaryEncoder with a JsonEncoder at any time without any other change to you code to switch to a JSON communication and to help you find out what's wrong with transmitted data.