docs: update docs

This commit is contained in:
hypercross 2026-04-07 16:29:08 +08:00
parent deb8c91239
commit 27e6d52cf3
2 changed files with 111 additions and 108 deletions

112
QWEN.md
View File

@ -17,113 +17,6 @@
`boardgame-core`的内容可以在`framework/node_modules/boardgame-core`找到。 `boardgame-core`的内容可以在`framework/node_modules/boardgame-core`找到。
这个文件夹被.gitignore忽略查看时需要绕开这一限制。 这个文件夹被.gitignore忽略查看时需要绕开这一限制。
## 编写GameModule
游戏逻辑以GameModule的形式定义
```typescript
import {createGameCommandRegistry, IGameContext} from "boardgame-core";
// 创建mutative游戏初始状态
export function createInitialState(): GameState {
//...
}
// 运行游戏
export async function start(game: IGameContext<GameState>) {
// ...
}
// 可选
export const registry = createGameCommandRegistry();
```
使用以下步骤创建GameModule
### 1. 定义状态
通常使用一个`regions: Record<string, Region>`和一个`parts: Record<string, Part<TMeta>>`来记录桌游物件的摆放。
```typescript
import {Region} from "boardgame-core";
type GameState = {
regions: {
white: Region,
black: Region,
board: Region,
},
pieces: Record<string, Part<PartsTable['0']>>,
currentPlayer: PlayerType,
winner: WinnerType,
};
```
游戏的部件可以从`csv`加载。详情见`boop-game/node_modules/inline-schema/`。
```
/// parts.csv
type, player, count
string, string, number
cat, white, 8
cat, black, 8
/// parts.csv.d.ts
type PartsTable = {
type: string;
player: string;
count: number;
}[];
declare const data: PartsTable;
export default data;
```
### 2. 定义流程
使用`async function start(game: IGameContext<GameState>)`作为入口。
使用`game.value`读取游戏当前状态
```typescript
async function gameEnd(game: IGameContext<GameState>) {
return game.value.winner;
}
```
需要修改状态时,使用`game.produce`或`game.produceAsync`。
```typescript
async function start(game: IGameContext<GameState>) {
await game.produceAsync(state => {
state.currentPlayer = 'white';
});
}
```
需要等待玩家交互时,使用`await game.prompt(promptDef, validator, player)`。
```typescript
import {createPromptDef} from "boardgame-core";
export const prompts = {
play: createPromptDef<[PlayerType, number, number]>('play <player> <row:number> <col:number>'),
}
async function turn(game: IGameContext<GameState>, currentPlayer: PlayerType) {
const {player, row, col} = await game.prompt(
prompts.play,
(player, row, col) => {
if (player !== currentPlayer)
throw `Wrong player!`
return {player, row, col};
}
)
}
```
### 3. 编写测试
使用`vitest`编写测试,测试应当使用`GameHost`来模拟游戏环境。
## 编写Phaser App ## 编写Phaser App
使用`framework/src/ui/PhaserBridge`来创建Phaser App。 使用`framework/src/ui/PhaserBridge`来创建Phaser App。
@ -136,6 +29,9 @@ async function turn(game: IGameContext<GameState>, currentPlayer: PlayerType) {
export class GameHost<TState extends Record<string, unknown>, TResult=unknown> { export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
// 获取游戏状态的只读快照 // 获取游戏状态的只读快照
get state(): TState{} get state(): TState{}
// 获取随机数
get rng(): ReadonlyRNG{}
// 运行状态 // 运行状态
readonly status: ReadonlySignal<GameHostStatus>; readonly status: ReadonlySignal<GameHostStatus>;
@ -151,7 +47,7 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
addInterruption(promise: Promise<void>): void {} addInterruption(promise: Promise<void>): void {}
// 开始或者重新开始游戏 // 开始或者重新开始游戏
start(): Promise<TResult>{} start(seed?: number): Promise<TResult>{}
// 销毁 // 销毁
dispose(): void {} dispose(): void {}

107
docs/GameModule.md Normal file
View File

@ -0,0 +1,107 @@
## 编写GameModule
游戏逻辑以GameModule的形式定义
```typescript
import {createGameCommandRegistry, IGameContext} from "boardgame-core";
// 创建mutative游戏初始状态
export function createInitialState(): GameState {
//...
}
// 运行游戏
export async function start(game: IGameContext<GameState>) {
// ...
}
// 可选
export const registry = createGameCommandRegistry();
```
使用以下步骤创建GameModule
### 1. 定义状态
通常使用一个`regions: Record<string, Region>`和一个`parts: Record<string, Part<TMeta>>`来记录桌游物件的摆放。
```typescript
import {Region} from "boardgame-core";
type GameState = {
regions: {
white: Region,
black: Region,
board: Region,
},
pieces: Record<string, Part<PartsTable['0']>>,
currentPlayer: PlayerType,
winner: WinnerType,
};
```
游戏的部件可以从`csv`加载。详情见`boop-game/node_modules/inline-schema/`。
```
/// parts.csv
type, player, count
string, string, number
cat, white, 8
cat, black, 8
/// parts.csv.d.ts
type PartsTable = {
type: string;
player: string;
count: number;
}[];
declare const data: PartsTable;
export default data;
```
### 2. 定义流程
使用`async function start(game: IGameContext<GameState>)`作为入口。
使用`game.value`读取游戏当前状态
```typescript
async function gameEnd(game: IGameContext<GameState>) {
return game.value.winner;
}
```
需要修改状态时,使用`game.produce`或`game.produceAsync`。
```typescript
async function start(game: IGameContext<GameState>) {
await game.produceAsync(state => {
state.currentPlayer = 'white';
});
}
```
需要等待玩家交互时,使用`await game.prompt(promptDef, validator, player)`。
```typescript
import {createPromptDef} from "boardgame-core";
export const prompts = {
play: createPromptDef<[PlayerType, number, number]>('play <player> <row:number> <col:number>'),
}
async function turn(game: IGameContext<GameState>, currentPlayer: PlayerType) {
const {player, row, col} = await game.prompt(
prompts.play,
(player, row, col) => {
if (player !== currentPlayer)
throw `Wrong player!`
return {player, row, col};
}
)
}
```
### 3. 编写测试
使用`vitest`编写测试,测试应当使用`GameHost`来模拟游戏环境。