From e5c68b0c3761de9d10b8a54e0ee7fd65bdce671b Mon Sep 17 00:00:00 2001 From: Tangent Wantwight Date: Mon, 18 May 2020 19:32:56 -0400 Subject: [PATCH] Fix prediction from null state to permit local prediction before server starts sending input. --- src/ecs/Lockstep.ts | 4 ++-- src/game/GameComponents.ts | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/ecs/Lockstep.ts b/src/ecs/Lockstep.ts index e1e78dd..ae0f950 100644 --- a/src/ecs/Lockstep.ts +++ b/src/ecs/Lockstep.ts @@ -3,7 +3,7 @@ export const INPUT_FREQUENCY = 33; // roughly 30fps export interface LockstepProcessor { compareInput(a: GlobalInput, b: GlobalInput): boolean; - predictInput(prev: GlobalInput | null, localPlayer: number, localInput: LocalInput): GlobalInput; + predictInput(prev: GlobalInput | undefined, localPlayer: number, localInput: LocalInput): GlobalInput; cloneState(source: State): State; advanceState(state: State, input: GlobalInput): void; } @@ -45,7 +45,7 @@ export class LockstepState { // ensure that we don't overwrite the canon input with local input somehow // (probably only possible in situations where game is unplayable anyways? but still for sanity.) if(this.inputIndex > this.canonIndex) { - this.inputLog[this.inputIndex] = this.engine.predictInput(this.inputLog[this.inputIndex - 1] ?? null, player, input); + this.inputLog[this.inputIndex] = this.engine.predictInput(this.inputLog[this.inputIndex - 1] ?? undefined, player, input); } } diff --git a/src/game/GameComponents.ts b/src/game/GameComponents.ts index d82d2f7..64a1091 100644 --- a/src/game/GameComponents.ts +++ b/src/game/GameComponents.ts @@ -181,8 +181,15 @@ export class Engine implements LockstepProcessor { return new Data(old); } - predictInput(prev: KeyName[][] | null, localPlayer: number, localInput: KeyName[]): KeyName[][] { - return prev?.map((prevInput, player) => (player == localPlayer) ? localInput : prevInput) ?? []; + predictInput(prev: KeyName[][] = [], localPlayer: number, localInput: KeyName[]): KeyName[][] { + const prediction = prev.slice(); + for(let i = 0; i <= localPlayer; i++) { + if(!prediction[i]) { + prediction[i] = []; + } + } + prediction[localPlayer] = localInput; + return prediction; } compareInput(a: KeyName[][], b: KeyName[][]): boolean {