tolerate internet latency for initial inputs
All checks were successful
build / image (push) Successful in 1m49s
All checks were successful
build / image (push) Successful in 1m49s
This commit is contained in:
@@ -91,7 +91,7 @@ export class NetworkedAuthoritativeEngine<
|
|||||||
) {
|
) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
this.historyTicks = options.historyTicks ?? game.tickRateHz * 2;
|
this.historyTicks = options.historyTicks ?? game.tickRateHz * 2;
|
||||||
this.maxPastTicks = options.maxPastTicks ?? 2;
|
this.maxPastTicks = options.maxPastTicks ?? game.tickRateHz;
|
||||||
this.maxFutureTicks = options.maxFutureTicks ?? game.tickRateHz;
|
this.maxFutureTicks = options.maxFutureTicks ?? game.tickRateHz;
|
||||||
this.snapshotEveryTicks = game.tickRateHz / game.snapshotRateHz;
|
this.snapshotEveryTicks = game.tickRateHz / game.snapshotRateHz;
|
||||||
this.state = game.server.createInitialState();
|
this.state = game.server.createInitialState();
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ import type {
|
|||||||
|
|
||||||
export interface ServerEngineOptions {
|
export interface ServerEngineOptions {
|
||||||
historyTicks?: number;
|
historyTicks?: number;
|
||||||
|
/**
|
||||||
|
* Maximum transport delay accepted for an input. Late inputs are applied on
|
||||||
|
* the next simulation step; they never rewrite authoritative history.
|
||||||
|
*/
|
||||||
maxPastTicks?: number;
|
maxPastTicks?: number;
|
||||||
maxFutureTicks?: number;
|
maxFutureTicks?: number;
|
||||||
}
|
}
|
||||||
@@ -63,7 +67,7 @@ export class AuthoritativeEngine<State, Input> {
|
|||||||
) {
|
) {
|
||||||
this.game = game;
|
this.game = game;
|
||||||
this.historyTicks = options.historyTicks ?? game.tickRateHz * 2;
|
this.historyTicks = options.historyTicks ?? game.tickRateHz * 2;
|
||||||
this.maxPastTicks = options.maxPastTicks ?? 2;
|
this.maxPastTicks = options.maxPastTicks ?? game.tickRateHz;
|
||||||
this.maxFutureTicks = options.maxFutureTicks ?? game.tickRateHz;
|
this.maxFutureTicks = options.maxFutureTicks ?? game.tickRateHz;
|
||||||
this.snapshotEveryTicks = game.tickRateHz / game.snapshotRateHz;
|
this.snapshotEveryTicks = game.tickRateHz / game.snapshotRateHz;
|
||||||
this.state = game.createInitialState();
|
this.state = game.createInitialState();
|
||||||
|
|||||||
@@ -151,6 +151,34 @@ test("the developer-facing API compiles named sections into a networked game", (
|
|||||||
);
|
);
|
||||||
server.step();
|
server.step();
|
||||||
assert.equal(server.currentState.value, 3);
|
assert.equal(server.currentState.value, 3);
|
||||||
|
|
||||||
|
// Internet clients can be several ticks behind the server when their first
|
||||||
|
// input arrives. Accept it within the default one-second transport window
|
||||||
|
// and apply it on the next authoritative step.
|
||||||
|
for (let index = 0; index < 6; index++) server.step();
|
||||||
|
assert.deepEqual(
|
||||||
|
server.submitInput(1, {
|
||||||
|
sequence: 2,
|
||||||
|
targetTick: 2,
|
||||||
|
observedTick: 2,
|
||||||
|
input: { amount: 2 },
|
||||||
|
}),
|
||||||
|
{ accepted: true },
|
||||||
|
);
|
||||||
|
server.step();
|
||||||
|
assert.equal(server.currentState.value, 5);
|
||||||
|
|
||||||
|
for (let index = 0; index < 7; index++) server.step();
|
||||||
|
assert.deepEqual(
|
||||||
|
server.submitInput(1, {
|
||||||
|
sequence: 3,
|
||||||
|
targetTick: 2,
|
||||||
|
observedTick: 2,
|
||||||
|
input: { amount: 2 },
|
||||||
|
}),
|
||||||
|
{ accepted: false, reason: "past" },
|
||||||
|
);
|
||||||
|
|
||||||
assert.deepEqual(codec.decode(codec.encode({ unicode: "flux ⚡" })), {
|
assert.deepEqual(codec.decode(codec.encode({ unicode: "flux ⚡" })), {
|
||||||
unicode: "flux ⚡",
|
unicode: "flux ⚡",
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user