docs: 三文档完整更新至 0.1.21
AGENTS.md:架构章节重写(0.1.14 大重构路径)+ 引擎红线(时轮/随机/事件闸/特效出口/插件/门面/双金钟罩) + 世界自演进模型 + sqlark陷阱 + 数值基调(0.1.16 修为经济化/0.1.17 市场实体化)+ 修改纪律 README.md:快速开始(1018 用例)+ 0.1.14+ 架构一览 + 守护机制(双金钟罩/事件闸/插件/回放) + 版本沿革 0.1.12-0.1.21 PROJECT_MEMORY.md:版本时间线补齐(0.1.12-0.1.21 每迭代的为什么)+ 关键架构决策 (事件闸定稿/WorldSim 四层递进/引擎表现双通道/normalize即迁移/线程定论) + 踩坑教训(era 无延续档/潮汐符号反向/事件闸竞态/每tick存档/金钟罩盲区) + 诚实技术债清单 + 修改路径
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# AGENTS.md
|
# AGENTS.md
|
||||||
|
|
||||||
仙途家族志 · Chronicle of the Immortal Clan — Electron + React + TS 家族修仙模拟器。全部 UI 与文案为中文。
|
仙途家族志 · Chronicle of the Immortal Clan — Electron + React + TS 家族修仙模拟器。全部 UI 与文案为中文。
|
||||||
|
当前版本 **0.1.21**(《大势流转》:era↔景气双向闭环 + 世界史表 + 渲染管线修复)。
|
||||||
|
|
||||||
## 命令
|
## 命令
|
||||||
|
|
||||||
@@ -32,23 +33,42 @@ SMOKE_TEST=1 SMOKE_SHOTS_DIR=/tmp/opencode/shots npx electron ... # 附
|
|||||||
- 私有 registry 的 `_auth` token 只在用户级 `~/.npmrc`;项目 `.npmrc` 只保留 registry 映射,不要把 token 写进仓库。
|
- 私有 registry 的 `_auth` token 只在用户级 `~/.npmrc`;项目 `.npmrc` 只保留 registry 映射,不要把 token 写进仓库。
|
||||||
- Linux 无 emoji 字体:**所有图标一律用汉字印章字符**(renderer/ui/styles.css 的 `.s-icon/.res-icon/.bld-icon`),不要引入 emoji。
|
- Linux 无 emoji 字体:**所有图标一律用汉字印章字符**(renderer/ui/styles.css 的 `.s-icon/.res-icon/.bld-icon`),不要引入 emoji。
|
||||||
|
|
||||||
## 插件架构(0.1.8 起)
|
## 架构(0.1.14 大重构后,目录与路径以此为准)
|
||||||
|
|
||||||
- **万物皆是插件**:`core/plugin.ts` 协议(Manifest/dependencies/conflicts/install/uninstall);`engine/pluginManager.ts` 安装管线(依赖校验、异常回滚、追踪型上下文——插件注册的时轮钩子卸载时全摘);`engine/plugin-bootstrap.ts` 三枚常驻核心插件(core-systems/core-data/core-events,protected 不可卸)。
|
```
|
||||||
- **事件多池**:`world.eventPools`(core 池受保护不可删)+ `eventRoll` 聚合抽样;第三方插件 `ctx.addEventPool(id, events)` 即注入内容。**注意 findEvent 必须带 world 参数查池**(`events.ts`),否则未知事件直接软锁。
|
src/renderer/game/ 纯 TS 引擎(无 React/DOM,vitest 直测)
|
||||||
- **能力卡**:`engine/capabilities.ts` 12 张;时钟注册走 `viaCap`;tournament/tribulation/apprentice/season 四卡各自内部检查 `w.sysEnabled`(无独立钩子,勿直接调)。
|
engine/GameEngine.ts 唯一门面:advance/restore/engineFromSnapshot/about/resolvePending
|
||||||
- **门面**:`engine/api.ts` GameFacade(act 24 项/query 6 类/subscribe 退订协议/about);**UI store 的 `facade` 字段必须通过 openState/startNewGame 赋值**,否则 act 走残缺 fallback。
|
engine/kernel/ Kernel.ts(三合一:Clock+Rng+BUS 转发)+ clock/rng/plugin/names/format/guide/urgency/timesense
|
||||||
- **金钟罩**:0.1.11 审计修复批次后三档指纹(47/100/180 年 × 3 seed = 9 值,见 tests/clock.test.ts;0.1.8 基线已作废、0.1.10 重建后再次漂移、0.1.11 大比 once/prune 后重固化)。
|
engine/runtime/ World.ts(大对象+normalize+bus 转发)/clocks.ts(时轮注册)/ApiFacade.ts(GameFacade)
|
||||||
|
Systems/(production/aging/cultivation/missions/events/diplomacy/marriage/tribulation/tournament/lifecycle/combat)
|
||||||
|
capabilities.ts(12 能力卡)/pluginManager.ts/plugin-bootstrap.ts/creation.ts/pcgen.ts
|
||||||
|
engine/sim/ 世界自进化: WorldSim.ts / worldsim-data.ts(数值与常量唯一权威)/Market.ts / worldsim-brief.ts
|
||||||
|
engine/narrative/ 族谱/传记/定鼎/年轴/百年报告
|
||||||
|
data/ balance 表 + DataPackRegistry(registry.ts pack() 单源;PILL_RECIPES/FORGE_RECIPES/ERA_CONF 等)
|
||||||
|
storage/ db(MetonaSqlark 单例)/slots(槽+快照+exportEnvelope)/migrate(CURRENT_SCHEMA=2,即 normalize 即迁移)
|
||||||
|
types/domain.ts 全量领域类型(改状态结构先看它)
|
||||||
|
src/renderer/ui/ React + zustand(store.ts 主状态;面板按 panel switch 挂载;订阅 revision 刷新)
|
||||||
|
src/main/ Electron 主进程(app:// 协议 + IPC 存档导出/导入)
|
||||||
|
```
|
||||||
|
|
||||||
## 架构要点
|
## 引擎红线(0.1.14+)
|
||||||
|
|
||||||
- `src/renderer/game/`:纯 TS 游戏引擎(无 React/DOM import),可被 vitest 直接测试;`types/domain.ts` 是全量领域类型,改状态结构先看它。
|
- **统一时轮**:月度 phase(production/aging/cultivation/missions/events/diplomacy/epilogue)+ 年首钩子均注册于 `runtime/clocks.ts`。**新增系统 = 注册一行,禁止手改 `advanceMonth` 本体**(World.ts:329)。
|
||||||
- **统一时轮 `core/clock.ts`**:月度 phase(production/aging/cultivation/missions/events/diplomacy/epilogue)+ 年首钩子均注册于 `engine/clocks.ts`。**新增系统 = 注册一行,禁止手改 `advanceMonth` 本体**。
|
- **统一随机**:引擎只经 `World.rng`;UI 播种用 `RngHub.rollSeed()`、音效白噪用 `RngHub.audioNoise01()`;**不要**在逻辑里引入 Math.random()(引擎域 0 处)。渲染层 canvas 粒子散布的 Math.random 不进引擎状态,可留。
|
||||||
- **统一随机 `core/rng.ts`**:引擎只经 `World.rng`(含 `nextCount` 审计);UI 播种用 `RngHub.rollSeed()`、音效白噪用 `RngHub.audioNoise01()`,**不要**在逻辑里引入 Math.random()。
|
- **引擎单线程定论**(0.1.21 实测):`advanceMonth` 2160 月平均 **0.05ms/tick**——无 Worker 化必要;拖帧热点在 UI 渲染与存档(都已在 0.1.20/0.1.21 修)。
|
||||||
- **金钟罩 `tests/clock.test.ts`**:3 枚固定 seed × 三档月数(560/1200/2160 = 47/100/180 年)指纹常驻(0.1.11 基线:见注释 GOLDEN)。任何改动若破坏确定性立即红;**有意变更时序/数值时**指纹一并重算并在注释注明原因。
|
- **事件闸**:pending 事件唯一写入入口是 `events.ts` 的 `fire(w, id, priority)`(0=普通遇占放弃 / 1=高优 raid·渡劫·大比可顶替被占者,被顶替者入 `eventQueue` 下月兑现不丢失)。**禁止直写 `state.pendingEvent`**(渡劫/破境丹均已改走 fire)。`applyEventChoice` 前置校验 `pendingEvent===id`(陈旧 Modal 二次结算防线)。
|
||||||
- `src/renderer/ui/`:React + zustand(`ui/store.ts`)。World 的 game state 是 mutable,advance 后 `revision++` 触发重渲染;订阅 `revision` 是面板刷新惯例。
|
- **特效/音效语义出口**:`WorldEventBus.onFx?(em: FxEmit)` + `World.emitFx(kind, source?)`(零 rng 消耗);UI 的 `makeBus` 桥接 FxGate;`onLog kind` 音效映射保留作兜底。
|
||||||
- 引擎 = 种子随机数(sfc32,`core/rng.ts`)+ 不可变快照存 `state.rng`,同 seed 全程可重放(tests/world.test.ts 有确定性用例,改任何 tick 顺序都要保证仍然确定性)。
|
- **插件架构**(0.1.8 起,路径已迁 engine/runtime|kernel):`kernel/plugin.ts` 协议、`runtime/pluginManager.ts` 安装管线(依赖校验/异常回滚/追踪型上下文——注销时钩子全摘)、`plugin-bootstrap.ts` 三核心插件(core-systems/core-data/core-events protected)。事件多池 `world.eventPools`;**findEvent 必须带 world 参数查池**。能力卡 12 张经 `viaCap` 注册;tournament/tribulation/apprentice/season 四卡各自内部检查 `w.sysEnabled`(无独立钩子)。
|
||||||
- 建档开头成员 id 硬编码 `x1`~`x5`,tests 依赖。
|
- **门面**:`runtime/ApiFacade.ts` GameFacade(act 24 项/query 6 类/subscribe 退订协议/about);**UI 面板事实走 world 直调**(act 为测试/自动化通道),`actDirect` 与 ACT_CATALOG 语义对齐(0.1.20 补齐全 24 项);store 的 `facade` 必须在 openState/startNewGame 赋值。
|
||||||
|
- **金钟罩(双基线)**:`tests/clock.test.ts` 的 `GOLDEN`(直调冻结世界)+ `GOLDEN_RESOLVED`(自动 resolve 长跑"现实"世界),各 3 seed × 三档月数(560/1200/2160)共 18 值。当前为 **0.1.21 基线**(见注释)。指纹 `tests/fingerprint.helper.ts` 含全世界轴(era/stance/prosperity/relationsWithOthers/calamity/pendingEvent/eventQueue/worldAnnals)。**有意变更时序/数值时**:指纹一并重算并在注释注明原因。
|
||||||
|
|
||||||
|
## 世界自演进模型(0.1.14 sim/ 层,改数值勿动流程)
|
||||||
|
|
||||||
|
- **市场实体化**:`marketPool` 是真库存——世界月供给(`worldSupplyRate` × 潮汐span × era.supplyMult)vs 常驻需求(`worldDemandRate`);NPC 按 `def.sells/buys` 逐月入池出池(姿态/区域灵势/灾年调制);玩家买卖经 `WorldSim.tradeSettle` 回写(买浅价涨/卖盈价跌);池深 < `tradeFloorPct(0.35)` 断供拒单(与 `poolFloorPct` 单常量一致)。`driftMarket` rebalance=0.025 弱锚定(让供需真实撬动价格,勿调回 0.1+)。
|
||||||
|
- **世纪弧 era**:盛世/平世/乱世/末法,`ERA_CONF`(灾年概率/供需/拍卖/tideBias)+ `ERA_DURA`(续航窗口);flow 权重和 <1(留白=延续档);**转移权重受世界温度调制**(`worldTemperature()` + `tempEraK`)——时代由天下兴衰孕育、又重塑天下。
|
||||||
|
- **NPC 定力**:`npcDyn.prosperity/stance/relationsWithOthers`——姿态(守成/扩张/隐忍/结盟)年首重估,调制 raid/互攻/贸量/外交;互攻按 power 加权 + 打残广播;玩家劫掠/结盟写关系网(蝴蝶效应)。
|
||||||
|
- **灾年**:持续 6 月(`calamityLeft`),减产乘子(CALAMITY_FAMILY)+ 疫病/兽潮体感 + NPC 贸易 ×0.7 + 群雄相噬 ×1.5;世界侧 `CALAMITY_EFFECT` 冲击池。
|
||||||
|
- **天下史表**:`worldSim.worldAnnals[]`(十年一鉴 80 页留档,免 newsFeed 裁剪丢失)。
|
||||||
|
|
||||||
## MetonaSqlark(@metona-team/metona-sqlark 0.7.4)陷阱
|
## MetonaSqlark(@metona-team/metona-sqlark 0.7.4)陷阱
|
||||||
|
|
||||||
@@ -56,15 +76,17 @@ SMOKE_TEST=1 SMOKE_SHOTS_DIR=/tmp/opencode/shots npx electron ... # 附
|
|||||||
- aria 引擎同库一个 tab 只能建一次连接(Web Locks → `ARIA_LOCKED`):存取必须走 `game/storage/db.ts` 的单例 `getSaveSlot(slot)` / `getSlotManager()`,**禁止**每次 `new SaveSlot/new SlotManager`。
|
- aria 引擎同库一个 tab 只能建一次连接(Web Locks → `ARIA_LOCKED`):存取必须走 `game/storage/db.ts` 的单例 `getSaveSlot(slot)` / `getSlotManager()`,**禁止**每次 `new SaveSlot/new SlotManager`。
|
||||||
- 数据在浏览器 OPFS(renderer 内),main 进程无 DB 逻辑;开发与打包后的 origin 不同,两环境存档不互通。
|
- 数据在浏览器 OPFS(renderer 内),main 进程无 DB 逻辑;开发与打包后的 origin 不同,两环境存档不互通。
|
||||||
- 存储层通过 `SaveDbDriver` 抽象(`storage/slots.ts`),node 环境下无 OPFS,测试只覆盖引擎不覆盖 DB。
|
- 存储层通过 `SaveDbDriver` 抽象(`storage/slots.ts`),node 环境下无 OPFS,测试只覆盖引擎不覆盖 DB。
|
||||||
|
- 存档防线:`loadState`/importAll 都过 `migrateIfNeeded`(TOO_NEW/未知版本 → MigrationError);normalizeGameState 是幂等兜底(**0.1.14+ 全部新字段靠它补**:worldSim 全套/era/prosperity/stance/worldAnnals 等,改字段记得同步补兜底);暂无 v3(需转换内容时才升)。
|
||||||
|
|
||||||
## 数值基调(0.1.10 重建后,勿当 bug 调回去)
|
## 数值基调(勿当 bug 调回去)
|
||||||
|
|
||||||
- **pacing.ts 的 MAJOR_RATE 是进度唯一生效因子**(qi 2.2、foundation 1.4、core 0.95、nascent 0.68、spirit 0.48);`realms.ts` 的 `expBase/expGrowth/maxRealmExp` 曲线**未参与计算**(历史摆设,勿以它反推)。
|
- **pacing.ts 的 MAJOR_RATE 是进度唯一生效因子**(qi 2.2、foundation 1.4、core 0.95、nascent 0.68、spirit 0.48);`realms.ts` 的 `expBase/expGrowth/maxRealmExp` 曲线**未参与计算**(历史摆设,勿以它反推)。
|
||||||
- 月率 base = `1.0 + perception*0.18`;65 岁起 ×0.72 衰减、8 岁以下 ×0.65(圣者护族 60+ 高境界者存在时乘 1.3)。
|
- 月率 base = `1.0 + perception*0.18`;65 岁起 ×0.72 衰减、8 岁以下 ×0.65(圣者护族 60+ 高境界者存在时乘 1.3)。
|
||||||
- 寿元:75/150/220/340/520/850(凡人→化神,0.1.10 放宽的梯度)。
|
- **0.1.16 修为经济化**:练气以上修行者月耗灵草(闭关2/普通1),无草速修 ×0.6~1.0 衰减——灵草是第一战略资源。
|
||||||
- 大境界晋升走**渡劫事件三选**(硬渡/护法/压制);玩家 12 月不应会**自动压制一年**(防挂机软锁,events.ts 计数 `tribPendingMonths`)。
|
- 寿元:75/150/220/340/520/850(凡人→化神)。
|
||||||
- 周期事件优先级:命运(百年/飞升)> 大比 > 传薪 > 拍卖 > 岁祷 > 回声;大比有 `once`,一年一届。
|
- 大境界晋升走**渡劫事件三选**(硬渡/护法/压制,12 月不应自动压制);破境丹在需渡劫时药力转 `tribBoost`(+12%) 入渡劫,**不可跳过**。
|
||||||
- `family.flag` 年份键(auction-/prayerDone-/echoDone-/recruitDone-)每 tick 剪 3 年前旧键。
|
- 周期事件优先级:命运(百年/飞升)> 大比 > 传薪(年锚 flag)> 拍卖(era 概率调制)> 岁祷 > 回声。
|
||||||
|
- `family.flag` 年份键(auction-/prayerDone-/echoDone-/recruitDone-/legacyDone-)每 tick 剪 3 年前旧键。
|
||||||
|
|
||||||
## 修改纪律(防覆盖——血泪教训,务必遵守)
|
## 修改纪律(防覆盖——血泪教训,务必遵守)
|
||||||
|
|
||||||
@@ -75,9 +97,9 @@ SMOKE_TEST=1 SMOKE_SHOTS_DIR=/tmp/opencode/shots npx electron ... # 附
|
|||||||
2. **改动中**:批量替换一律用「先 assert 旧文本存在 → 替换 → 再全局 grep 断言新文本唯一」三步;禁止无检查的 sed/python 盲替。
|
2. **改动中**:批量替换一律用「先 assert 旧文本存在 → 替换 → 再全局 grep 断言新文本唯一」三步;禁止无检查的 sed/python 盲替。
|
||||||
3. **禁止 `git checkout -- <file>` / 整文件回滚**(这是历史事故元凶)。确需回滚时:`git show HEAD:<file> > /tmp/bak` 手动 diff 恢复,恢复后跑全量测试确认无伤。
|
3. **禁止 `git checkout -- <file>` / 整文件回滚**(这是历史事故元凶)。确需回滚时:`git show HEAD:<file> > /tmp/bak` 手动 diff 恢复,恢复后跑全量测试确认无伤。
|
||||||
4. **优先小步快跑**:每个功能块改完立即 `npm test`(引擎)或 `tsc`(UI 类型),绿了再动下一处——绝不在错误状态上加新修改。
|
4. **优先小步快跑**:每个功能块改完立即 `npm test`(引擎)或 `tsc`(UI 类型),绿了再动下一处——绝不在错误状态上加新修改。
|
||||||
5. **高危文件白名单**(world.ts / events.ts / store.ts / styles.css / cultivation.ts)改动后必须 `git diff --stat` 核对改动面与预期一致(±文件行数应与你改的块吻合)。
|
5. **高危文件白名单**(world.ts / events.ts / store.ts / styles.css / cultivation.ts / **WorldSim.ts / worldsim-data.ts**)改动后必须 `git diff --stat` 核对改动面与预期一致。
|
||||||
6. 每次迭代收尾:`git status` 应干净 + `git log --oneline` 确认每步都有提交记录;凡 "git stash/checkout/rm" 类命令,执行前后都 `git status` 留痕。
|
6. 每次迭代收尾:`git status` 应干净 + `git log --oneline` 确认每步都有提交记录;凡 "git stash/checkout/rm" 类命令,执行前后都 `git status` 留痕。
|
||||||
|
|
||||||
- 提交前:`npm test` + `npm run typecheck` 必须绿(改存储/SQL 后再跑一次冒烟)。
|
- 提交前:`npm test`(当前 43 套件 1018 例全绿)+ `npm run typecheck` 必须绿(改存储/SQL 后再跑一次冒烟)。
|
||||||
- 平衡数值集中在 `game/data/`(realms/pacing/buildings/events...),调平衡不改引擎流程。
|
- 平衡数值集中在 `game/data/` 与 `engine/sim/worldsim-data.ts`(世界循环参数唯一权威),调平衡不改引擎流程。
|
||||||
- 发布产物 `release/`、`out/` 均已 gitignore,勿入库。
|
- 发布产物 `release/`、`out/` 均已 gitignore,勿入库。
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
一座庄园、一家修士、四邻势力,随年月流转:族人修炼突破、建筑产出、探秘寻宝、婚丧嫁娶;
|
一座庄园、一家修士、四邻势力,随年月流转:族人修炼突破、建筑产出、探秘寻宝、婚丧嫁娶;
|
||||||
仇家犯境则结阵应战;百年之际,望气定鼎,春秋原上写下一卷族史。
|
仇家犯境则结阵应战;百年之际,望气定鼎,春秋原上写下一卷族史。
|
||||||
|
**世界也在自演进**:市场有真库存与供需呼吸,NPC 有战略姿态与恩怨网,时代有盛世乱世的大势流转——天下兴衰与家族命运互为因果。
|
||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
@@ -11,32 +12,39 @@
|
|||||||
npm install # 依赖(含 git.metona.cn 私有 registry,token 在用户级 ~/.npmrc)
|
npm install # 依赖(含 git.metona.cn 私有 registry,token 在用户级 ~/.npmrc)
|
||||||
npm install-scripts approve electron esbuild # npm12 首装时必须(Electron 二进制)
|
npm install-scripts approve electron esbuild # npm12 首装时必须(Electron 二进制)
|
||||||
npm run dev # 开发模式(热更新)
|
npm run dev # 开发模式(热更新)
|
||||||
npm run verify # 发布验收哨兵:vitest + typecheck + build
|
npm test # 引擎测试(43 套件 / 1018 用例,纯 Node 无 GUI)
|
||||||
npm run verify:package # 附打包预览(electron-builder)
|
npm run build # 产物到 out/
|
||||||
npm run package # 直接打包(Windows 需在 Windows 侧执行)
|
npm run package # 打包(Windows 需在 Windows 侧执行)
|
||||||
npm test # 仅测试(923+ 用例)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
端到端冒烟(渲染 + OPFS + 开局推进 + 可选截图):见 `AGENTS.md`「命令」。
|
||||||
|
|
||||||
## 架构一览
|
## 架构一览
|
||||||
|
|
||||||
```
|
```
|
||||||
src/renderer/game/ 纯 TS 引擎(无 React/DOM,可被 vitest 直测)
|
src/renderer/game/ 纯 TS 引擎(无 React/DOM,vitest 直测;单线程,实测 0.05ms/tick)
|
||||||
core/ rng(RngHub) · clock(GameClock·7相位) · plugin · legacy · report · yearaxis · biography · genealogy
|
engine/GameEngine.ts 唯一门面:advance / restore / engineFromSnapshot / about / resolvePending
|
||||||
data/ balance 表 + DataPackRegistry(数据包可覆写)
|
engine/kernel/ Kernel(Clock+Rng 三合一)+ clock / rng(RngHub) / plugin / guide / urgency...
|
||||||
engine/ world · clocks(注册) · pluginManager(∃插件管线) · capabilities(12 能力卡) · api(GameFacade act/query/subscribe/about)
|
engine/runtime/ World(大对象+normalize+bus 转发)· clocks(时轮注册)· ApiFacade(GameFacade)
|
||||||
systems/(生产·寿元·修炼·任务·事件·外交·婚育·渡劫·大比·寄读)
|
Systems/(生产/修炼/任务/事件/外交/婚育/渡劫/大比/寿元/战斗)
|
||||||
storage/ db(MetonaSqlark 单例) · slots(存档槽+快照) · migrate(版本迁移链 v1→v2)
|
capabilities(12 能力卡)· pluginManager(插件管线)
|
||||||
src/renderer/ui/ React + zustand(store 持 GameFacade;面板订阅 revision 刷新)
|
engine/sim/ WorldSim(世界自进化)· worldsim-data(数值唯一权威)· Market(行情/买卖)
|
||||||
src/main/ Electron 主进程(app:// 协议 + IPC 存档导出/导入)
|
engine/narrative/ 族谱/传记/定鼎/年轴/百年报告
|
||||||
|
data/ balance 表 + DataPackRegistry(PILL_RECIPES / FORGE_RECIPES / ERA_CONF)
|
||||||
|
storage/ db(MetonaSqlark 单例) · slots(槽+快照) · migrate(CURRENT_SCHEMA=2,normalize 即迁移)
|
||||||
|
types/domain.ts 全量领域类型(改状态结构先看它)
|
||||||
|
src/renderer/ui/ React + zustand(store.ts 主状态;面板按 tab 挂载;LogFeed 精订阅)
|
||||||
|
src/main/ Electron 主进程(app:// 协议 + IPC 存档导出/导入)
|
||||||
```
|
```
|
||||||
|
|
||||||
设计文档见 `AGENTS.md`(环境坑/架构红线/方言陷阱/金钟罩约定)。
|
设计文档见 `AGENTS.md`(环境坑 / 架构红线 / 引擎纪律 / 金钟罩双基线 / 修改纪律)。
|
||||||
|
|
||||||
## 守护机制
|
## 守护机制
|
||||||
|
|
||||||
- **金钟罩**:tests/clock.test.ts 三枚固定 seed × 560 月指纹常驻(0.1.8 基线:9af71ecb/63cede89/ebfec4a4);有意变更时序需受控更新并注明。
|
- **双金钟罩**:`tests/clock.test.ts` 的 `GOLDEN`(直调冻结世界)+ `GOLDEN_RESOLVED`(自动 resolve 长跑"现实"世界),各 3 固定 seed × 560/1200/2160 月(47/100/180 年)= 18 指纹;指纹含全世界轴(era/stance/prosperity/关系网/事件闸);**0.1.21 基线**。有意变更时序需受控更新并注明。
|
||||||
- **插件化**:万物皆是插件(系统/数据包/事件池),示例见 tests/helpers/examplePlugin.ts。
|
- **事件闸**:pending 唯一入口 `fire(w,id,priority)`——高优(raid/渡劫/大比)可顶替被占者,被顶替者入队下月兑现;`applyEventChoice` 前置校验防陈旧 Modal 二次结算。
|
||||||
- **可回放**:种子随机(sfc32)+ 闰档快照 + 回档时间轴。
|
- **插件化**:万物皆是插件(系统/数据包/事件池),三核心插件 protected 常驻;示例见 tests/helpers/examplePlugin.ts。
|
||||||
|
- **可回放**:种子随机(sfc32,引擎域零 Math.random)+ 快照回放保真(restore 重建内核+回置 rng)。
|
||||||
|
|
||||||
## 打包产物
|
## 打包产物
|
||||||
|
|
||||||
@@ -44,19 +52,20 @@ src/main/ Electron 主进程(app:// 协议 + IPC 存档导
|
|||||||
- 图标资源 resources/icon.png|ico —— electron-builder 自动使用
|
- 图标资源 resources/icon.png|ico —— electron-builder 自动使用
|
||||||
- 注意:WSL/Linux 交叉打 win 包可行但未签名,正规发布请用 Windows 侧重跑
|
- 注意:WSL/Linux 交叉打 win 包可行但未签名,正规发布请用 Windows 侧重跑
|
||||||
|
|
||||||
## 版本沿革(0.1.0 → 0.1.9)
|
## 版本沿革(0.1.0 → 0.1.21)
|
||||||
|
|
||||||
| 版本 | 主题 |
|
| 版本 | 主题 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 0.1.0 | 核心循环(修仙/家族/经营/战斗)完备可玩 |
|
| 0.1.0-0.1.11 | 核心循环 → 插件架构 → 审计三连(详见 docs/PROJECT_MEMORY.md) |
|
||||||
| 0.1.1 | 养成闭环+回档+叙事(指婚/装备/祭祖/战报匣/年度纸笺) |
|
| 0.1.12 | 金碧山河(SVG 素材 + 动效系统 + 舞美重装) |
|
||||||
| 0.1.2 | 宗族气韵(职事/悟道/谱系/碑录/庆典/飞升/合音效) |
|
| 0.1.13 | 交付与回档(工艺/界面修复 + UI 存储直连回档) |
|
||||||
| 0.1.3 | 深度审计(旧档兼容/血缘/联姻/远征修复) |
|
| 0.1.14 | 大重构:GameEngine 门面 + Kernel 三合一 + WorldSim 世界自进化(五大闭环) |
|
||||||
| 0.1.4 | 百年定局(终局/大比/寄读/春秋原) |
|
| 0.1.15 | 深度审计加固(7 P0 + 20+ P1 歼灭;restore 双注册/引擎锁死等) |
|
||||||
| 0.1.5 | 人物志(志向/渡劫/列传/契合/回声) |
|
| 0.1.16 | 资源闭环 × 世情入味(修为耗草/炼丹概率化/铸器/灵脉收益/NPC 战力/灾变落效) |
|
||||||
| 0.1.6 | 时轮与造化(GameClock/RngHub/时节/年轴/保护) |
|
| 0.1.17 | 天下为市——市场实体化(真库存/供需呼吸/NPC 上桌/玩家回写)+ 战争伤骨 + 关系网 |
|
||||||
| 0.1.7 | 仙门之钥(门面/能力注册表/数据包/开发者面板) |
|
| 0.1.18 | 时代绘卷(世纪弧 era/NPC 景气/蝴蝶效应/十年鉴)+ 特效入引擎(onFx 语义出口) |
|
||||||
| 0.1.8 | 万物皆是插件 + 全应用审计(60+ 缺陷歼灭) |
|
| 0.1.19 | 八方风雨(NPC 战略姿态/超卖潮/盟约连坐/干预天下)+ 孤立系统归并(FxGate/音效/兜底) |
|
||||||
| 0.1.9 | 百年报告 + 存档迁移 v2 + 战斗阵型 + 冬祷 + 发布哨兵 |
|
| 0.1.20 | 万世无谬(第二轮全量审计:事件闸优先级/era 延续/潮汐符号/弱锚定/双金钟罩) |
|
||||||
| 0.1.10 | 长线决断(数值重建:修炼提速/寿元放宽/渡劫修复 + 拍卖/传薪/护族) |
|
| 0.1.21 | 大势流转(线程定论 0.05ms、era↔景气双向闭环、世界史表、渲染管线修复) |
|
||||||
| 0.1.11 | 全源码审计缺陷歼灭 + UX 打磨(警讯徽章/首启引导/格式化) |
|
|
||||||
|
详见:`docs/PROJECT_MEMORY.md`(设计哲学与每个迭代的"为什么")。
|
||||||
|
|||||||
+62
-51
@@ -15,83 +15,94 @@
|
|||||||
1. 世代血脉(婚育/继嗣/谱系)——传承是主叙事;
|
1. 世代血脉(婚育/继嗣/谱系)——传承是主叙事;
|
||||||
2. 修炼纵深(境界/功法/悟道/渡劫)——成长是爽点;
|
2. 修炼纵深(境界/功法/悟道/渡劫)——成长是爽点;
|
||||||
3. 经营与外交(建筑/贸易/联姻/劫掠)——决策供给;
|
3. 经营与外交(建筑/贸易/联姻/劫掠)——决策供给;
|
||||||
4. 叙事编织(编年史/列传/百年报告/定鼎)——情绪收束。
|
4. 叙事编织(编年史/列传/百年报告/定鼎/天下史观)——情绪收束。
|
||||||
|
- **0.1.14+ 的独特命题**:世界不是背景板——市场有真库存(供需呼吸/NPC 上桌/玩家回写)、NPC 有战略姿态(守成/扩张/隐忍/结盟)与恩怨网(蝴蝶效应)、时代有大势弧(盛世/乱世/末法与景气双向闭环)。**天下兴衰与家族命运互为因果**,这是本作与"个人养成+结算"类游戏的本质区别。
|
||||||
|
|
||||||
## 二、版本时间线(每迭代的"为什么")
|
## 二、版本时间线(每迭代的"为什么")
|
||||||
|
|
||||||
| 版本 | 主题 | 当时为什么做 |
|
| 版本 | 主题 | 当时为什么做 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 0.1.0 | 核心循环 | 把"修仙+家族+经营+战斗"四系统全部立起来,形成可玩闭环 |
|
| 0.1.0-0.1.5 | 核心循环 → 养成闭环 → 审计 → 百年定局 → 人物志 | 立四系统、给成长闭环、上线前清毒、补"收束"、破成员同质化 |
|
||||||
| 0.1.1 | 养成闭环+存档安全 | 指婚/装备/祭祖/回档:管理自主度决定模拟器粘性 |
|
| 0.1.6-0.1.8 | 时轮与造化 → 仙门之钥 → 万物皆是插件 | 时间/随机统一(架构地基)→ 门面/能力卡/数据包 → 全部系统插件化 |
|
||||||
| 0.1.2 | 宗族气韵 | 职事/悟道/谱系/碑录:让"传承"有可视载体 |
|
| 0.1.9-0.1.11 | 百年报告/迁移 v2 → 长线决断 → 收官打磨 | 情感复盘 → 全灭崩溃数值重建 → 二次审计+UX 三件套 |
|
||||||
| 0.1.3 | 深度审计 | 刚做完新系统必有一批缺陷,上线前清毒 |
|
| 0.1.12 | 金碧山河 | 画面情绪价值:SVG 素材、动效系统、舞美 |
|
||||||
| 0.1.4 | 百年定局 | 模拟器缺"收束":四维评分+十二称号+春秋原 |
|
| 0.1.13 | 交付与回档 | 工艺修复 + 存储直连回档(玩家资产安全) |
|
||||||
| 0.1.5 | 人物志 | 成员同质化:志向/渡劫/列传/契合让"人"有戏 |
|
| **0.1.14** | **大重构:GameEngine 门面 + WorldSim** | 引擎/UI 边界彻底划清:世界自进化(市场/NPC/快讯)作为独立 sim 层 |
|
||||||
| 0.1.6 | 时轮与造化 | 时间与随机从"散装"走向"统一"(GameClock/RngHub)——**架构地基** |
|
| 0.1.15 | 深度审计 | 重构后必有一批缺陷;修 restore 双注册/引擎锁死等 7 P0 |
|
||||||
| 0.1.7 | 仙门之钥 | 门面/能力注册表/数据包:对外暴露与可拔插 |
|
| 0.1.16 | 资源闭环 × 世情入味 | "灵石无压力、资源无出口"——修为经济化/炼丹概率化/铸器/灵脉收益 |
|
||||||
| 0.1.8 | 万物皆是插件 | 把全部系统统一进插件协议(Manifest/依赖/卸载/追踪型钩子) |
|
| 0.1.17 | 天下为市 | 市场从"幽灵振荡器"变"真库存":玩家与 NPC 都能撼动行情——**世界对玩家单边透明死穴** |
|
||||||
| 0.1.9 | 百年报告与发布 | 情感复盘(报告)+工程收口(迁移管线/发布哨兵) |
|
| 0.1.18 | 时代绘卷 + 特效入引擎 | 世界缺大周期——世纪弧 era;特效从 UI 正则猜事件→引擎语义出口(onFx) |
|
||||||
| 0.1.10 | 长线决断 | **审计发现全灭崩溃**:修炼太慢+寿元短+渡劫误压——数值重建 |
|
| 0.1.19 | 八方风雨 + 孤立归并 | NPC 从统计物理→行为战略(stance 四姿态);超卖潮/盟约连坐/干预天下 |
|
||||||
| 0.1.11 | 收官打磨 | 二次审计(引擎8+UI11缺陷歼灭)+ UX 三件套(警讯/引导/格式化) |
|
| 0.1.20 | 万世无谬 | 第二轮全量审计:**事件闸竞态**(raid 落地率 18%)/era 无延续档/潮汐符号反向——三处"看着合理其实错" |
|
||||||
|
| 0.1.21 | 大势流转 | 线程定论(0.05ms 单线程无需 Worker);era↔景气**双向闭环**(自演进最高形态);渲染管线修 |
|
||||||
|
|
||||||
## 三、关键架构决策(及为什么)
|
## 三、关键架构决策(及为什么)
|
||||||
|
|
||||||
### 1. 纯 TS 引擎 + 确定性种子流
|
### 1. 纯 TS 引擎 + 确定性种子流
|
||||||
- `src/renderer/game/` 无 React/DOM import,vitest 直测。
|
- `src/renderer/game/` 无 React/DOM import,vitest 直测;引擎域零 `Math.random`(真实存在 0 处,唯一播种走 `RngHub.rollSeed()`)。
|
||||||
- sfc32 随机种,同 seed 全程重放;**金钟罩**=3 seed×3 档时长(47/100/180年)指纹固化。
|
- sfc32 随机种,同 seed 全程重放;**双金钟罩** = 3 seed × 3 档(47/100/180 年)× 两条长跑(冻结世界 + 自动 resolve 现实世界)= 18 指纹。
|
||||||
- **为什么**:模拟器平衡调参需要"可复现";金钟罩把"改坏了确定性"变成"一秒red"。
|
- **为什么**:平衡调参要"可复现";且 0.1.20 审计发现"直调冻结世界"的指纹锁的是事件流静止的假样本——补第二条 resolved 长跑才算真正锁住"现实"。
|
||||||
|
|
||||||
### 2. GameClock 七相位
|
### 2. GameClock 七相位 + clocks 注册表
|
||||||
- 月度 phase:production→aging→cultivation→missions→events→diplomacy→epilogue;
|
- 月度 phase:production→aging→cultivation→missions→events→diplomacy→epilogue;**新系统 = 注册一行,禁手改 `advanceMonth`**。
|
||||||
- 年首三钩子:婚配→岁贡→族簿。新系统=注册一行,禁手改 `advanceMonth`。
|
- 为什么:0.1.6 前每个 tick 体内散着调用,加系统必乱序→破坏随机→金钟罩红。
|
||||||
- **为什么**:0.1.6 前每个 tick 体内散着调用,加系统必乱序→破坏随机→金钟罩红。
|
|
||||||
|
|
||||||
### 3. 插件协议(0.1.8)
|
### 3. 事件闸(0.1.20 定稿)
|
||||||
- 万物皆是插件:系统/数据包/事件池统一 Manifest;`engine/pluginManager.ts` 安装管线(依赖校验/异常回滚/追踪型上下文)。
|
- `fire(w,id,priority)` 是 pending **唯一**写入入口;高优可顶替(被顶替者入 `eventQueue` 月月兑现);普通被占放弃。
|
||||||
- 三核心插件(Systems/Data/Events)protected 常驻。
|
- **为什么**:0.1.20 审计实证——raid 名义 0.03/月、实际落地 18%(11 命中仅 2 落地),日常事件每月占闸 70~86%,军事线被打 1/5 折扣。且传薪曾同年重复 12 次、渡劫直写会覆盖既有 pending。事件闸语义必须文档化。
|
||||||
- **为什么**:玩法内容增量的"可插拔出口";事件多池让第三方能注入事件。
|
|
||||||
|
|
||||||
### 4. 存档分层
|
### 4. WorldSim 世界自演进(0.1.14+ 的 4 层递进)
|
||||||
- metona-sqlark 在 renderer(OPFS)+ {Slots} {迁移链};**v1→v2 迁移管线**(0.1.9)。
|
- ① 市场实体化(真库存/供需/NPC/玩家回写)→ ② NPC 行为战略(姿态/景气/恩怨网/蝴蝶效应)→ ③ 世纪弧 era → ④ **era↔景气双向闭环**(世界温度反馈转移概率)。
|
||||||
- **为什么**:浏览器持久化天生平台限制;预置迁移链防未来表变炸档。
|
- **为什么**:模拟器世界"只单方向驱动玩家"会像纸片;双向因果(玩家动作→市场→时代→NPC 行为→玩家的外交与局势)才是"自进化"的真义。`worldsim-data.ts` 是数值唯一权威(含 POOL_BASE/ERO_CONF/REGION_TIDE),调平衡改它不动流程。
|
||||||
|
|
||||||
### 5. UI 惯例
|
### 5. 引擎-表现双通道
|
||||||
- zustand `revision++` 是刷新惯例;`facade` 必须 openState/startNewGame 赋值;
|
- 引擎语义事件经 `World.out`(WorldEventBus):onLog/onChronicle/onBattle/pending/gameOver/yearPaper/**onFx**(0.1.18 语义特效);UI `makeBus` 桥接(音效/日志/粒子)。特效发射零 rng(0.1.18 明训:**特效随机归渲染层,否则金钟罩崩**)。
|
||||||
- 警讯徽章(urgency)与引导任务(guide)做成 engine 侧纯函数,UI 只渲染。
|
|
||||||
|
### 6. 存档策略:normalize 即迁移
|
||||||
|
- CURRENT_SCHEMA=2,0.1.14+ 全部新字段靠 `normalizeGameState` 幂等兜底(worldSim/era/prosperity/stance/worldAnnals…)+ `loadState` 过 `migrateIfNeeded`(TOO_NEW 抛 MigrationError)。
|
||||||
|
- **为什么**:v1→v2 后才真正需要"转换"的只有一次;其余靠兜底。升 v3 无真实转换内容(每轮审计结论一致:**不升**)。
|
||||||
|
|
||||||
|
### 7. 线程定论(0.1.21 实测)
|
||||||
|
- 引擎 = renderer 主线程同步,`advanceMonth` 2160 月平均 **0.05ms/tick**;拖帧热点是 UI 全量渲染 + 存档 stringify(已修:精订阅/节流/截断)。
|
||||||
|
- **为什么不做 Worker**:0.05ms 换线程是负收益工程;真问题(UI 渲染、OPFS 成本)已定位修复。
|
||||||
|
|
||||||
## 四、踩过的坑(高价值教训)
|
## 四、踩过的坑(高价值教训)
|
||||||
|
|
||||||
1. **金钟罩盲区**:560 月(47 年)只能听见"中期",看不见"晚期"——0.1.10 之前全灭崩溃藏在这里。→ 教训:**确定性验证要覆盖寿命尺度**(现在三档到 180 年)。
|
1. **金钟罩盲区**:560 月(47 年)听不见 180 年;且"直调冻结世界"指纹锁的是假样本(事件闸永驻、raid 永不落地)。→ 教训:**确定性验证要覆盖寿命尺度 + 现实长跑**(0.1.20 双基线)。
|
||||||
2. **渡劫误压制**:eventRoll 一处"自动压制"让 qi8→筑基永不可达(境界峰恒炼气)。→ 教训:**自动回退/悬空逻辑必须单测"有人一直不响应"**。
|
2. **era flow 权重和=1 → 无延续档**:`roll<acc` 恒真,第一年即转移,ERA_DURA 全死码——"看着合理其实错"。→ 教训:**概率转移表永远留"延续"权重**(和<1),测试断言 sum<1。
|
||||||
3. **大比缺 once**:整年刷 12 场,收益通胀。→ 教训:周期性动态事件**生来就要考虑 once/年度封缄**。
|
3. **潮汐供给符号反向**:`1-(tide-1)*k` 在潮高 1.35 时供给 ×0.895(注释承诺 ×1.3),末法反而供给过剩。→ 教训:**每个乘子写测试断言方向**(tide>1 必丰)。
|
||||||
4. **flag 键膨胀**:auction-{year} 等永不清理,180 年挂 400 键。→ 教训:**任何按年份生成的键都要有剪枝数**(现在 3 年)。
|
4. **duplicate 时轮/双注册**(0.1.15):restore 重建世界不重建内核 → 时钟注册 12→24 跑双倍。→ 教训:单例内核 + 回档测试。
|
||||||
5. **UI 层"状态反直觉"**:死者显示"闭关/养伤"——直觉信任崩塌。→ 教训:**UI 状态必须与领域语义严格对齐**(dead 分支显式)。
|
5. **事件闸竞态**(0.1.20):单闸无条件 return → raid/军事线被日常事件饿死;被吞不写 CD 下月重试(白烧 rng 不落地)。→ 教训:**同 tick 多事件系统必须做优先级评测**。
|
||||||
6. **修改覆盖事故**(爸爸点名):批量 python 替换命中旧文本 / `git checkout` 回滚误伤已修复文件 / 链式 replace 生成重复属性——多起"改着改着把之前修复覆盖了"。→ 教训:**修改纪律**——原子提交、替换三步断言、禁整文件 checkout、小步绿灯再前进(详见 AGENTS.md「修改纪律」)。
|
6. **每 tick 全量存档**(0.1.20):autosaveEvery 死代码 + saveChronicle O(N) 逐条查询 → 2160 月档每 tick 数千 OPFS。→ 教训:**autosave 节流必须真实接线;冗余表用增量写**。
|
||||||
6. **模块单例纪律**:MetonaSqlark 同库同 tab 一次连接(ARIA_LOCKED);spouse 竞态防了。→ 教训:**存储/稀罕资源一律单例**。
|
7. **修改覆盖事故**(爸爸点名):批量 python 替换命中旧文本 / `git checkout` 回滚误伤 / 链式 replace 重复属性。→ 教训:**修改纪律**(原子提交、替换三步断言、禁整文件 checkout、小步绿灯再前进)。
|
||||||
|
8. **模块单例纪律**:MetonaSqlark 同库同 tab 一次连接(ARIA_LOCKED)→ 单例存取。
|
||||||
|
|
||||||
## 五、平衡哲学(玩起来正确的普适原则)
|
## 五、平衡哲学(玩起来正确的普适原则)
|
||||||
|
|
||||||
- **修炼快感 > 真实性**:宁可让"凡人百岁筑基"变成"30岁炼气、50岁筑基、百岁金丹",不要按修真文教条拉长。
|
- **修炼快感 > 真实性**:30 岁炼气、50 岁筑基、百岁金丹,不按修真文教条拉长。
|
||||||
- **世代窗口**:关键体验"每代 25-30 年",一回合 1 月,推两百步就能看到"代际更替"。
|
- **世代窗口**:每代 25-30 年,一回合 1 月,两百步见代际更替。
|
||||||
- **失败必须有出口**:渡劫失败只跌伤不太狠(重伤/跌落为主,陨落限高阶);事件悬置自动压制不锁死。
|
- **失败必须有出口**:渡劫失败跌伤为主(陨落限高阶);事件悬置自动压制不锁死;断供拒单只到 0.35 且有世界供给回填(不造死局)。
|
||||||
- **漏斗要"花钱有去处"**:后期灵石通胀是 0.1.10 才加拍卖来回收——任何资源曲线都要有消耗侧。
|
- **资源漏斗有出口**:修为耗草(0.1.16)、兽核炼器、灵石养丹/调停/援兵——每个产出都有消耗侧;**市场超卖有反噬**(谷贱伤农)。
|
||||||
|
- **世界不是背景板**:玩家的交易/战争/结盟都会改变行情、NPC 势力与时代走向——决策有代价才有味道(0.1.17-0.1.21 一以贯之)。
|
||||||
|
|
||||||
## 六、已知技术债(诚实清单)
|
## 六、已知技术债(诚实清单)
|
||||||
|
|
||||||
1. `realms.ts` 的 `expBase/expGrowth/maxRealmExp` 曲线未参与计算(历史摆设,勿信勿用)。
|
1. `realms.ts` 的 `expBase/expGrowth/maxRealmExp` 未参与计算(历史摆设,勿信勿用)。
|
||||||
2. GameFacade `act` 目录部分 act 只走 `actDirect` fallback(少 4 项),若未来全走 facade 需补齐 `member.meditate` 等。
|
2. GameFacade act 通道与面板直调并存(**仲裁结论**:直调是事实通道、act 为测试/自动化通道——actDirect 已补齐 24 项等价映射)。
|
||||||
3. `npc.power` 目前纯展示(不参与战斗结算)。
|
3. `guide.ts`(引导任务)只做 UI 条,钩子目标点不完("提示"非"强制")。
|
||||||
4. 引导任务(guide.ts)只做 UI 条,钩子目标点不完(未联动高亮/自动转跳——是"提示"不是"强制")。
|
4. `family.flag` 长线键已有 3 年剪枝、但 `state.missions/missionIds` 只增不减(未剪枝)。
|
||||||
5. 行列 flag `family.flag` 仍在长线漂移;`state.missions`/`missionIds` 只增不减(未剪枝)。
|
5. NPC 四家是固定成分(无"覆灭/新贵补位"——0.1.19 留作 0.1.22+ 候选);附庸/吞并仅 UI"衰"标记。
|
||||||
|
6. `worldsim` 的能力卡开关无独立钩子(viaCap 恒真已注册,实际不可关)——如需可关需重构。
|
||||||
|
|
||||||
## 七、如何开始修改(给下一个智能体的路径)
|
## 七、如何开始修改(给下一个智能体的路径)
|
||||||
|
|
||||||
```
|
```
|
||||||
1. 读 AGENTS.md(红线)→ 2. 读本文件(意图)→ 3. 跑 npm test & typecheck 确认绿
|
1. 读 AGENTS.md(红线)→ 2. 读本文件(意图)→ 3. 跑 npm test & typecheck 确认绿
|
||||||
→ 4. 改引擎:先改数据(data/)再改逻辑,小步跑金钟罩;改结构:注册进 clocks/plugins
|
→ 4. 改引擎:先改数据(data/ 或 sim/worldsim-data.ts)再改逻辑,小步跑金钟罩;
|
||||||
→ 5. 改 UI:先改 store(revision)再改组件;纯逻辑放 game/core 可测
|
改结构:注册进 clocks/plugins;世界循环参数唯一权威 = worldsim-data.ts
|
||||||
→ 6. 加测试:金钟罩三档不动,新增用例挂 tests/audit-fix-0.1.x.test.ts
|
→ 5. 改 UI:先改 store(revision)再改组件;纯逻辑放 game/engine 可测
|
||||||
→ 7. 提交前:npm test + typecheck + (GUI 冒烟需 WSLg 在线)+ 更新 README/PROJECT_MEMORY/AGENTS
|
→ 6. 加测试:双金钟罩不动,新增用例挂 tests/xxx-0.1.x.test.ts(按主题命名)
|
||||||
|
→ 7. 提交前:npm test + typecheck + (GUI 冒烟需 WSLg 在线)+ 更新三份文档
|
||||||
```
|
```
|
||||||
|
|
||||||
**一句话原则**:先复现、再小改、后金钟罩。改坏确定性比改错玩法更危险。
|
**一句话原则**:先复现、再小改、后金钟罩。改坏确定性比改错玩法更危险;改数值去 worldsim-data,改流程去 clocks,改事件去 fire()。
|
||||||
|
|||||||
Reference in New Issue
Block a user