import { h, render } from 'preact'; import { signal } from '@preact/signals-core'; import Phaser from 'phaser'; import { createGameContext } from 'boardgame-core'; import { GameUI, PromptDialog, CommandLog } from 'boardgame-phaser'; import { createInitialState, registry, type TicTacToeState } from './game/tic-tac-toe'; import { GameScene, type GameSceneData } from './scenes/GameScene'; import './style.css'; const gameContext = createGameContext(registry, createInitialState); const promptSignal = signal>>(null); const commandLog = signal>([]); gameContext.commands.on('prompt', (event) => { promptSignal.value = event; }); const originalRun = gameContext.commands.run.bind(gameContext.commands); (gameContext.commands as any).run = async (input: string) => { const result = await originalRun(input); commandLog.value = [ ...commandLog.value, { input, result: result.success ? `OK: ${JSON.stringify(result.result)}` : `ERR: ${result.error}`, timestamp: Date.now(), }, ]; return result; }; const sceneData: GameSceneData = { state: gameContext.state, commands: gameContext.commands, }; const phaserConfig: Phaser.Types.Core.GameConfig = { type: Phaser.AUTO, width: 560, height: 560, parent: 'phaser-container', backgroundColor: '#f9fafb', scene: [], }; const game = new Phaser.Game(phaserConfig); game.scene.add('GameScene', GameScene, true, sceneData); const ui = new GameUI({ container: document.getElementById('ui-root')!, root: h('div', { className: 'flex flex-col h-screen' }, h('div', { className: 'flex-1 relative' }, h('div', { id: 'phaser-container', className: 'w-full h-full' }), h(PromptDialog, { prompt: promptSignal.value, onSubmit: (input: string) => { gameContext.commands._tryCommit(input); promptSignal.value = null; }, onCancel: () => { gameContext.commands._cancel('cancelled'); promptSignal.value = null; }, }), ), h('div', { className: 'p-4 bg-gray-100 border-t' }, h(CommandLog, { entries: commandLog }), ), ), }); ui.mount(); gameContext.commands.run('setup');