- 新增双升(DoubleUp)完整实现:引擎 double-up-core.ts / double-up.ts、牌桌 UI DoubleUpBoard.tsx、单测与 E2E - 甩牌跟牌修复:validateFollow 新增 mixed 分支,甩牌后其他家可正常跟单张同花色牌 - start.sh:PORT=5173 单端口一键启动(Koa 同时 serve 页面+/api+/socket.io),浏览器直连无需 Vite 代理 - 玩家名 server 权威化(join 时写入 G.playerNames);LobbyRoomList 支持 fixedSeats(双升固定 4 人) - 文档:新增 dev-log/14、更新 dev-log README 索引与进度、更新根 README 启动/部署说明 - .gitignore 忽略根目录 data/*.db 运行时 SQLite
138 lines
5.0 KiB
Markdown
138 lines
5.0 KiB
Markdown
# tts-like
|
||
|
||
TTS-like tabletop simulator. Rule-engine: [boardgame.io](https://boardgame.io). Desktop shell: [Tauri](https://tauri.app).
|
||
|
||
## Status
|
||
|
||
🚧 Early scaffold. 已落地 5 个游戏:DragTest / War / Mill(九子棋)/ Holdem(德州扑克,2-9 人)/ DoubleUp(双升,固定 4 人)。详见 `docs/`。
|
||
|
||
## Workspace
|
||
|
||
```
|
||
packages/
|
||
engine/ # boardgame.io re-exports + game-authoring helpers + 各游戏定义
|
||
ui/ # React UI primitives (<Board>, <Card>, <Zone>, <LobbyRoomList>, ...)
|
||
protocol/ # Shared TS types (UI schema, state shapes)
|
||
server/ # Relay server (wraps boardgame.io master, /api 前缀 + 静态 serve)
|
||
apps/
|
||
web/ # Vite + React SPA (含各游戏 Board 组件 + e2e)
|
||
desktop/ # Tauri wrapper around apps/web build(待启动)
|
||
docs/
|
||
impl.md # High-level implementation plan
|
||
ui-primitives.md # UI API design
|
||
dev-log/ # 按主题切的开发过程记录(做什么 → 问题 → 怎么解决)
|
||
```
|
||
|
||
## 环境要求
|
||
|
||
- **Node.js** ≥ 22.12(推荐通过 [nvm](https://github.com/nvm-sh/nvm) 装 22.x)
|
||
- **pnpm** ≥ 10.16(通过 corepack 启用,见下)
|
||
- 端口:dev 默认 5173(web)+ 8000(server),生产可合并为单端口
|
||
|
||
## 启动整个系统
|
||
|
||
### 1. 准备环境(每台机器只需一次)
|
||
|
||
```sh
|
||
# 用 nvm 装 Node 22(已装可跳过)
|
||
nvm install 22 && nvm use 22
|
||
|
||
# 启用 pnpm(corepack 是 Node 自带的包管理器入口)
|
||
corepack enable
|
||
```
|
||
|
||
### 2. 安装依赖
|
||
|
||
```sh
|
||
pnpm install
|
||
```
|
||
|
||
### 3a. 开发模式(dev,两个进程)
|
||
|
||
```sh
|
||
# 终端 1:启动 boardgame.io relay server(:8000)
|
||
pnpm --filter @tts-like/server dev
|
||
|
||
# 终端 2:启动 vite dev server(:5173)
|
||
pnpm dev
|
||
```
|
||
|
||
打开 http://localhost:5173 → 选游戏 → "本地" 单机调试,或 "联机" 创建/加入房间。
|
||
vite proxy 自动把 `/api` 和 `/socket.io` 转发到 :8000,同源无 CORS。
|
||
|
||
### 3b. 一键 dev(单进程,server 顺带 serve 静态)
|
||
|
||
```sh
|
||
pnpm --filter @tts-like/server dev # :8000
|
||
# 另一个终端:
|
||
pnpm --filter @tts-like/web build # 构建到 apps/web/dist
|
||
# server 检测到 dist 后自动 serve → http://localhost:8000 直接可用(无需 vite)
|
||
```
|
||
|
||
### 3c. 一键单端口启动(推荐,含双升等全部游戏)
|
||
|
||
根目录 `start.sh`:以 `PORT=5173` 启动 Koa,单进程同时 serve 前端页面 + `/api` + `/socket.io`,浏览器直连 `:5173`,**无需 Vite 代理**。dist 缺失会自动 build;启动前自动清理 5173/8000 残留。
|
||
|
||
```sh
|
||
./start.sh
|
||
# 打开 http://localhost:5173
|
||
```
|
||
|
||
> 该模式与「统一端口」设计一致:Koa 在 5173 上即完整应用。公网暴露时直接映射 5173 端口即可(如 Cloudflare Tunnel / 反向代理),客户端零配置。详见 `docs/dev-log/14-double-up-game.md`「部署」一节(frp 配置不在本仓库范围内)。
|
||
|
||
### 4. 验证(可选)
|
||
|
||
```sh
|
||
pnpm -r ts # 全包类型检查
|
||
pnpm -r test # 单元测试(engine + server)
|
||
pnpm test:e2e # Playwright E2E(自动起 server + web)
|
||
```
|
||
|
||
### 5. 局域网联机
|
||
|
||
dev 模式 vite 默认监听 `0.0.0.0:5173`,server 的 origins 默认覆盖 LAN 网段(192.168 / 10 / 172.16-31 / 100.x Tailscale)。
|
||
其它设备访问 `http://<本机内网IP>:5173/` 即可加入同一房间。
|
||
|
||
## 迁移到其它机器
|
||
|
||
把整个项目目录拷到新机器后,按顺序执行:
|
||
|
||
```sh
|
||
# 1. 装 Node 22(nvm 方式)
|
||
nvm install 22 && nvm use 22
|
||
|
||
# 2. 启用 pnpm
|
||
corepack enable
|
||
|
||
# 3. 清掉旧机器的依赖产物(不同 Node 版本 / 不同 OS 架构的 node_modules 不要跨机器拷)
|
||
rm -rf node_modules packages/*/node_modules apps/*/node_modules
|
||
|
||
# 4. 重装依赖
|
||
pnpm install
|
||
|
||
# 5. 验证
|
||
pnpm -r ts && pnpm -r test && pnpm test:e2e
|
||
|
||
# 6. 启动
|
||
pnpm --filter @tts-like/server dev # 终端 1
|
||
pnpm dev # 终端 2
|
||
```
|
||
|
||
**注意事项:**
|
||
|
||
- **不要跨机器拷 `node_modules`**:原生依赖(如 esbuild / playwright 浏览器二进制)按 OS / 架构编译,跨机器会 ABI 不匹配。新机器重新 `pnpm install`。
|
||
- **Playwright 浏览器**:首次跑 e2e 要 `npx playwright install`(下载 Chromium)。
|
||
- **房间数据是 InMemory**:server 重启会丢所有进行中的房间(boardgame.io 默认 InMemory)。要持久化需接 DB(v2 规划)。
|
||
- **生产部署**:用 `docker compose up --build`(见 `docker-compose.yml`),把 `ALLOWED_ORIGINS` 改成你的真实域名。反代(Nginx/Caddy)终止 TLS 后转发到 :8000。也可用单端口模式:构建后 `PORT=5173 ALLOWED_ORIGINS=https://你的域名 pnpm --filter @tts-like/server start`,直接映射 5173。
|
||
- **CORS**:dev 默认覆盖 LAN;生产必须用 `ALLOWED_ORIGINS` 环境变量设具体 origin 列表。
|
||
|
||
## 设计参考
|
||
|
||
- [`docs/impl.md`](./docs/impl.md) — overall architecture and phases
|
||
- [`docs/ui-primitives.md`](./docs/ui-primitives.md) — UI component API
|
||
- [`docs/dev-log/README.md`](./docs/dev-log/README.md) — 开发日志索引(做什么 → 问题 → 怎么解决)
|
||
|
||
## License
|
||
|
||
MIT
|