@series-inc/rundot-syncplay 5.25.0-beta.5 → 5.25.0-beta.6

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/README.md CHANGED
@@ -171,6 +171,10 @@ runner without rewriting those layers:
171
171
  - Drive a room badge from the snapshot's `ready`, `appliedThrough`, `predictedThrough`,
172
172
  `localSlot`, and `status` — no reach into the underlying client (e.g. `appliedThrough < 0`
173
173
  means "waiting for peers"; `predictedThrough - appliedThrough` is the catch-up depth).
174
+ - Tune the networked client through the runner: `pacing` (`targetLeadTicks`,
175
+ `maxStepsPerPump`, drift correction) and `inputDelay` (`minTicks`/`maxTicks`,
176
+ RTT-adaptive) are forwarded verbatim, and live `netStats` (RTT, timescale, input
177
+ delay) is surfaced on the snapshot + runner (`null` offline) for a netcode HUD.
174
178
 
175
179
  Direct `NetworkedSyncplayClient` users get the same projection surface:
176
180
  `getPresentationFrame()`, `renderAlpha`, `currentFrame`, `caughtUp`, and a
package/dist/runner.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { DeterministicEventRecord } from './events.js';
2
- import { type KinetixRuntimeFactory, type NetworkedClientTransport, type NetworkedSyncplaySessionDescriptor, type NetworkedSyncplayClientOptions } from './networked-client.js';
2
+ import { type KinetixRuntimeFactory, type NetworkedClientTransport, type NetworkedSyncplaySessionDescriptor, type NetworkedSyncplayClientInputDelayOptions, type NetworkedSyncplayClientNetStats, type NetworkedSyncplayClientOptions, type NetworkedSyncplayClientPacingOptions } from './networked-client.js';
3
3
  import type { KinetixRuntimeIdentity } from './runtime-session.js';
4
4
  export type SyncplayRunnerStatus = 'offline' | 'connecting' | 'syncing' | 'live' | 'stopped' | 'error';
5
5
  export type SyncplayRunnerConnectionEvent = {
@@ -39,6 +39,16 @@ export interface SyncplayRunnerConfig<State, Input, Checkpoint, Projection, Rend
39
39
  * omitted, the runner uses the last `applyInput(...)` value verbatim.
40
40
  */
41
41
  readonly localInputForTick?: (slot: number, frame: number) => Input;
42
+ /**
43
+ * Wall-clock pacing + clock-drift correction for the networked client (G1).
44
+ * Forwarded verbatim; omit for the client defaults.
45
+ */
46
+ readonly pacing?: NetworkedSyncplayClientPacingOptions;
47
+ /**
48
+ * Local input delay for the networked client. `maxTicks > minTicks` auto-tunes
49
+ * from measured RTT. Forwarded verbatim; omit for the client default (0).
50
+ */
51
+ readonly inputDelay?: NetworkedSyncplayClientInputDelayOptions;
42
52
  }
43
53
  export interface SyncplayRunnerOfflineOptions<Input> {
44
54
  readonly identity: KinetixRuntimeIdentity;
@@ -63,6 +73,8 @@ export interface SyncplayRunnerSnapshot<RenderState> {
63
73
  readonly ready: boolean;
64
74
  readonly appliedThrough: number;
65
75
  readonly predictedThrough: number;
76
+ /** Live networked netcode telemetry (RTT, timescale, input delay); null offline. */
77
+ readonly netStats: NetworkedSyncplayClientNetStats | null;
66
78
  readonly error?: Error;
67
79
  }
68
80
  export interface SyncplayRunner<Input, RenderState, EventPayload> {
@@ -73,6 +85,7 @@ export interface SyncplayRunner<Input, RenderState, EventPayload> {
73
85
  readonly ready: boolean;
74
86
  readonly appliedThrough: number;
75
87
  readonly predictedThrough: number;
88
+ readonly netStats: NetworkedSyncplayClientNetStats | null;
76
89
  startOffline(options: SyncplayRunnerOfflineOptions<Input>): void;
77
90
  startNetworked(connect: () => Promise<SyncplayRunnerTransport>): Promise<void>;
78
91
  applyInput(input: Input): void;
package/dist/runner.js CHANGED
@@ -59,6 +59,7 @@ export function createSyncplayRunner(config) {
59
59
  ready: telemetryReady(),
60
60
  appliedThrough: telemetryAppliedThrough(),
61
61
  predictedThrough: telemetryPredictedThrough(),
62
+ netStats: networkClient?.netStats ?? null,
62
63
  ...(status === 'error' && error !== undefined ? { error } : {}),
63
64
  });
64
65
  }
@@ -190,6 +191,8 @@ export function createSyncplayRunner(config) {
190
191
  decodeInput: config.decodeInput,
191
192
  confirmedPresentationBufferSize: 256,
192
193
  ...(config.maxPredictionTicks === undefined ? {} : { maxPredictionTicks: config.maxPredictionTicks }),
194
+ ...(config.pacing === undefined ? {} : { pacing: config.pacing }),
195
+ ...(config.inputDelay === undefined ? {} : { inputDelay: config.inputDelay }),
193
196
  });
194
197
  networkClient = client;
195
198
  await client.whenReady();
@@ -288,6 +291,7 @@ export function createSyncplayRunner(config) {
288
291
  get ready() { return telemetryReady(); },
289
292
  get appliedThrough() { return telemetryAppliedThrough(); },
290
293
  get predictedThrough() { return telemetryPredictedThrough(); },
294
+ get netStats() { return networkClient?.netStats ?? null; },
291
295
  startOffline,
292
296
  startNetworked,
293
297
  applyInput(input) { latestInput = structuredClone(input); },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@series-inc/rundot-syncplay",
3
- "version": "5.25.0-beta.5",
3
+ "version": "5.25.0-beta.6",
4
4
  "description": "Kinetix orchestration, rollback, replay, late-join, and deterministic networking for RUN.game",
5
5
  "repository": {
6
6
  "type": "git",