import { JsonObject, JsonValue } from "type-fest"; import * as autoserialize from "./serialization/autoserialize"; export abstract class NetplayState> { abstract tick(playerInputs: Map): void; /** * By default, use the auto serializer. */ serialize(): JsonValue { return autoserialize.serialize(this); } /** * By default, use the auto deserializer. */ deserialize(value: JsonValue): void { autoserialize.deserialize(value as JsonObject, this); } } export abstract class NetplayInput> { /** * By default, the prediction is to just use the same value. */ predictNext(): TInput { // @ts-ignore return this; } /** * By default, use the auto serializer. */ serialize(): JsonValue { return autoserialize.serialize(this); } /** * By default, use the auto deserializer. */ deserialize(value: JsonValue): void { autoserialize.deserialize(value as JsonObject, this); } } export class NetplayPlayer { id: number; isLocal: boolean; isHost: boolean; constructor(id: number, isLocal: boolean, isHost: boolean) { this.id = id; this.isLocal = isLocal; this.isHost = isHost; } isLocalPlayer(): boolean { return this.isLocal; } isRemotePlayer(): boolean { return !this.isLocal; } isServer(): boolean { return this.isHost; } isClient(): boolean { return !this.isHost; } getID(): number { return this.id; } } export interface GameType { /** * Given a list of players, return the initial game state. */ constructInitialState(players: Array): TState; /** * Construct a new input object with a default value. A new object * needs to be constructed, since serialized values will be copied into this. */ constructDefaultInput(): TInput; /** * The game simulation timestep, in milliseconds. */ timestep: number; // The dimensions of the rendering canvas. canvasWidth: number; canvasHeight: number; draw(state: TState, canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D); getInputReader( document: HTMLDocument, canvas: HTMLCanvasElement ): () => TInput; }