diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..208e9a5 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,50 @@ +# AGENTS.md + +仙途家族志 · Chronicle of the Immortal Clan — Electron + React + TS 家族修仙模拟器。全部 UI 与文案为中文。 + +## 命令 + +```bash +npm test # vitest 引擎测试(tests/*.test.ts,全部纯 Node,无 DOM/DB 依赖) +npx vitest run tests/world.test.ts # 单文件测试 +npm run typecheck # tsc --noEmit(npm 会打 warn 噪音,用 npx tsc --noEmit 更干净) +npm run dev # electron-vite 热更新(开发期 origin 为 http://localhost:5173) +npm run build # 产物到 out/ +npm run package # build + electron-builder(Linux 打 win 包可出产物,但未签名,Windows 上可能被 SmartScreen 静默拦截;正规发布在 Windows 侧重跑此命令) +``` + +端到端冒烟(渲染 + OPFS 数据库 + 开局推进 + 可选截图): + +```bash +npm run build +SMOKE_TEST=1 npx electron out/main/index.js --no-sandbox --disable-gpu # 退出码 0 = 全通 +SMOKE_TEST=1 SMOKE_SHOTS_DIR=/tmp/opencode/shots npx electron ... # 附带 UI 截图 +``` + +冒烟会写真实用户数据目录(Linux 下 `~/.config/Electron`),跑完删掉该目录以免脏数据。 + +## 环境坑 + +- npm 12 拦截 postinstall:首次安装后须 `npm install-scripts approve electron esbuild`,否则 Electron 二进制缺失。 +- 私有 registry 的 `_auth` token 只在用户级 `~/.npmrc`;项目 `.npmrc` 只保留 registry 映射,不要把 token 写进仓库。 +- Linux 无 emoji 字体:**所有图标一律用汉字印章字符**(renderer/ui/styles.css 的 `.s-icon/.res-icon/.bld-icon`),不要引入 emoji。 + +## 架构要点 + +- `src/renderer/game/`:纯 TS 游戏引擎(无 React/DOM import),可被 vitest 直接测试;`types/domain.ts` 是全量领域类型,改状态结构先看它。 +- `src/renderer/ui/`:React + zustand(`ui/store.ts`)。World 的 game state 是 mutable,advance 后 `revision++` 触发重渲染;订阅 `revision` 是面板刷新惯例。 +- 引擎 = 种子随机数(sfc32,`core/rng.ts`)+ 不可变快照存 `state.rng`,同 seed 全程可重放(tests/world.test.ts 有确定性用例,改任何 tick 顺序都要保证仍然确定性)。 +- 建档开头成员 id 硬编码 `x1`~`x5`,tests 依赖。 + +## MetonaSqlark(@metona-team/metona-sqlark 0.7.4)陷阱 + +- SQL 方言为自有实现(不是 SQLite):建表列类型写 `string|number|boolean|date|json`,**不是** `INTEGER/TEXT`;不支持 `INSERT OR REPLACE`、`ON CONFLICT`、`rowid`——用「SELECT 判断 → UPDATE/INSERT」或直接 `DELETE+INSERT`。 +- aria 引擎同库一个 tab 只能建一次连接(Web Locks → `ARIA_LOCKED`):存取必须走 `game/storage/db.ts` 的单例 `getSaveSlot(slot)` / `getSlotManager()`,**禁止**每次 `new SaveSlot/new SlotManager`。 +- 数据在浏览器 OPFS(renderer 内),main 进程无 DB 逻辑;开发与打包后的 origin 不同,两环境存档不互通。 +- 存储层通过 `SaveDbDriver` 抽象(`storage/slots.ts`),node 环境下无 OPFS,测试只覆盖引擎不覆盖 DB。 + +## 工作流约定 + +- 提交前:`npm test` + `npm run typecheck` 必须绿(改存储/SQL 后再跑一次冒烟)。 +- 平衡数值集中在 `game/data/`(realms/pacing/buildings/events...),调平衡不改引擎流程。 +- 发布产物 `release/`、`out/` 均已 gitignore,勿入库。