1.1.0 • Published 5 years ago
netpack v1.1.0
netpack
Fast + lightweight binary packet encoder/decoder for entities in multiplayer games
Install
npm i netpack
Usage - Server
const Packer = require('netpack')
// Create packer instance
// Define your fields
// fieldName : dataType
let packer = new Packer({
'name': 'string',
'x': 'uint16',
'y': 'uint16',
'leaderboard': 'json', // json encodes with messagepack
})
// Construct your game's state object in this format:
// TIP: You can leave .entities or .messages undefined to send none
let gamestate = {
entities: [
{
id: 10,
fields: {
'name': 'Mike Tromba',
'x': 50,
'y': 50,
}
}
// ...
],
messages: {
'leaderboard': [124, 564, 2135, 7455]
}
}
// Encode and send it
let buffer = packer.pack(gamestate)
// Now send to client via websocket or whatever transport you're using
Usage - Client
// ON CLIENT:
// Construct your packer instance the same way you did on server.
// When you recieve a packet from the server, decode it with .unpack()
let unpacked = packer.unpack(buffer)
console.log(unpacked)
Available Data Types
For more info, see: https://github.com/phretaddin/schemapack
Type Name | Aliases | Bytes | Range of Values |
---|---|---|---|
bool | boolean | 1 | True or false |
int8 | 1 | -128 to 127 | |
uint8 | 1 | 0 to 255 | |
int16 | 2 | -32,768 to 32,767 | |
uint16 | 2 | 0 to 65,535 | |
int32 | 4 | -2,147,483,648 to 2,147,483,647 | |
uint32 | 4 | 0 to 4,294,967,295 | |
float32 | 4 | 3.4E +/- 38 (7 digits) | |
float64 | 8 | 1.7E +/- 308 (15 digits) | |
string | varuint length prefix followed by bytes of each character | Any string | |
json | encodes to a string via JSON.stringify | Any object or array | |
varuint | 1 byte when 0 to 127 2 bytes when 128 to 16,383 3 bytes when 16,384 to 2,097,151 4 bytes when 2,097,152 to 268,435,455 etc. | 0 to 2,147,483,647 | |
varint | 1 byte when -64 to 63 2 bytes when -8,192 to 8,191 3 bytes when -1,048,576 to 1,048,575 4 bytes when -134,217,728 to 134,217,727 etc. | -1,073,741,824 to 1,073,741,823 | |
buffer | varuint length prefix followed by bytes of buffer | Any buffer |
Performance
To run your own, modify tests/benchmark.js
These tests were run with a realistically-large payload for a multiplayer game running at a 20 tickrate
I optimized each as best I could to squeeze out extra performance. For example, for the msgpack-lite and JSON.stringify payloads, I crushed all of the json keys (ex. 'name' becomes 'n')
JSON.stringify produced by far the largest payloads... not recommended for heavy realtime networking
kbps is estimated per-player
netpack: 11.48 kbps
msgpack-lite: 13.62 kbps
JSON.stringify: 25.78 kbps
netpack encode x 46,798 ops/sec ±1.76% (87 runs sampled)
msgpack-lite encode x 27,174 ops/sec ±0.77% (96 runs sampled)
JSON.stringify x 94,533 ops/sec ±0.72% (95 runs sampled)