modd-network 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Binary Input Protocol
3
+ *
4
+ * Minimal bandwidth for game inputs. Server knows client from connection.
5
+ *
6
+ * Message format: [type:1][payload:variable]
7
+ *
8
+ * Types:
9
+ * 0x01 KEY - [key:1] where bit7=down, bits0-6=keyIndex
10
+ * 0x02 CAMERA - [yaw:2][pitch:2] as int16 (radians * 10000)
11
+ * 0x03 SHOOT - no payload (uses current camera)
12
+ * 0x04 JOIN - no payload
13
+ * 0x05 LEAVE - no payload
14
+ * 0x06 KEYS - [count:1][keys:count] batch of key changes
15
+ */
16
+ export declare const InputType: {
17
+ readonly KEY: 1;
18
+ readonly CAMERA: 2;
19
+ readonly SHOOT: 3;
20
+ readonly JOIN: 4;
21
+ readonly LEAVE: 5;
22
+ readonly KEYS: 6;
23
+ };
24
+ export declare const KeyIndex: {
25
+ readonly W: 0;
26
+ readonly A: 1;
27
+ readonly S: 2;
28
+ readonly D: 3;
29
+ readonly SPACE: 4;
30
+ readonly SHIFT: 5;
31
+ readonly CTRL: 6;
32
+ readonly E: 7;
33
+ readonly Q: 8;
34
+ readonly R: 9;
35
+ readonly F: 10;
36
+ };
37
+ export declare function encodeKey(key: string, down: boolean): Uint8Array;
38
+ export declare function encodeKeys(keys: Array<{
39
+ key: string;
40
+ down: boolean;
41
+ }>): Uint8Array;
42
+ export declare function encodeCamera(yaw: number, pitch: number): Uint8Array;
43
+ export declare function encodeShoot(): Uint8Array;
44
+ export declare function encodeJoin(): Uint8Array;
45
+ export declare function encodeLeave(): Uint8Array;
46
+ export interface DecodedInput {
47
+ type: 'key' | 'camera' | 'shoot' | 'join' | 'leave';
48
+ key?: string;
49
+ down?: boolean;
50
+ yaw?: number;
51
+ pitch?: number;
52
+ }
53
+ export declare function decodeInput(buf: Uint8Array): DecodedInput[];
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ /**
3
+ * Binary Input Protocol
4
+ *
5
+ * Minimal bandwidth for game inputs. Server knows client from connection.
6
+ *
7
+ * Message format: [type:1][payload:variable]
8
+ *
9
+ * Types:
10
+ * 0x01 KEY - [key:1] where bit7=down, bits0-6=keyIndex
11
+ * 0x02 CAMERA - [yaw:2][pitch:2] as int16 (radians * 10000)
12
+ * 0x03 SHOOT - no payload (uses current camera)
13
+ * 0x04 JOIN - no payload
14
+ * 0x05 LEAVE - no payload
15
+ * 0x06 KEYS - [count:1][keys:count] batch of key changes
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.KeyIndex = exports.InputType = void 0;
19
+ exports.encodeKey = encodeKey;
20
+ exports.encodeKeys = encodeKeys;
21
+ exports.encodeCamera = encodeCamera;
22
+ exports.encodeShoot = encodeShoot;
23
+ exports.encodeJoin = encodeJoin;
24
+ exports.encodeLeave = encodeLeave;
25
+ exports.decodeInput = decodeInput;
26
+ exports.InputType = {
27
+ KEY: 0x01,
28
+ CAMERA: 0x02,
29
+ SHOOT: 0x03,
30
+ JOIN: 0x04,
31
+ LEAVE: 0x05,
32
+ KEYS: 0x06,
33
+ };
34
+ // Key indices - extendable
35
+ exports.KeyIndex = {
36
+ W: 0,
37
+ A: 1,
38
+ S: 2,
39
+ D: 3,
40
+ SPACE: 4,
41
+ SHIFT: 5,
42
+ CTRL: 6,
43
+ E: 7,
44
+ Q: 8,
45
+ R: 9,
46
+ F: 10,
47
+ // Add more as needed, up to 127
48
+ };
49
+ const KEY_DOWN_BIT = 0x80;
50
+ // Reverse lookup for decoding
51
+ const keyIndexToName = {
52
+ 0: 'w', 1: 'a', 2: 's', 3: 'd',
53
+ 4: 'space', 5: 'shift', 6: 'ctrl',
54
+ 7: 'e', 8: 'q', 9: 'r', 10: 'f'
55
+ };
56
+ const keyNameToIndex = {
57
+ 'w': 0, 'a': 1, 's': 2, 'd': 3,
58
+ 'space': 4, ' ': 4,
59
+ 'shift': 5, 'ctrl': 6, 'control': 6,
60
+ 'e': 7, 'q': 8, 'r': 9, 'f': 10
61
+ };
62
+ // ============================================
63
+ // Encoding (Client -> Server)
64
+ // ============================================
65
+ function encodeKey(key, down) {
66
+ const buf = new Uint8Array(2);
67
+ buf[0] = exports.InputType.KEY;
68
+ const keyIdx = keyNameToIndex[key.toLowerCase()] ?? 0;
69
+ buf[1] = keyIdx | (down ? KEY_DOWN_BIT : 0);
70
+ return buf;
71
+ }
72
+ function encodeKeys(keys) {
73
+ if (keys.length === 1) {
74
+ return encodeKey(keys[0].key, keys[0].down);
75
+ }
76
+ const buf = new Uint8Array(2 + keys.length);
77
+ buf[0] = exports.InputType.KEYS;
78
+ buf[1] = keys.length;
79
+ for (let i = 0; i < keys.length; i++) {
80
+ const keyIdx = keyNameToIndex[keys[i].key.toLowerCase()] ?? 0;
81
+ buf[2 + i] = keyIdx | (keys[i].down ? KEY_DOWN_BIT : 0);
82
+ }
83
+ return buf;
84
+ }
85
+ function encodeCamera(yaw, pitch) {
86
+ const buf = new Uint8Array(5);
87
+ buf[0] = exports.InputType.CAMERA;
88
+ // Convert radians to int16 (multiply by 10000 for ~0.0001 precision)
89
+ const yawInt = Math.round(yaw * 10000);
90
+ const pitchInt = Math.round(pitch * 10000);
91
+ buf[1] = yawInt & 0xFF;
92
+ buf[2] = (yawInt >> 8) & 0xFF;
93
+ buf[3] = pitchInt & 0xFF;
94
+ buf[4] = (pitchInt >> 8) & 0xFF;
95
+ return buf;
96
+ }
97
+ function encodeShoot() {
98
+ return new Uint8Array([exports.InputType.SHOOT]);
99
+ }
100
+ function encodeJoin() {
101
+ return new Uint8Array([exports.InputType.JOIN]);
102
+ }
103
+ function encodeLeave() {
104
+ return new Uint8Array([exports.InputType.LEAVE]);
105
+ }
106
+ function decodeInput(buf) {
107
+ if (buf.length === 0)
108
+ return [];
109
+ const type = buf[0];
110
+ const results = [];
111
+ switch (type) {
112
+ case exports.InputType.KEY: {
113
+ const keyByte = buf[1];
114
+ const down = (keyByte & KEY_DOWN_BIT) !== 0;
115
+ const keyIdx = keyByte & 0x7F;
116
+ results.push({
117
+ type: 'key',
118
+ key: keyIndexToName[keyIdx] ?? 'unknown',
119
+ down
120
+ });
121
+ break;
122
+ }
123
+ case exports.InputType.KEYS: {
124
+ const count = buf[1];
125
+ for (let i = 0; i < count; i++) {
126
+ const keyByte = buf[2 + i];
127
+ const down = (keyByte & KEY_DOWN_BIT) !== 0;
128
+ const keyIdx = keyByte & 0x7F;
129
+ results.push({
130
+ type: 'key',
131
+ key: keyIndexToName[keyIdx] ?? 'unknown',
132
+ down
133
+ });
134
+ }
135
+ break;
136
+ }
137
+ case exports.InputType.CAMERA: {
138
+ const yawInt = buf[1] | (buf[2] << 8);
139
+ const pitchInt = buf[3] | (buf[4] << 8);
140
+ // Convert from uint16 to int16
141
+ const yaw = (yawInt > 32767 ? yawInt - 65536 : yawInt) / 10000;
142
+ const pitch = (pitchInt > 32767 ? pitchInt - 65536 : pitchInt) / 10000;
143
+ results.push({ type: 'camera', yaw, pitch });
144
+ break;
145
+ }
146
+ case exports.InputType.SHOOT:
147
+ results.push({ type: 'shoot' });
148
+ break;
149
+ case exports.InputType.JOIN:
150
+ results.push({ type: 'join' });
151
+ break;
152
+ case exports.InputType.LEAVE:
153
+ results.push({ type: 'leave' });
154
+ break;
155
+ }
156
+ return results;
157
+ }
158
+ // ============================================
159
+ // Size comparison
160
+ // ============================================
161
+ // JSON keypress: ~65 bytes
162
+ // Binary keypress: 2 bytes (32x smaller)
163
+ //
164
+ // JSON camera: ~50 bytes
165
+ // Binary camera: 5 bytes (10x smaller)
166
+ //
167
+ // JSON shoot: ~40 bytes
168
+ // Binary shoot: 1 byte (40x smaller)
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Game Input Codec - Ultra-compact binary encoding for game inputs
3
+ *
4
+ * Instead of sending 180+ byte JSON:
5
+ * {"type":"move","keys":{"w":true,"a":false},"mouseX":400,"mouseY":300,"yaw":1.5}
6
+ *
7
+ * We send ~10 bytes binary:
8
+ * [type:1][keys:2][mouseX:2][mouseY:2][yaw:2][pitch:2] = 11 bytes
9
+ *
10
+ * This is a 15-20x reduction in bandwidth for move inputs.
11
+ */
12
+ export interface MoveInput {
13
+ type?: 'move' | 'input';
14
+ keys?: Record<string, boolean>;
15
+ mouseX?: number;
16
+ mouseY?: number;
17
+ x?: number;
18
+ y?: number;
19
+ yaw?: number;
20
+ pitch?: number;
21
+ seq?: number;
22
+ pid?: string;
23
+ }
24
+ export interface JoinInput {
25
+ type: 'join';
26
+ user?: {
27
+ id: string;
28
+ name?: string;
29
+ };
30
+ id?: string;
31
+ }
32
+ export interface LeaveInput {
33
+ type: 'leave';
34
+ id?: string;
35
+ }
36
+ export type GameInput = MoveInput | JoinInput | LeaveInput | {
37
+ type: string;
38
+ [key: string]: any;
39
+ };
40
+ /**
41
+ * Encode a game input to compact binary
42
+ * Returns null if input cannot be encoded (will fall back to JSON)
43
+ */
44
+ export declare function encodeGameInput(input: GameInput, playerId?: string): Uint8Array;
45
+ /**
46
+ * Decode binary input back to object
47
+ */
48
+ export declare function decodeGameInput(buf: Uint8Array | ArrayBuffer, offset?: number): {
49
+ input: GameInput;
50
+ bytesRead: number;
51
+ } | null;
52
+ /**
53
+ * Check if an input will use compact binary encoding (vs JSON fallback)
54
+ */
55
+ export declare function isCompactInput(input: GameInput): boolean;
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ /**
3
+ * Game Input Codec - Ultra-compact binary encoding for game inputs
4
+ *
5
+ * Instead of sending 180+ byte JSON:
6
+ * {"type":"move","keys":{"w":true,"a":false},"mouseX":400,"mouseY":300,"yaw":1.5}
7
+ *
8
+ * We send ~10 bytes binary:
9
+ * [type:1][keys:2][mouseX:2][mouseY:2][yaw:2][pitch:2] = 11 bytes
10
+ *
11
+ * This is a 15-20x reduction in bandwidth for move inputs.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.encodeGameInput = encodeGameInput;
15
+ exports.decodeGameInput = decodeGameInput;
16
+ exports.isCompactInput = isCompactInput;
17
+ // Input types
18
+ const INPUT_TYPE = {
19
+ MOVE: 0x01, // Standard movement input
20
+ JOIN: 0x02, // Player joined
21
+ LEAVE: 0x03, // Player left
22
+ CUSTOM: 0xFF, // Fallback to JSON for unknown types
23
+ };
24
+ // Key bitmask positions (16 keys max with 2 bytes)
25
+ const KEY_BITS = {
26
+ 'w': 0,
27
+ 'a': 1,
28
+ 's': 2,
29
+ 'd': 3,
30
+ 'space': 4,
31
+ ' ': 4,
32
+ 'shift': 5,
33
+ 'ctrl': 6,
34
+ 'control': 6,
35
+ 'e': 7,
36
+ 'q': 8,
37
+ 'r': 9,
38
+ 'f': 10,
39
+ 'tab': 11,
40
+ 'mouse0': 12, // Left click
41
+ 'mouse1': 13, // Right click
42
+ 'mouse2': 14, // Middle click
43
+ 'jump': 4, // Alias for space
44
+ };
45
+ const KEY_NAMES = ['w', 'a', 's', 'd', 'space', 'shift', 'ctrl', 'e', 'q', 'r', 'f', 'tab', 'mouse0', 'mouse1', 'mouse2'];
46
+ /**
47
+ * Encode a game input to compact binary
48
+ * Returns null if input cannot be encoded (will fall back to JSON)
49
+ */
50
+ function encodeGameInput(input, playerId) {
51
+ if (!input) {
52
+ return encodeCustom(input);
53
+ }
54
+ const type = input.type || 'move';
55
+ switch (type) {
56
+ case 'move':
57
+ case 'input':
58
+ case undefined:
59
+ return encodeMove(input, playerId);
60
+ case 'join':
61
+ return encodeJoin(input);
62
+ case 'leave':
63
+ return encodeLeave(input);
64
+ default:
65
+ return encodeCustom(input);
66
+ }
67
+ }
68
+ /**
69
+ * Encode move/input - the most common and bandwidth-critical input type
70
+ * Format: [MOVE:1][keys:2][mouseX:2][mouseY:2][yaw:2][pitch:2][pidLen:1][pid:var] = 12+ bytes
71
+ */
72
+ function encodeMove(input, playerId) {
73
+ const pid = playerId || input.pid || '';
74
+ const pidBytes = new TextEncoder().encode(pid);
75
+ // 1 + 2 + 2 + 2 + 2 + 2 + 1 + pidLen = 12 + pidLen bytes
76
+ const buf = new Uint8Array(12 + pidBytes.length);
77
+ const view = new DataView(buf.buffer);
78
+ buf[0] = INPUT_TYPE.MOVE;
79
+ // Encode keys as bitmask
80
+ let keyBits = 0;
81
+ if (input.keys) {
82
+ for (const [key, pressed] of Object.entries(input.keys)) {
83
+ if (pressed) {
84
+ const bit = KEY_BITS[key.toLowerCase()];
85
+ if (bit !== undefined) {
86
+ keyBits |= (1 << bit);
87
+ }
88
+ }
89
+ }
90
+ }
91
+ view.setUint16(1, keyBits, true);
92
+ // Mouse position as uint16 (0-65535 range, plenty for screens)
93
+ const mouseX = Math.max(0, Math.min(65535, Math.round(input.mouseX ?? input.x ?? 0)));
94
+ const mouseY = Math.max(0, Math.min(65535, Math.round(input.mouseY ?? input.y ?? 0)));
95
+ view.setUint16(3, mouseX, true);
96
+ view.setUint16(5, mouseY, true);
97
+ // Yaw/pitch as int16 (scaled by 10000 for precision)
98
+ // Yaw range: [-π, π] -> [-31416, 31416] fits in int16
99
+ const yawScaled = Math.round((input.yaw ?? 0) * 10000);
100
+ const pitchScaled = Math.round((input.pitch ?? 0) * 10000);
101
+ view.setInt16(7, Math.max(-32768, Math.min(32767, yawScaled)), true);
102
+ view.setInt16(9, Math.max(-32768, Math.min(32767, pitchScaled)), true);
103
+ // Player ID
104
+ buf[11] = pidBytes.length;
105
+ buf.set(pidBytes, 12);
106
+ return buf;
107
+ }
108
+ /**
109
+ * Encode join event
110
+ * Format: [JOIN:1][pidLen:1][pid:var][nameLen:1][name:var]
111
+ */
112
+ function encodeJoin(input) {
113
+ const pid = input.user?.id || input.id || '';
114
+ const name = input.user?.name || '';
115
+ const pidBytes = new TextEncoder().encode(pid);
116
+ const nameBytes = new TextEncoder().encode(name);
117
+ const buf = new Uint8Array(3 + pidBytes.length + nameBytes.length);
118
+ buf[0] = INPUT_TYPE.JOIN;
119
+ buf[1] = pidBytes.length;
120
+ buf.set(pidBytes, 2);
121
+ buf[2 + pidBytes.length] = nameBytes.length;
122
+ buf.set(nameBytes, 3 + pidBytes.length);
123
+ return buf;
124
+ }
125
+ /**
126
+ * Encode leave event
127
+ * Format: [LEAVE:1][pidLen:1][pid:var]
128
+ */
129
+ function encodeLeave(input) {
130
+ const pid = input.id || '';
131
+ const pidBytes = new TextEncoder().encode(pid);
132
+ const buf = new Uint8Array(2 + pidBytes.length);
133
+ buf[0] = INPUT_TYPE.LEAVE;
134
+ buf[1] = pidBytes.length;
135
+ buf.set(pidBytes, 2);
136
+ return buf;
137
+ }
138
+ /**
139
+ * Encode custom/unknown input types as JSON (fallback)
140
+ * Format: [CUSTOM:1][len:2][json:var]
141
+ */
142
+ function encodeCustom(input) {
143
+ const json = JSON.stringify(input);
144
+ const jsonBytes = new TextEncoder().encode(json);
145
+ const buf = new Uint8Array(3 + jsonBytes.length);
146
+ const view = new DataView(buf.buffer);
147
+ buf[0] = INPUT_TYPE.CUSTOM;
148
+ view.setUint16(1, jsonBytes.length, true);
149
+ buf.set(jsonBytes, 3);
150
+ return buf;
151
+ }
152
+ /**
153
+ * Decode binary input back to object
154
+ */
155
+ function decodeGameInput(buf, offset = 0) {
156
+ const data = buf instanceof ArrayBuffer ? new Uint8Array(buf) : buf;
157
+ if (data.length <= offset)
158
+ return null;
159
+ const type = data[offset];
160
+ switch (type) {
161
+ case INPUT_TYPE.MOVE:
162
+ return decodeMove(data, offset);
163
+ case INPUT_TYPE.JOIN:
164
+ return decodeJoin(data, offset);
165
+ case INPUT_TYPE.LEAVE:
166
+ return decodeLeave(data, offset);
167
+ case INPUT_TYPE.CUSTOM:
168
+ return decodeCustom(data, offset);
169
+ default:
170
+ return null;
171
+ }
172
+ }
173
+ function decodeMove(data, offset) {
174
+ if (data.length < offset + 12)
175
+ return null;
176
+ const view = new DataView(data.buffer, data.byteOffset + offset);
177
+ const keyBits = view.getUint16(1, true);
178
+ const mouseX = view.getUint16(3, true);
179
+ const mouseY = view.getUint16(5, true);
180
+ const yawScaled = view.getInt16(7, true);
181
+ const pitchScaled = view.getInt16(9, true);
182
+ const pidLen = data[offset + 11];
183
+ if (data.length < offset + 12 + pidLen)
184
+ return null;
185
+ const pid = new TextDecoder().decode(data.slice(offset + 12, offset + 12 + pidLen));
186
+ // Decode keys
187
+ const keys = {};
188
+ for (let i = 0; i < KEY_NAMES.length; i++) {
189
+ keys[KEY_NAMES[i]] = (keyBits & (1 << i)) !== 0;
190
+ }
191
+ return {
192
+ input: {
193
+ type: 'input',
194
+ keys,
195
+ mouseX,
196
+ mouseY,
197
+ yaw: yawScaled / 10000,
198
+ pitch: pitchScaled / 10000,
199
+ pid: pid || undefined,
200
+ },
201
+ bytesRead: 12 + pidLen
202
+ };
203
+ }
204
+ function decodeJoin(data, offset) {
205
+ if (data.length < offset + 3)
206
+ return null;
207
+ const pidLen = data[offset + 1];
208
+ if (data.length < offset + 2 + pidLen + 1)
209
+ return null;
210
+ const pid = new TextDecoder().decode(data.slice(offset + 2, offset + 2 + pidLen));
211
+ const nameLen = data[offset + 2 + pidLen];
212
+ if (data.length < offset + 3 + pidLen + nameLen)
213
+ return null;
214
+ const name = new TextDecoder().decode(data.slice(offset + 3 + pidLen, offset + 3 + pidLen + nameLen));
215
+ return {
216
+ input: {
217
+ type: 'join',
218
+ user: { id: pid, name: name || undefined },
219
+ id: pid,
220
+ },
221
+ bytesRead: 3 + pidLen + nameLen
222
+ };
223
+ }
224
+ function decodeLeave(data, offset) {
225
+ if (data.length < offset + 2)
226
+ return null;
227
+ const pidLen = data[offset + 1];
228
+ if (data.length < offset + 2 + pidLen)
229
+ return null;
230
+ const pid = new TextDecoder().decode(data.slice(offset + 2, offset + 2 + pidLen));
231
+ return {
232
+ input: {
233
+ type: 'leave',
234
+ id: pid,
235
+ },
236
+ bytesRead: 2 + pidLen
237
+ };
238
+ }
239
+ function decodeCustom(data, offset) {
240
+ if (data.length < offset + 3)
241
+ return null;
242
+ const view = new DataView(data.buffer, data.byteOffset + offset);
243
+ const jsonLen = view.getUint16(1, true);
244
+ if (data.length < offset + 3 + jsonLen)
245
+ return null;
246
+ const json = new TextDecoder().decode(data.slice(offset + 3, offset + 3 + jsonLen));
247
+ try {
248
+ return {
249
+ input: JSON.parse(json),
250
+ bytesRead: 3 + jsonLen
251
+ };
252
+ }
253
+ catch {
254
+ return null;
255
+ }
256
+ }
257
+ /**
258
+ * Check if an input will use compact binary encoding (vs JSON fallback)
259
+ */
260
+ function isCompactInput(input) {
261
+ const type = input?.type;
262
+ return type === 'move' || type === 'input' || type === 'join' || type === 'leave' || type === undefined;
263
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './modd-network';
1
+ export { connect as networkConnect, modd, type Connection, type ConnectOptions, type Input } from './modd-network';
2
2
  export * from './modd-engine';
package/dist/index.js CHANGED
@@ -14,5 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./modd-network"), exports);
17
+ exports.modd = exports.networkConnect = void 0;
18
+ // Re-export modd-network (but rename connect to avoid conflict)
19
+ var modd_network_1 = require("./modd-network");
20
+ Object.defineProperty(exports, "networkConnect", { enumerable: true, get: function () { return modd_network_1.connect; } });
21
+ Object.defineProperty(exports, "modd", { enumerable: true, get: function () { return modd_network_1.modd; } });
22
+ // Re-export modd-engine (this is the main API)
18
23
  __exportStar(require("./modd-engine"), exports);
24
+ // modd-engine.connect is the primary connect function
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Input Codec - Compresses readable inputs to binary
3
+ *
4
+ * Game sends: { type: 'keydown', key: 'w' }
5
+ * Wire sends: [0x01, 0x80] (2 bytes)
6
+ *
7
+ * Game sends: { type: 'camera', yaw: 1.5, pitch: 0.3 }
8
+ * Wire sends: [0x02, yaw_lo, yaw_hi, pitch_lo, pitch_hi] (5 bytes)
9
+ */
10
+ /**
11
+ * Compress a readable input to binary
12
+ */
13
+ export declare function compress(input: any): Uint8Array | null;
14
+ /**
15
+ * Compress multiple inputs into single buffer
16
+ */
17
+ export declare function compressBatch(inputs: any[]): Uint8Array | null;
18
+ /**
19
+ * Decompress binary back to readable input
20
+ */
21
+ export declare function decompress(buf: Uint8Array, offset?: number): {
22
+ input: any;
23
+ bytesRead: number;
24
+ } | null;
25
+ /**
26
+ * Decompress a batch of inputs
27
+ */
28
+ export declare function decompressBatch(buf: Uint8Array): any[];
29
+ /**
30
+ * Check if an input can be compressed
31
+ * Note: join/leave are excluded because they contain unique player ID data
32
+ */
33
+ export declare function canCompress(input: any): boolean;