Per user request: split the development process into per-topic docs under docs/dev-log/. Each entry follows the same structure: What was asked → Problems → How solved Files: - README.md index - 01-initial-scope-and-design.md - 02-ui-primitives-api-design.md - 03-monorepo-scaffold.md - 04-ui-primitive-impl.md - 05-drag-and-drop.md - 06-three-games.md - 07-bugfixes-round-1.md - lessons-learned.md all gotchas consolidated - decisions.md locked decisions with dates Total: 1071 lines across 10 files.
2.7 KiB
2.7 KiB
02 · UI 原语 API 设计
做什么
在动手写代码之前,先把 UI 组件的 props、game.ui 字段结构、数据流定义清楚,写成 docs/ui-primitives.md 供实现参考。
遇到什么问题
- 接口界定:组件要通用(支持任意 boardgame.io 游戏),又不能过于抽象失去表现力。
- game.ui 字段怎么设计:是松散的"约定"还是强类型的 schema?
- 拖拽 API:TTS 用 Lua 控制每个对象的交互。JS 端怎么抽象?
- 玩家视角:boardgame.io master 会按 playerID 过滤状态,UI 怎么配合?
怎么解决
5 个设计原则
- 声明式:业务代码只描述"是什么",不描述"怎么画"
- 数据驱动:所有可见状态都来自
G(boardgame.io 的 state) - 服务器权威:所有 game-affecting 操作都通过
onMove触发 reducer - 玩家视角:UI 接收的
G已经是 boardgame.io 过滤后的版本 - 可扩展:通过
game.ui.overrides注入自定义组件
8 个组件
<Board> <Zone> <Hand> <Deck> <Card> <Token> <ActionButton> <Dice>
6 个 zone type
hand / pile / discard / grid / area / free
关键 schema
interface UISchema {
background?: string;
zones: ZoneDef[];
cards?: CardTemplate;
tokens?: TokenDef[];
actions?: ActionDef[];
overrides?: UIOverrides;
}
interface ZoneDef {
id: string;
type: 'hand' | 'pile' | 'discard' | 'grid' | 'area' | 'free';
position: { x: number; y: number };
size?: { w: number; h: number };
layout?: { fan?: number; spacing?: number; maxWidth?: number };
faceDown?: boolean;
owner?: string | null; // 'self' | 'P0' | null(公开)
collection?: string; // G 中持有 ID 数组的字段名
entityField?: string; // G 中持有 ID → 实体映射的字段名
dropMove?: string; // 接收 drop 时调用的 move
dropArgs?: (cardIds, fromZoneId, toZoneId) => any[];
accepts?: string | ((card, ctx) => boolean); // 接收规则
}
6 个待决项(已锁定 ✅)
| 待决项 | 决定 |
|---|---|
| zone 坐标系统 | 固定像素 + Board 视口缩放 |
| 动画策略 | CSS transition 默认 + 游戏可覆盖 |
| 可访问性 | v1 仅鼠标 |
| 触屏/移动端 | v1 仅桌面 |
| 多选 UI | v1 仅 Shift+click |
| 牌堆数量显示 | 角标显示数量 |
资产格式:SVG 内嵌字符串优先(fallback DataURL/URL)。
成果
docs/ui-primitives.md(15 KB,511 行)- 6 个待决项的设计默认值锁定,避免实现时反复讨论
关联
- 04-ui-primitive-impl.md — 按这份设计实现
- 03-monorepo-scaffold.md — 同步开始搭骨架