boardgame-core/src/core/game.ts

50 lines
1.6 KiB
TypeScript
Raw Normal View History

2026-04-02 10:26:42 +08:00
import {createEntityCollection} from "../utils/entity";
import {Part} from "./part";
import {Region} from "./region";
2026-04-02 10:48:20 +08:00
import {
Command,
CommandRegistry,
type CommandRunner, CommandRunnerContext,
CommandRunnerContextExport, CommandSchema,
createCommandRunnerContext, parseCommandSchema,
PromptEvent
} from "../utils/command";
2026-04-02 10:26:42 +08:00
import {AsyncQueue} from "../utils/async-queue";
export interface IGameContext {
parts: ReturnType<typeof createEntityCollection<Part>>;
regions: ReturnType<typeof createEntityCollection<Region>>;
commands: CommandRunnerContextExport<IGameContext>;
2026-04-02 10:48:20 +08:00
prompts: AsyncQueue<PromptEvent>;
2026-04-02 10:26:42 +08:00
}
2026-04-02 10:48:20 +08:00
/**
* creates a game context.
* expects a command registry already registered with commands.
* @param commandRegistry
*/
2026-04-02 10:26:42 +08:00
export function createGameContext(commandRegistry: CommandRegistry<IGameContext>) {
const parts = createEntityCollection<Part>();
const regions = createEntityCollection<Region>();
const ctx: IGameContext = {
parts,
regions,
2026-04-02 10:48:20 +08:00
commands: null!,
prompts: new AsyncQueue(),
2026-04-02 10:26:42 +08:00
};
ctx.commands = createCommandRunnerContext(commandRegistry, ctx);
2026-04-02 10:48:20 +08:00
ctx.commands.on('prompt', (prompt: PromptEvent) => ctx.prompts.push(prompt));
2026-04-02 10:26:42 +08:00
return ctx;
2026-04-02 10:48:20 +08:00
}
export function createGameCommand<TResult>(
schema: CommandSchema | string,
run: (this: CommandRunnerContext<IGameContext>, command: Command) => Promise<TResult>
): CommandRunner<IGameContext, TResult> {
return {
schema: typeof schema === 'string' ? parseCommandSchema(schema) : schema,
run,
};
}