39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
import { PredictedEngine } from "./client.js";
|
|
import { AuthoritativeEngine, type ServerEngineOptions } from "./server.js";
|
|
import type { GameDefinition } from "./types.js";
|
|
|
|
export interface DefinedGame<State, Input>
|
|
extends GameDefinition<State, Input> {
|
|
createServer(options?: ServerEngineOptions): AuthoritativeEngine<State, Input>;
|
|
createClient(): PredictedEngine<State, Input>;
|
|
}
|
|
|
|
export function defineGame<State, Input>(
|
|
definition: GameDefinition<State, Input>,
|
|
): DefinedGame<State, Input> {
|
|
if (!Number.isInteger(definition.tickRateHz) || definition.tickRateHz <= 0) {
|
|
throw new RangeError("tickRateHz must be a positive integer");
|
|
}
|
|
|
|
if (
|
|
!Number.isInteger(definition.snapshotRateHz) ||
|
|
definition.snapshotRateHz <= 0 ||
|
|
definition.snapshotRateHz > definition.tickRateHz ||
|
|
definition.tickRateHz % definition.snapshotRateHz !== 0
|
|
) {
|
|
throw new RangeError(
|
|
"snapshotRateHz must be a positive divisor of tickRateHz",
|
|
);
|
|
}
|
|
|
|
return Object.freeze({
|
|
...definition,
|
|
createServer(options?: ServerEngineOptions) {
|
|
return new AuthoritativeEngine(definition, options);
|
|
},
|
|
createClient() {
|
|
return new PredictedEngine(definition);
|
|
},
|
|
});
|
|
}
|