@carverjs/multiplayer 0.0.1

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.
Files changed (43) hide show
  1. package/dist/NetworkManager-DrKM2tEx.d.mts +369 -0
  2. package/dist/NetworkManager-nvVAOr1O.d.ts +369 -0
  3. package/dist/chunk-3KT73N2S.mjs +655 -0
  4. package/dist/chunk-3KT73N2S.mjs.map +1 -0
  5. package/dist/chunk-EO3YNPRQ.mjs +817 -0
  6. package/dist/chunk-EO3YNPRQ.mjs.map +1 -0
  7. package/dist/chunk-UD6FDZMX.mjs +581 -0
  8. package/dist/chunk-UD6FDZMX.mjs.map +1 -0
  9. package/dist/firebase-CPu87KA0.d.ts +100 -0
  10. package/dist/firebase-PE6MxGdJ.d.mts +100 -0
  11. package/dist/index.d.mts +316 -0
  12. package/dist/index.d.ts +316 -0
  13. package/dist/index.js +3817 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/index.mjs +1743 -0
  16. package/dist/index.mjs.map +1 -0
  17. package/dist/strategy.d.mts +7 -0
  18. package/dist/strategy.d.ts +7 -0
  19. package/dist/strategy.js +619 -0
  20. package/dist/strategy.js.map +1 -0
  21. package/dist/strategy.mjs +11 -0
  22. package/dist/strategy.mjs.map +1 -0
  23. package/dist/sync.d.mts +212 -0
  24. package/dist/sync.d.ts +212 -0
  25. package/dist/sync.js +845 -0
  26. package/dist/sync.js.map +1 -0
  27. package/dist/sync.mjs +11 -0
  28. package/dist/sync.mjs.map +1 -0
  29. package/dist/transport.d.mts +159 -0
  30. package/dist/transport.d.ts +159 -0
  31. package/dist/transport.js +1274 -0
  32. package/dist/transport.js.map +1 -0
  33. package/dist/transport.mjs +19 -0
  34. package/dist/transport.mjs.map +1 -0
  35. package/dist/types-5LHBOW08.d.mts +74 -0
  36. package/dist/types-5LHBOW08.d.ts +74 -0
  37. package/dist/types.d.mts +2 -0
  38. package/dist/types.d.ts +2 -0
  39. package/dist/types.js +19 -0
  40. package/dist/types.js.map +1 -0
  41. package/dist/types.mjs +1 -0
  42. package/dist/types.mjs.map +1 -0
  43. package/package.json +73 -0
