Fix prediction from null state to permit local prediction before server starts sending input.

This commit is contained in:
Tangent Wantwight 2020-05-18 19:32:56 -04:00
parent e9c73ae998
commit e5c68b0c37
2 changed files with 11 additions and 4 deletions

View file

@ -3,7 +3,7 @@ export const INPUT_FREQUENCY = 33; // roughly 30fps
export interface LockstepProcessor<LocalInput, GlobalInput, State> { export interface LockstepProcessor<LocalInput, GlobalInput, State> {
compareInput(a: GlobalInput, b: GlobalInput): boolean; 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; cloneState(source: State): State;
advanceState(state: State, input: GlobalInput): void; advanceState(state: State, input: GlobalInput): void;
} }
@ -45,7 +45,7 @@ export class LockstepState<LocalInput, GlobalInput, State> {
// ensure that we don't overwrite the canon input with local input somehow // 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.) // (probably only possible in situations where game is unplayable anyways? but still for sanity.)
if(this.inputIndex > this.canonIndex) { 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);
} }
} }

View file

@ -181,8 +181,15 @@ export class Engine implements LockstepProcessor<KeyName[], KeyName[][], Data> {
return new Data(old); return new Data(old);
} }
predictInput(prev: KeyName[][] | null, localPlayer: number, localInput: KeyName[]): KeyName[][] { predictInput(prev: KeyName[][] = [], localPlayer: number, localInput: KeyName[]): KeyName[][] {
return prev?.map((prevInput, player) => (player == localPlayer) ? localInput : prevInput) ?? []; 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 { compareInput(a: KeyName[][], b: KeyName[][]): boolean {