@carverjs/multiplayer 0.0.1 → 0.0.2
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.
- package/dist/InputBuffer-J6XT_Tt0.d.mts +61 -0
- package/dist/InputBuffer-V7XfHbc6.d.ts +61 -0
- package/dist/{NetworkManager-nvVAOr1O.d.ts → NetworkManager-D-DxFgdM.d.mts} +66 -14
- package/dist/{NetworkManager-DrKM2tEx.d.mts → NetworkManager-DH9uGVMg.d.ts} +66 -14
- package/dist/{chunk-UD6FDZMX.mjs → chunk-CBTAOVXP.mjs} +34 -3
- package/dist/chunk-CBTAOVXP.mjs.map +1 -0
- package/dist/{chunk-EO3YNPRQ.mjs → chunk-Q25TJEY4.mjs} +494 -204
- package/dist/chunk-Q25TJEY4.mjs.map +1 -0
- package/dist/{chunk-3KT73N2S.mjs → chunk-UKEFWQ76.mjs} +0 -0
- package/dist/chunk-UKEFWQ76.mjs.map +1 -0
- package/dist/{firebase-CPu87KA0.d.ts → firebase-B5MgLlHk.d.ts} +6 -1
- package/dist/{firebase-PE6MxGdJ.d.mts → firebase-GrbVrNgs.d.mts} +6 -1
- package/dist/index.d.mts +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.js +744 -245
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +172 -37
- package/dist/index.mjs.map +1 -1
- package/dist/strategy.d.mts +2 -2
- package/dist/strategy.d.ts +2 -2
- package/dist/strategy.js +33 -2
- package/dist/strategy.js.map +1 -1
- package/dist/strategy.mjs +1 -1
- package/dist/sync.d.mts +134 -50
- package/dist/sync.d.ts +134 -50
- package/dist/sync.js +499 -205
- package/dist/sync.js.map +1 -1
- package/dist/sync.mjs +15 -3
- package/dist/transport.d.mts +0 -0
- package/dist/transport.d.ts +0 -0
- package/dist/transport.js +0 -0
- package/dist/transport.js.map +1 -1
- package/dist/transport.mjs +2 -2
- package/dist/{types-5LHBOW08.d.mts → types-hNfCIBzj.d.mts} +7 -0
- package/dist/{types-5LHBOW08.d.ts → types-hNfCIBzj.d.ts} +7 -0
- package/dist/types.d.mts +2 -2
- package/dist/types.d.ts +2 -2
- package/dist/types.js.map +1 -1
- package/package.json +26 -5
- package/dist/chunk-3KT73N2S.mjs.map +0 -1
- package/dist/chunk-EO3YNPRQ.mjs.map +0 -1
- package/dist/chunk-UD6FDZMX.mjs.map +0 -1
package/dist/sync.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { C as CarverTransport,
|
|
2
|
-
export {
|
|
3
|
-
import './
|
|
1
|
+
import { C as CarverTransport, e as Codec, S as SnapshotBuffer, E as EntityState, P as PlayerInput, N as NetworkQuality, f as SnapshotListener, g as SnapshotSource, h as TickKeeper, i as PredictionSyncOptions, j as PhysicsStepCallback, k as PredictionWorldDriver, l as ErrorOffset } from './NetworkManager-DH9uGVMg.js';
|
|
2
|
+
export { m as EntityState2D, n as EntityState3D, o as EventPacket, I as InputPacket, p as SnapshotPacket, q as SyncMode } from './NetworkManager-DH9uGVMg.js';
|
|
3
|
+
import { I as InputBuffer } from './InputBuffer-V7XfHbc6.js';
|
|
4
|
+
import './types-hNfCIBzj.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Layer 1: Event-based messaging over a reliable+ordered channel.
|
|
@@ -59,10 +60,11 @@ declare class HostAuthority {
|
|
|
59
60
|
/**
|
|
60
61
|
* Called every fixed tick by the sync engine.
|
|
61
62
|
* Collects entity states and decides whether to broadcast.
|
|
63
|
+
* `hostInput` (prediction mode) is embedded in the snapshot packet as `hi`.
|
|
62
64
|
*/
|
|
63
|
-
tick(currentTick: number, entities: Map<string, EntityState>, delta: number): void;
|
|
65
|
+
tick(currentTick: number, entities: Map<string, EntityState>, delta: number, hostInput?: PlayerInput): void;
|
|
64
66
|
/** Force a keyframe broadcast to all clients (e.g., after host migration) */
|
|
65
|
-
forceKeyframe(currentTick: number, entities: Map<string, EntityState
|
|
67
|
+
forceKeyframe(currentTick: number, entities: Map<string, EntityState>, hostInput?: PlayerInput): void;
|
|
66
68
|
destroy(): void;
|
|
67
69
|
private _broadcastToClient;
|
|
68
70
|
}
|
|
@@ -87,6 +89,7 @@ declare class ClientReceiver {
|
|
|
87
89
|
private _packetCount;
|
|
88
90
|
private _is2D;
|
|
89
91
|
private _fullState;
|
|
92
|
+
private _snapshotListeners;
|
|
90
93
|
constructor(transport: CarverTransport, codec: Codec, options?: {
|
|
91
94
|
bufferSize?: number;
|
|
92
95
|
method?: "hermite" | "linear";
|
|
@@ -103,6 +106,8 @@ declare class ClientReceiver {
|
|
|
103
106
|
interpolate(renderTime: number): Map<string, EntityState>;
|
|
104
107
|
/** Request a keyframe from the host */
|
|
105
108
|
requestKeyframe(): void;
|
|
109
|
+
/** Register a listener fired after each snapshot is merged into the full world state */
|
|
110
|
+
onSnapshot(cb: SnapshotListener): void;
|
|
106
111
|
destroy(): void;
|
|
107
112
|
private _handleSnapshot;
|
|
108
113
|
private _interpolateEntity;
|
|
@@ -123,18 +128,21 @@ interface SnapshotSyncOptions {
|
|
|
123
128
|
* Layer 2: Snapshot interpolation sync engine.
|
|
124
129
|
* Host broadcasts state at fixed intervals, clients interpolate.
|
|
125
130
|
*/
|
|
126
|
-
declare class SnapshotSync {
|
|
131
|
+
declare class SnapshotSync implements SnapshotSource {
|
|
127
132
|
private _transport;
|
|
128
133
|
private _hostAuthority;
|
|
129
134
|
private _clientReceiver;
|
|
130
135
|
private _codec;
|
|
131
136
|
private _snapshotBuffer;
|
|
137
|
+
private _snapshotListeners;
|
|
132
138
|
constructor(transport: CarverTransport, codec: Codec, snapshotBuffer: SnapshotBuffer, options?: SnapshotSyncOptions);
|
|
133
139
|
get isHost(): boolean;
|
|
134
140
|
get hostAuthority(): HostAuthority | null;
|
|
135
141
|
get clientReceiver(): ClientReceiver | null;
|
|
136
142
|
/** Host: called every fixed tick to potentially broadcast state */
|
|
137
|
-
hostTick(tick: number, entities: Map<string, EntityState>, delta: number): void;
|
|
143
|
+
hostTick(tick: number, entities: Map<string, EntityState>, delta: number, hostInput?: PlayerInput): void;
|
|
144
|
+
/** Register a listener fired after each merged snapshot (client side). */
|
|
145
|
+
onSnapshot(cb: SnapshotListener): void;
|
|
138
146
|
/** Client: called every render frame to interpolate */
|
|
139
147
|
clientInterpolate(renderTime: number): Map<string, EntityState>;
|
|
140
148
|
/** Set interest filter on host authority */
|
|
@@ -144,69 +152,145 @@ declare class SnapshotSync {
|
|
|
144
152
|
/** Handle host migration: switch from host to client mode */
|
|
145
153
|
demoteToClient(options?: SnapshotSyncOptions): void;
|
|
146
154
|
destroy(): void;
|
|
155
|
+
/** Forward receiver snapshots to registered listeners (survives host migration). */
|
|
156
|
+
private _attachSnapshotForwarder;
|
|
147
157
|
}
|
|
148
158
|
|
|
149
|
-
interface PredictionOptions {
|
|
150
|
-
maxRewindTicks: number;
|
|
151
|
-
errorSmoothingDecay: number;
|
|
152
|
-
maxErrorPerFrame: number;
|
|
153
|
-
snapThreshold: number;
|
|
154
|
-
lagCompensation: boolean;
|
|
155
|
-
}
|
|
156
159
|
/**
|
|
157
|
-
* Layer 3:
|
|
158
|
-
*
|
|
160
|
+
* Layer 3: Full-world prediction with full-world rollback.
|
|
161
|
+
* Ported from LumberNet, built on top of Layer 2 (SnapshotSync) as the
|
|
162
|
+
* authoritative state channel.
|
|
159
163
|
*
|
|
160
164
|
* Flow:
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
+
* Every peer (host included): broadcast tick-stamped input to ALL peers each
|
|
166
|
+
* fixed tick on carver:inputs, simulate EVERY networked entity forward with
|
|
167
|
+
* last-known remote inputs (hold-last-input extrapolation).
|
|
168
|
+
*
|
|
169
|
+
* Host: stays authoritative; SnapshotSync broadcasts delta-compressed,
|
|
170
|
+
* ACK-driven snapshots with the host's own input embedded (`hi`).
|
|
171
|
+
*
|
|
172
|
+
* Client: on each accepted snapshot, reset ALL networked entities to server
|
|
173
|
+
* state, resimulate from serverTick + 1 to localTick replaying per-tick
|
|
174
|
+
* inputs for every peer, and convert the visual discontinuity into
|
|
175
|
+
* per-entity error offsets decayed per render frame.
|
|
176
|
+
*
|
|
177
|
+
* Role is checked dynamically via transport.isHost at every use site (host
|
|
178
|
+
* migration is best-effort).
|
|
165
179
|
*/
|
|
180
|
+
|
|
166
181
|
declare class PredictionSync {
|
|
167
182
|
private _transport;
|
|
168
|
-
private _codec;
|
|
169
183
|
private _tickKeeper;
|
|
170
184
|
private _options;
|
|
171
185
|
private _inputChannel;
|
|
172
|
-
private
|
|
173
|
-
private
|
|
174
|
-
private
|
|
175
|
-
private
|
|
176
|
-
private _predictedState;
|
|
177
|
-
private _errorCorrections;
|
|
178
|
-
private _serverState;
|
|
186
|
+
private _inputs;
|
|
187
|
+
private _currentInput;
|
|
188
|
+
private _pending;
|
|
189
|
+
private _errors;
|
|
179
190
|
private _serverTick;
|
|
191
|
+
private _lastAppliedServerTick;
|
|
192
|
+
private _worldDriver;
|
|
180
193
|
private _onPhysicsStep;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
/** Set the
|
|
185
|
-
|
|
186
|
-
/** Set the
|
|
187
|
-
setInput(input:
|
|
194
|
+
constructor(transport: CarverTransport, tickKeeper: TickKeeper, snapshots: SnapshotSource, options?: PredictionSyncOptions);
|
|
195
|
+
/** Set the game simulation callback (forward sim + rollback resim). */
|
|
196
|
+
setPhysicsStep(cb: PhysicsStepCallback): void;
|
|
197
|
+
/** Set the world driver used for forward stepping and rollback. */
|
|
198
|
+
setWorldDriver(driver: PredictionWorldDriver): void;
|
|
199
|
+
/** Set the local player's input. PERSISTS across ticks until replaced. */
|
|
200
|
+
setInput(input: PlayerInput): void;
|
|
201
|
+
/** Local input stored at the given tick (neutral fallback). Used by the host to embed `hi`. */
|
|
202
|
+
getLocalInput(tick: number): PlayerInput;
|
|
188
203
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
204
|
+
* Apply the newest pending server snapshot (full-world rollback).
|
|
205
|
+
* Call once per render frame BEFORE tickKeeper.update().
|
|
206
|
+
* No-op on host or when nothing is pending.
|
|
191
207
|
*/
|
|
192
|
-
|
|
208
|
+
beginFrame(): void;
|
|
193
209
|
/**
|
|
194
|
-
*
|
|
195
|
-
*
|
|
210
|
+
* Run one forward fixed tick (host AND client): store + broadcast input,
|
|
211
|
+
* build per-tick input maps, invoke the callback, then step the world.
|
|
196
212
|
*/
|
|
197
|
-
|
|
213
|
+
tick(tick: number): void;
|
|
198
214
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
215
|
+
* Decay stored error offsets and return the portion to ADD to rendered
|
|
216
|
+
* transforms this frame. Call exactly once per render frame.
|
|
201
217
|
*/
|
|
202
|
-
|
|
203
|
-
|
|
218
|
+
getRenderErrorOffsets(): Map<string, ErrorOffset>;
|
|
219
|
+
/** Tick of the newest RECEIVED snapshot. */
|
|
204
220
|
get serverTick(): number;
|
|
221
|
+
/** Tick of the newest APPLIED (rolled-back) snapshot, 0 initially. */
|
|
222
|
+
get lastAppliedServerTick(): number;
|
|
205
223
|
destroy(): void;
|
|
206
|
-
private _setupHostListeners;
|
|
207
|
-
private _setupClientListeners;
|
|
208
|
-
private _reconcile;
|
|
209
|
-
private _computeError;
|
|
210
224
|
}
|
|
211
225
|
|
|
212
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Rollback — full-world rollback for prediction mode.
|
|
228
|
+
*
|
|
229
|
+
* Ported from LumberNet's LumberRollback, adapted to CarverJS entity state
|
|
230
|
+
* (2D and 3D). On each accepted server snapshot the client:
|
|
231
|
+
* 1. captures the pre-rollback visual pose (raw physics + accumulated error),
|
|
232
|
+
* 2. hard-applies server state to EVERY networked entity,
|
|
233
|
+
* 3. resimulates from serverTick + 1 to localTick replaying per-tick inputs
|
|
234
|
+
* (or hard-snaps the tick when drift exceeds maxRewindTicks),
|
|
235
|
+
* 4. converts the visual discontinuity into per-entity error offsets.
|
|
236
|
+
*
|
|
237
|
+
* Pure module: no transport, no React, no three.js. Quaternion math is
|
|
238
|
+
* hand-rolled below.
|
|
239
|
+
*/
|
|
240
|
+
|
|
241
|
+
interface Quat {
|
|
242
|
+
x: number;
|
|
243
|
+
y: number;
|
|
244
|
+
z: number;
|
|
245
|
+
w: number;
|
|
246
|
+
}
|
|
247
|
+
/** Hamilton product (a ⊗ b). */
|
|
248
|
+
declare function quatMultiply(a: Quat, b: Quat): Quat;
|
|
249
|
+
/** Conjugate (inputs assumed normalized). */
|
|
250
|
+
declare function quatInvert(q: Quat): Quat;
|
|
251
|
+
/** Normalize; degenerate (near-zero) quaternions return identity. */
|
|
252
|
+
declare function quatNormalize(q: Quat): Quat;
|
|
253
|
+
/** Rotation angle in radians: 2*acos(clamp(|w|, 0, 1)). */
|
|
254
|
+
declare function quatAngle(q: Quat): number;
|
|
255
|
+
/** Scale the rotation angle toward identity by `factor`, preserving the axis. */
|
|
256
|
+
declare function quatScaleAngle(q: Quat, factor: number): Quat;
|
|
257
|
+
interface RollbackParams {
|
|
258
|
+
/** Tick embedded in the accepted server snapshot. */
|
|
259
|
+
serverTick: number;
|
|
260
|
+
/** Authoritative full-world state from the snapshot. */
|
|
261
|
+
serverState: ReadonlyMap<string, EntityState>;
|
|
262
|
+
/** Client's current simulation tick. */
|
|
263
|
+
localTick: number;
|
|
264
|
+
/** This peer's id (local inputs are replayed from the local ring buffer). */
|
|
265
|
+
localPeerId: string;
|
|
266
|
+
/** Input buffer holding local and per-peer tick history. */
|
|
267
|
+
inputs: InputBuffer;
|
|
268
|
+
/** Currently accumulated visual error offsets (kept continuous across rollbacks). */
|
|
269
|
+
currentErrors: ReadonlyMap<string, ErrorOffset>;
|
|
270
|
+
/** World access for capture/apply/step. */
|
|
271
|
+
driver: PredictionWorldDriver;
|
|
272
|
+
/** Game physics-step callback, re-invoked during resimulation. */
|
|
273
|
+
callback: PhysicsStepCallback | null;
|
|
274
|
+
/** Fixed timestep in seconds. */
|
|
275
|
+
dt: number;
|
|
276
|
+
/** Snap target offset: snap target = serverTick + driftTargetTicks. */
|
|
277
|
+
driftTargetTicks: number;
|
|
278
|
+
/** Max |localTick - (serverTick + driftTargetTicks)| before hard tick snap. */
|
|
279
|
+
maxRewindTicks: number;
|
|
280
|
+
/** Per-axis positional jump above which correction is suppressed (teleport). */
|
|
281
|
+
snapThreshold: number;
|
|
282
|
+
}
|
|
283
|
+
interface RollbackResult {
|
|
284
|
+
/** New local tick (differs from localTick only when a hard snap occurred). */
|
|
285
|
+
newLocalTick: number;
|
|
286
|
+
snapped: boolean;
|
|
287
|
+
/** Per-entity visual error offsets (pre-visual minus post-resim). */
|
|
288
|
+
errors: Map<string, ErrorOffset>;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Apply a server snapshot to the whole world and resimulate forward.
|
|
292
|
+
* Returns the new local tick and per-entity visual error offsets.
|
|
293
|
+
*/
|
|
294
|
+
declare function applyRollback(params: RollbackParams): RollbackResult;
|
|
295
|
+
|
|
296
|
+
export { EntityState, ErrorOffset, EventSync, PhysicsStepCallback, PlayerInput, PredictionSync, PredictionSyncOptions, PredictionWorldDriver, type Quat, type RollbackParams, type RollbackResult, SnapshotListener, SnapshotSource, SnapshotSync, type SnapshotSyncOptions, applyRollback, quatAngle, quatInvert, quatMultiply, quatNormalize, quatScaleAngle };
|