@@ -0,0 +1,369 @@
1
+ import { S as SignalingStrategy } from './types-5LHBOW08.mjs';
2
+
3
+ type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'migrating' | 'reconnecting';
4
+ type RoomState = 'lobby' | 'playing' | 'ended';
5
+ interface Room {
6
+ id: string;
7
+ name: string;
8
+ hostId: string;
9
+ playerCount: number;
10
+ maxPlayers: number;
11
+ gameMode?: string;
12
+ isPrivate: boolean;
13
+ metadata: Record<string, unknown>;
14
+ createdAt: number;
15
+ state: RoomState;
16
+ }
17
+ interface RoomConfig {
18
+ name: string;
19
+ maxPlayers?: number;
20
+ gameMode?: string;
21
+ password?: string;
22
+ isPrivate?: boolean;
23
+ metadata?: Record<string, unknown>;
24
+ }
25
+ interface Player {
26
+ peerId: string;
27
+ displayName: string;
28
+ isHost: boolean;
29
+ isSelf: boolean;
30
+ isReady: boolean;
31
+ isConnected: boolean;
32
+ metadata: Record<string, unknown>;
33
+ latencyMs: number;
34
+ joinedAt: number;
35
+ }
36
+ interface CarverTransport {
37
+ readonly peerId: string;
38
+ readonly peers: ReadonlySet<string>;
39
+ readonly hostId: string;
40
+ readonly isHost: boolean;
41
+ readonly room?: Room;
42
+ readonly initialPlayers?: Player[];
43
+ onPeerJoin(cb: (peerId: string) => void): void;
44
+ onPeerLeave(cb: (peerId: string) => void): void;
45
+ onPeerUpdated(cb: (player: Player) => void): void;
46
+ onHostChanged(cb: (newHostId: string) => void): void;
47
+ createChannel<T = unknown>(name: string, options?: ChannelOptions): CarverChannel<T>;
48
+ connect(roomId: string, config?: TransportConfig): Promise<void>;
49
+ disconnect(): void;
50
+ setReady?(ready: boolean): void;
51
+ setMetadata?(metadata: Record<string, unknown>): void;
52
+ setRoomMetadata?(metadata: Record<string, unknown>): void;
53
+ kick?(peerId: string, reason?: string): void;
54
+ transferHost?(peerId: string): void;
55
+ setRoomState?(state: RoomState): void;
56
+ setMaxPlayers?(n: number): void;
57
+ lockRoom?(): void;
58
+ unlockRoom?(): void;
59
+ requestRoomList?(): void;
60
+ }
61
+ interface CarverChannel<T = unknown> {
62
+ send(data: T, target?: string | string[]): void;
63
+ onReceive(cb: (data: T, peerId: string) => void): void;
64
+ close(): void;
65
+ }
66
+ interface ChannelOptions {
67
+ reliable?: boolean;
68
+ ordered?: boolean;
69
+ maxRetransmits?: number;
70
+ }
71
+ interface TransportConfig {
72
+ displayName?: string;
73
+ playerMetadata?: Record<string, unknown>;
74
+ password?: string;
75
+ iceServers?: RTCIceServer[];
76
+ iceTransportPolicy?: RTCIceTransportPolicy;
77
+ maxPlayers?: number;
78
+ roomConfig?: RoomConfig;
79
+ }
80
+
81
+ type SyncMode = 'events' | 'snapshot' | 'prediction';
82
+ type NetworkQuality = 'good' | 'degraded' | 'poor';
83
+ interface EntityState2D {
84
+ id: string;
85
+ x: number;
86
+ y: number;
87
+ a: number;
88
+ vx: number;
89
+ vy: number;
90
+ va: number;
91
+ c?: Record<string, unknown>;
92
+ }
93
+ interface EntityState3D {
94
+ id: string;
95
+ x: number;
96
+ y: number;
97
+ z: number;
98
+ qx: number;
99
+ qy: number;
100
+ qz: number;
101
+ qw: number;
102
+ vx: number;
103
+ vy: number;
104
+ vz: number;
105
+ wx: number;
106
+ wy: number;
107
+ wz: number;
108
+ c?: Record<string, unknown>;
109
+ }
110
+ type EntityState = EntityState2D | EntityState3D;
111
+ interface SnapshotPacket {
112
+ t: number;
113
+ b: number;
114
+ s: Uint8Array;
115
+ hi?: unknown;
116
+ }
117
+ interface InputPacket {
118
+ t: number;
119
+ i: unknown;
120
+ p: string;
121
+ }
122
+ interface EventPacket {
123
+ type: string;
124
+ payload: unknown;
125
+ sender: string;
126
+ target?: string;
127
+ }
128
+ type CarverErrorCode = 'ROOM_NOT_FOUND' | 'ROOM_FULL' | 'ROOM_LOCKED' | 'INVALID_PASSWORD' | 'CONNECTION_FAILED' | 'HOST_UNREACHABLE' | 'KICKED' | 'SIGNALING_ERROR' | 'TURN_CREDENTIAL_ERROR' | 'TRANSPORT_ERROR' | 'MIGRATION_FAILED';
129
+ interface CarverMultiplayerError {
130
+ code: CarverErrorCode;
131
+ message: string;
132
+ recoverable: boolean;
133
+ }
134
+ interface UseRoomOptions {
135
+ /** Supply a custom CarverTransport instance to bypass the built-in WebRTCTransport. */
136
+ transport?: CarverTransport;
137
+ password?: string;
138
+ displayName?: string;
139
+ playerMetadata?: Record<string, unknown>;
140
+ /** Override ICE servers for this room (overrides provider-level config). */
141
+ iceServers?: RTCIceServer[];
142
+ hostMigration?: boolean;
143
+ reconnectAttempts?: number;
144
+ reconnectIntervalMs?: number;
145
+ /** ICE transport policy: 'all' (default) or 'relay' (force TURN only). */
146
+ privacy?: 'all' | 'relay';
147
+ onConnected?: () => void;
148
+ onDisconnected?: (reason: string) => void;
149
+ onHostMigration?: (newHostId: string) => void;
150
+ onError?: (error: CarverMultiplayerError) => void;
151
+ }
152
+ interface UseLobbyOptions {
153
+ autoRefresh?: boolean;
154
+ filter?: {
155
+ maxPlayers?: number;
156
+ gameMode?: string;
157
+ hasPassword?: boolean;
158
+ };
159
+ }
160
+ interface UseMultiplayerOptions {
161
+ mode?: SyncMode;
162
+ tickRate?: number;
163
+ broadcastRate?: number;
164
+ keyframeInterval?: number;
165
+ quantize?: {
166
+ position?: number;
167
+ rotation?: number;
168
+ velocity?: number;
169
+ };
170
+ deltaThresholds?: {
171
+ position?: number;
172
+ rotation?: number;
173
+ velocity?: number;
174
+ custom?: 'strict' | number;
175
+ };
176
+ prediction?: {
177
+ maxRewindTicks?: number;
178
+ errorSmoothingDecay?: number;
179
+ maxErrorPerFrame?: number;
180
+ snapThreshold?: number;
181
+ lagCompensation?: boolean;
182
+ };
183
+ interpolation?: {
184
+ bufferSize?: number;
185
+ method?: 'hermite' | 'linear';
186
+ extrapolateMs?: number;
187
+ };
188
+ interestManagement?: {
189
+ enabled?: boolean;
190
+ cellSize?: number;
191
+ defaultRadius?: number;
192
+ alwaysRelevant?: string[];
193
+ };
194
+ debug?: {
195
+ overlay?: boolean;
196
+ simulatedLatencyMs?: number;
197
+ simulatedPacketLoss?: number;
198
+ logLevel?: 'none' | 'error' | 'warn' | 'verbose';
199
+ };
200
+ onPhysicsStep?: (inputs: Map<string, unknown>, tick: number, isRollback: boolean) => void;
201
+ }
202
+ interface MultiplayerContextValue {
203
+ appId: string;
204
+ strategy: SignalingStrategy;
205
+ iceServers?: RTCIceServer[];
206
+ networkManager: NetworkManager;
207
+ }
208
+ interface JoinOptions {
209
+ password?: string;
210
+ displayName?: string;
211
+ playerMetadata?: Record<string, unknown>;
212
+ }
213
+
214
+ /**
215
+ * Accumulator-based fixed timestep with drift-aware time dilation.
216
+ * Adapted from lumbernet's LumberTickKeeper.
217
+ */
218
+ declare class TickKeeper {
219
+ private _tickRate;
220
+ private _tickDelta;
221
+ private _accumulator;
222
+ private _tick;
223
+ private _serverTick;
224
+ private _alpha;
225
+ private _timeScale;
226
+ private static readonly DRIFT_BEHIND_THRESHOLD;
227
+ private static readonly DRIFT_AHEAD_THRESHOLD;
228
+ private static readonly SPEED_UP_SCALE;
229
+ private static readonly SLOW_DOWN_SCALE;
230
+ private static readonly NORMAL_SCALE;
231
+ constructor(tickRate?: number);
232
+ get tick(): number;
233
+ get serverTick(): number;
234
+ get tickDelta(): number;
235
+ get tickRate(): number;
236
+ /** Interpolation alpha for rendering between ticks (0-1) */
237
+ get alpha(): number;
238
+ /** Current time scale (affected by drift correction) */
239
+ get timeScale(): number;
240
+ /** Ticks ahead of server (positive = ahead, negative = behind) */
241
+ get drift(): number;
242
+ /** Update server tick from received snapshot */
243
+ setServerTick(serverTick: number): void;
244
+ /**
245
+ * Accumulate time and return the number of fixed ticks to process.
246
+ * Call this once per render frame with the raw frame delta.
247
+ */
248
+ update(rawDelta: number): number;
249
+ /** Reset to initial state */
250
+ reset(): void;
251
+ /** Set tick rate (updates tickDelta accordingly) */
252
+ setTickRate(rate: number): void;
253
+ private _updateDriftCorrection;
254
+ }
255
+
256
+ /** Configuration for delta thresholds */
257
+ interface DeltaThresholds {
258
+ position: number;
259
+ rotation: number;
260
+ velocity: number;
261
+ custom: 'strict' | number;
262
+ }
263
+ /** Quantization config: number of decimal places to keep */
264
+ interface QuantizeConfig {
265
+ position?: number;
266
+ rotation?: number;
267
+ velocity?: number;
268
+ }
269
+ /**
270
+ * Snapshot ring buffer: stores recent snapshots for delta computation.
271
+ */
272
+ declare class SnapshotBuffer {
273
+ private _buffer;
274
+ private _capacity;
275
+ constructor(capacity?: number);
276
+ /** Store a snapshot at the given tick */
277
+ store(tick: number, entities: Map<string, EntityState>): void;
278
+ /** Get a snapshot at the given tick */
279
+ get(tick: number): Map<string, EntityState> | undefined;
280
+ /** Clear all stored snapshots */
281
+ clear(): void;
282
+ }
283
+ /**
284
+ * Codec handles serialization and delta compression for network state.
285
+ */
286
+ declare class Codec {
287
+ private _thresholds;
288
+ private _quantize;
289
+ private _is2D;
290
+ constructor(options?: {
291
+ thresholds?: Partial<DeltaThresholds>;
292
+ quantize?: QuantizeConfig;
293
+ is2D?: boolean;
294
+ });
295
+ /** Serialize entity states to binary (msgpackr) */
296
+ serialize(entities: EntityState[]): Uint8Array;
297
+ /** Deserialize binary to entity states */
298
+ deserialize(data: Uint8Array): EntityState[];
299
+ /**
300
+ * Compute delta: only include entities that changed beyond thresholds
301
+ * since the baseline snapshot.
302
+ * Returns null if nothing changed.
303
+ */
304
+ computeDelta(current: Map<string, EntityState>, baseline: Map<string, EntityState> | undefined): EntityState[] | null;
305
+ /** Serialize a delta snapshot packet */
306
+ serializeDelta(tick: number, baseTick: number, current: Map<string, EntityState>, baseline: Map<string, EntityState> | undefined): Uint8Array | null;
307
+ /** Deserialize a snapshot packet */
308
+ deserializePacket(data: Uint8Array): {
309
+ tick: number;
310
+ baseTick: number;
311
+ entities: EntityState[];
312
+ };
313
+ private _hasChanged;
314
+ private _quantizeEntity;
315
+ }
316
+
317
+ /**
318
+ * Central orchestrator for the multiplayer system.
319
+ * Holds references to the active transport, sync engine, room state, and codec.
320
+ * One instance per MultiplayerProvider.
321
+ */
322
+ declare class NetworkManager {
323
+ private _transport;
324
+ private _connectionState;
325
+ private _room;
326
+ private _players;
327
+ private _syncMode;
328
+ private _tickKeeper;
329
+ private _codec;
330
+ private _snapshotBuffer;
331
+ private _networkQuality;
332
+ private _options;
333
+ private _connectionListeners;
334
+ private _playerListeners;
335
+ private _roomListeners;
336
+ private _errorListeners;
337
+ constructor(options?: UseMultiplayerOptions);
338
+ get transport(): CarverTransport | null;
339
+ get connectionState(): ConnectionState;
340
+ get room(): Room | null;
341
+ get players(): Map<string, Player>;
342
+ get selfId(): string | null;
343
+ get isHost(): boolean;
344
+ get hostId(): string | null;
345
+ get syncMode(): SyncMode;
346
+ get tickKeeper(): TickKeeper;
347
+ get codec(): Codec;
348
+ get snapshotBuffer(): SnapshotBuffer;
349
+ get networkQuality(): NetworkQuality;
350
+ get options(): UseMultiplayerOptions;
351
+ setTransport(transport: CarverTransport): void;
352
+ setConnectionState(state: ConnectionState): void;
353
+ onConnectionStateChange(cb: (state: ConnectionState) => void): () => void;
354
+ setRoom(room: Room): void;
355
+ onRoomChange(cb: () => void): () => void;
356
+ setPlayers(players: Player[]): void;
357
+ updatePlayer(player: Player): void;
358
+ removePlayer(peerId: string): void;
359
+ onPlayersChange(cb: () => void): () => void;
360
+ emitError(error: CarverMultiplayerError): void;
361
+ onError(cb: (error: CarverMultiplayerError) => void): () => void;
362
+ setNetworkQuality(quality: NetworkQuality): void;
363
+ updateOptions(options: UseMultiplayerOptions): void;
364
+ destroy(): void;
365
+ private _notifyPlayerListeners;
366
+ private _notifyRoomListeners;
367
+ }
368
+
369
+ export { type CarverTransport as C, type EntityState as E, type InputPacket as I, type JoinOptions as J, type MultiplayerContextValue as M, type NetworkQuality as N, type Player as P, type Room as R, SnapshotBuffer as S, type TransportConfig as T, type UseRoomOptions as U, type ChannelOptions as a, type CarverChannel as b, type RoomState as c, Codec as d, TickKeeper as e, type EntityState2D as f, type EntityState3D as g, type EventPacket as h, type SnapshotPacket as i, type SyncMode as j, NetworkManager as k, type ConnectionState as l, type CarverMultiplayerError as m, type UseLobbyOptions as n, type RoomConfig as o, type UseMultiplayerOptions as p, type CarverErrorCode as q };