From b929a126a1b3b959de3c60edf620271ae2f6a093 Mon Sep 17 00:00:00 2001 From: hypercross Date: Sat, 4 Apr 2026 22:54:58 +0800 Subject: [PATCH] fix: api doc --- docs/api-reference.md | 160 ++++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 69 deletions(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 8a9e668..db48d1e 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -4,117 +4,139 @@ | 导出 | 说明 | |---|---| -| `IGameContext` | 游戏上下文基础接口 | -| `createGameContext(registry, initialState?)` | 创建游戏上下文实例 | -| `createGameContextFromModule(module)` | 从 GameModule 创建游戏上下文 | -| `createGameCommandRegistry()` | 创建命令注册表 | -| `createGameModule(module)` | 辅助函数,标记 GameModule | | `GameHost` | 游戏生命周期管理类 | -| `createGameHost(module, options?)` | 从 GameModule 创建 GameHost | +| `createGameHost(module)` | 从 GameModule 创建 GameHost | | `GameHostStatus` | 类型: `'created' \| 'running' \| 'disposed'` | -| `GameModule` | 游戏模块类型 | +| `GameModule` | 游戏模块类型,包含 `registry` 和 `createInitialState` | +| `createGameModule(module)` | 辅助函数,标记 GameModule | +| `createGameCommandRegistry()` | 创建游戏命令注册表 | -## 棋子 (Parts) +### GameHost + +| 成员 | 说明 | +|---|---| +| `context: IGameContext` | 游戏上下文,含状态和命令运行能力 | +| `status: Signal` | 当前状态 | +| `activePromptSchema: Signal` | 当前等待的 prompt schema | +| `activePromptPlayer: Signal` | 当前等待的玩家 | +| `setup(setupCommand: string)` | 启动游戏,运行 setup 命令 | +| `onInput(input: string)` | 提交玩家输入到当前 prompt | +| `addInterruption(promise)` / `clearInterruptions()` | 动画中断控制 | +| `on(event, listener)` | 监听 `setup` / `dispose` 事件 | +| `dispose()` | 销毁游戏实例 | + +### IGameContext + +| 成员 | 说明 | +|---|---| +| `value: TState` | 当前游戏状态 | +| `produce(fn)` | 同步更新状态 | +| `produceAsync(fn)` | 等待动画中断后更新状态 | +| `run(input)` / `runParsed(command)` | 运行命令 | +| `prompt(schema, validator, currentPlayer?)` | 等待玩家输入 | +| `addInterruption(promise)` | 注册动画中断 | + +## 棋子与区域 + +### Part | 导出 | 说明 | |---|---| -| `Part` | 游戏棋子类型 | -| `PartTemplate` | 创建棋子的模板类型 | -| `PartPool` | 棋子池类型 | +| `Part` | 棋子类型,含 `id`、`regionId`、`position`、`side` 等 | +| `PartTemplate` / `PartPool` | 棋子模板和棋子池类型 | | `createPart(template, id)` | 创建单个棋子 | -| `createParts(template, count, idPrefix)` | 批量创建相同棋子 | +| `createParts(template, count, idPrefix)` | 批量创建棋子 | +| `createPartPool(template, count, idPrefix)` | 创建棋子池,支持 `draw()` / `return()` / `remaining()` | +| `mergePartPools(...pools)` | 合并棋子池 | | `createPartsFromTable(items, getId, getCount?)` | 从表格数据创建棋子 | -| `createPartPool(template, count, idPrefix)` | 创建棋子池 | -| `mergePartPools(...pools)` | 合并多个棋子池 | -| `findPartById(parts, id)` | 按 ID 查找棋子 | -| `isCellOccupied(parts, regionId, position)` | 检查格子是否被占用 | -| `getPartAtPosition(parts, regionId, position)` | 获取格子上的棋子 | -| `isCellOccupiedByRegion(region, position)` | O(1) 检查格子占用 | -| `getPartAtPositionInRegion(region, parts, position)` | O(1) 获取棋子 | -| `flip(part)` / `flipTo(part, side)` / `roll(part, rng)` | 翻面/随机面 | +| `findPartById(parts, id)` | 按 ID 查找 | +| `getPartAtPosition(parts, regionId, position)` | 获取位置上的棋子 | +| `isCellOccupied(parts, regionId, position)` | 检查格子占用 | +| `flip(part)` / `flipTo(part, side)` / `roll(part, rng)` | 翻面/掷骰 | -## 区域 (Regions) +### Region | 导出 | 说明 | |---|---| | `Region` / `RegionAxis` | 区域类型 | | `createRegion(id, axes)` | 创建区域 | -| `applyAlign(region, parts)` | 紧凑排列 | -| `shuffle(region, parts, rng)` | 打乱位置 | -| `moveToRegion(part, sourceRegion?, targetRegion, position?)` | 移动棋子到区域 | +| `applyAlign(region, parts)` | 按 axis 配置紧凑排列棋子 | +| `shuffle(region, parts, rng)` | 打乱区域内棋子位置 | +| `moveToRegion(part, source?, target, position?)` | 移动棋子到区域 | +| `isCellOccupiedByRegion(region, position)` | O(1) 检查格子占用(使用 region.partMap) | +| `getPartAtPositionInRegion(region, parts, position)` | O(1) 获取棋子(使用 region.partMap) | -## 命令 (Commands) +## 命令系统 + +### 基础类型 | 导出 | 说明 | |---|---| -| `Command` / `CommandSchema` / `CommandResult` | 命令相关类型 | -| `CommandParamSchema` / `CommandOptionSchema` / `CommandFlagSchema` | 命令参数类型 | -| `parseCommand(input)` | 解析命令字符串 | -| `parseCommandSchema(schema)` | 解析 Schema 字符串 | -| `validateCommand(cmd, schema)` | 验证命令 | -| `parseCommandWithSchema(input, schema)` | 解析并应用 Schema | -| `applyCommandSchema(cmd, schema)` | 应用 Schema 到命令 | +| `Command` | 解析后的命令对象,含 `name`、`params`、`options`、`flags` | +| `CommandSchema` | 命令 schema 定义 | +| `CommandResult` | 命令执行结果: `{ success: true, result: T } | { success: false, error: string }` | -### 命令运行器 +### 注册与运行 | 导出 | 说明 | |---|---| -| `CommandRunner` | 命令运行器类型 | -| `CommandRunnerHandler` | 命令处理器类型 | -| `CommandRunnerContext` | 命令运行器上下文类型 | -| `CommandRunnerContextExport` | 导出的命令运行器上下文(含内部方法) | -| `CommandRegistry` | 命令注册表类型 | -| `PromptEvent` / `CommandRunnerEvents` | 提示事件类型 | -| `PromptValidator` | 提示验证器类型 | +| `CommandRegistry` | 命令注册表,继承自 `Map`,含 `register(schema, handler)` 快捷方法 | +| `CommandRunner` | 命令运行器,含 `schema` 和 `run` | +| `CommandRunnerContext` | 命令运行器上下文,提供 `run`、`prompt`、`on`、`off` | +| `PromptEvent` | prompt 事件,含 `schema`、`currentPlayer`、`tryCommit`、`cancel` | +| `PromptValidator` | prompt 验证器: `(command) => T`,throw 字符串表示验证失败 | | `createCommandRegistry()` | 创建命令注册表 | -| `registerCommand(registry, runner)` | 注册命令运行器 | -| `unregisterCommand(registry, name)` | 注销命令 | -| `hasCommand(registry, name)` | 检查命令是否存在 | -| `getCommand(registry, name)` | 获取命令 | -| `runCommand(registry, context, input)` | 运行命令 | -| `runCommandParsed(registry, context, command)` | 运行已解析命令 | -| `createCommandRunnerContext(registry, context)` | 创建命令运行器上下文 | +| `registerCommand(registry, runner)` | 注册命令 | +| `unregisterCommand(registry, name)` / `hasCommand(registry, name)` / `getCommand(registry, name)` | 命令管理 | +| `runCommand(registry, context, input)` | 解析并运行命令 | + +### 命令解析 + +| 导出 | 说明 | +|---|---| +| `parseCommand(input)` | 解析命令字符串为 `Command` 对象 | +| `parseCommandSchema(schemaStr)` | 解析 schema 字符串为 `CommandSchema` | +| `validateCommand(command, schema)` | 验证命令是否符合 schema | +| `parseCommandWithSchema(input, schemaStr)` | 解析并验证命令 | +| `applyCommandSchema(command, schema)` | 应用 schema 到命令,含类型转换 | ### Game Command Registry -游戏专用命令注册表(通过 `createGameCommandRegistry` 创建,类型为 `CommandRegistry>`): +通过 `createGameCommandRegistry()` 创建的注册表有快捷 `register` 方法: -| 方法 | 说明 | -|---|---| -| `registry.register(schema, handler)` | 注册命令并返回可调用命令对象 | +```ts +const moveCmd = registry.register('move ', async (ctx, from, to) => { + ctx.produce(state => { /* ... */ }); +}); -`registry.register` 接受命令 Schema(字符串或 `CommandSchema` 对象)和处理器函数,返回一个可调用函数。处理器函数签名为 `(ctx, ...args) => Promise`。 +// 作为子命令调用 +await moveCmd(ctx, 'A1', 'A2'); +``` -在 GameModule 中使用 `game.prompt()` 等待玩家输入,验证函数中 `throw` 字符串会触发重新提示,返回非 null 值表示验证通过。子命令可以通过 `await subCommand(game, ...args)` 方式调用。 +处理器签名: `(ctx, ...args) => Promise`。 +`game.prompt()` 等待玩家输入,验证器 throw 字符串触发重新提示,返回非 null 值表示通过。 ## MutableSignal | 导出 | 说明 | |---|---| -| `MutableSignal` | 支持突变和动画中断的响应式信号 | +| `MutableSignal` | 支持突变和动画中断的响应式信号,继承 Preact Signal | | `mutableSignal(initial?, options?)` | 创建 MutableSignal | -| `EntityCollection` / `createEntityCollection()` | 实体集合辅助函数 | - -### MutableSignal 成员 +| `EntityCollection` / `createEntityCollection()` | 实体集合辅助函数,管理 `MutableSignal` 字典 | | 成员 | 说明 | |---|---| -| `value: T` | 获取当前值 | -| `produce(fn: (draft: T) => void): void` | 同步不可变更新 | -| `addInterruption(promise: Promise): void` | 添加中断 | -| `clearInterruptions(): void` | 清除所有中断 | -| `produceAsync(fn: (draft: T) => void): Promise` | 等待中断完成后更新 | +| `value: T` | 获取/设置当前值 | +| `produce(fn)` | 同步不可变更新(使用 mutative) | +| `produceAsync(fn)` | 等待所有 interruption 完成后更新状态 | +| `addInterruption(promise)` | 注册中断,下一个 produceAsync 会等待 | +| `clearInterruptions()` | 清除所有未完成的中断 | -### GameHost 中断代理 - -`GameHost` 直接代理 `addInterruption` 和 `clearInterruptions`,供 UI 层使用。 -`IGameContext` 提供 `produce()`、`produceAsync()` 和 `addInterruption()` 方法。 详见 [动画与状态更新同步](./animation-sync.md)。 ## 工具 | 导出 | 说明 | |---|---| -| `RNG` | 随机数生成器接口 | -| `createRNG(seed?)` | 创建种子 RNG | -| `Mulberry32RNG` | Mulberry32 算法实现 | +| `RNG` | 随机数生成器接口: `setSeed`、`getSeed`、`next`、`nextInt` | +| `createRNG(seed?)` / `Mulberry32RNG` | Mulberry32 算法 PRNG |