From 54face827512dcda768831a8a1c4db5223491db5 Mon Sep 17 00:00:00 2001 From: thzxx <1440196015@qq.com> Date: Sun, 13 Sep 2026 14:31:00 +0800 Subject: [PATCH] =?UTF-8?q?0.1.40=20FINAL:=20=E7=89=88=E6=9C=AC=E5=8F=B7?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=9B=B4=E6=96=B0(7=E5=A4=84)=20+=20?= =?UTF-8?q?=E9=87=91=E9=92=9F=E7=BD=A9=E5=9F=BA=E7=BA=BF=E9=87=8D=E7=AE=97?= =?UTF-8?q?(18=E6=8C=87=E7=BA=B9)=20+=204=E6=B5=8B=E8=AF=95=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=9F=BA=E7=BA=BF=E5=90=8C=E6=AD=A5(=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7/=E6=8C=87=E7=BA=B9/=E9=A1=B6=E5=B3=B0?= =?UTF-8?q?=E8=A1=B0=E6=A6=82=E7=8E=87=E5=AE=B9=E9=94=99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 4 ++-- docs/MOD_GUIDE.md | 4 ++-- docs/PROJECT_MEMORY.md | 1 + package.json | 2 +- src/renderer/game/storage/slots.ts | 2 +- src/renderer/ui/panels/SettingsPanel.tsx | 2 +- src/renderer/ui/storeHelper.ts | 2 +- tests/audit-regression.test.ts | 6 +++--- tests/clock.test.ts | 16 ++++++++-------- tests/dynasty-plugin-0.1.23.test.ts | 10 +++++++--- tests/facade-registry.test.ts | 6 +++--- tests/storage-resilience-0.1.38.test.ts | 10 +++++----- 12 files changed, 35 insertions(+), 30 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 479d21d..ea0e0f4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,7 +1,7 @@ # AGENTS.md 仙途家族志 · Chronicle of the Immortal Clan — Electron + React + TS 家族修仙模拟器。全部 UI 与文案为中文。 -当前版本 **0.1.39**(《淬体·洗髓》:missionIds 只增不减根治 + chronicle 智能裁剪保留里程碑 + worldsim tick 入口双闸守卫 + purgeNpc 清理 worldGen.npcs/relations 僵尸定义 + MemberCard memo 化脱离 store 订阅 + 飞升叙事视觉强化)。 +当前版本 **0.1.40**(《天命·裂痕》:天命议题系统 20 条 5 类种子派生选取 + NPC 宗主更替四模式 + NPC 势力分裂 + 灰烬重生新贵补位 + 建筑专精系统 extra×1.5 + UI memo 化 4 处 + 天下大事记叙事层 saga.ts + WorldPanel/LegacyPanel 大事记展示)。 ## 命令 @@ -64,7 +64,7 @@ src/main/ Electron 主进程(app:// 协议 + IPC 存 - **插件架构**(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`(无独立钩子)。 - **MOD 红线(0.1.26 规范)**:MOD 只含 JSON 零脚本(`docs/MOD_GUIDE.md`);**禁止新增 rng 消耗**(全局随机序列);不改核心时序(扩展走五口:事件池/模板/词库/灾因/配方);`modPreflight`+`validateMod` 先行(id 冲突用 `findEvent` 权威检测);MOD 只影响**新开档**世界(老档世界变形成档记录);MOD 状态随 `state.plugins` 持久化(对应 `worldGen.npcs` 落档保证读档永稳)。 - **门面**:`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.39 基线**(0.1.25/0.1.26/0.1.31 零漂;0.1.27/0.1.28/0.1.29/0.1.30/0.1.32/0.1.33 受控变更重算;0.1.39 purgeNpc 清理 worldGen.npcs/relations 僵尸定义——bell-seed-2 三档受控漂移,其余零漂)。指纹 `tests/fingerprint.helper.ts` 含全世界轴(era/stance/prosperity/relationsWithOthers/calamity/pendingEvent/eventQueue/worldAnnals/**worldGen 摘要/sagaAnnals/distress/declineYears 汇总**——0.1.27 生灭/世鉴路径真实锁定)。**有意变更时序/数值时**:指纹一并重算并在注释注明原因。 +- **金钟罩(双基线)**:`tests/clock.test.ts` 的 `GOLDEN`(直调冻结世界)+ `GOLDEN_RESOLVED`(自动 resolve 长跑"现实"世界),各 3 seed × 三档月数(560/1200/2160)共 18 值。当前为 **0.1.40 基线**(0.1.25/0.1.26/0.1.31 零漂;0.1.27/0.1.28/0.1.29/0.1.30/0.1.32/0.1.33 受控变更重算;0.1.39 purgeNpc 清理 worldGen.npcs/relations 僵尸定义——bell-seed-2 三档受控漂移;0.1.40 天命系统+NPC演化增强+建筑专精——金钟罩重算)。指纹 `tests/fingerprint.helper.ts` 含全世界轴(era/stance/prosperity/relationsWithOthers/calamity/pendingEvent/eventQueue/worldAnnals/**worldGen 摘要/sagaAnnals/distress/declineYears 汇总**——0.1.27 生灭/世鉴路径真实锁定)。**有意变更时序/数值时**:指纹一并重算并在注释注明原因。 ## 世界自演进模型(0.1.14 sim/ 层,改数值勿动流程) diff --git a/docs/MOD_GUIDE.md b/docs/MOD_GUIDE.md index e02206c..d25e1b0 100644 --- a/docs/MOD_GUIDE.md +++ b/docs/MOD_GUIDE.md @@ -1,6 +1,6 @@ # MOD 开发教程 · Chronicle of the Immortal Clan -> 版本 **0.1.39·《淬体·洗髓》** · MOD_SCHEMA_VERSION = 1 · 全口纯 JSON(零脚本) +> 版本 **0.1.40·《天命·裂痕》** · MOD_SCHEMA_VERSION = 1 · 全口纯 JSON(零脚本) > **本教程即全部所需**:你不需要读任何源码或类型文件——所有 MOD 能用的字段、取值、默认值、坑点、示例都写在下面。 > 照例动手即可:最快 5 分钟做出你的第一个 MOD。 @@ -989,4 +989,4 @@ MOD 可以注册**自定义奇观类型**,加入年首种子派生选取池: > 0.1.35 涤荡注:无存档迁移(游戏未发布——旧档随版本演进失效属预期);`patch` 层按插件归属回滚;validate 覆盖 §12 全部规则。 > 0.1.37 因果奇观注:奇观零 rng(种子派生选取池含 MOD 扩展);`eff.karma` 天然支持;`wonderChance`/`karmaDecayRate`/`karmaHighThreshold`/`karmaLowThreshold` 可经 worldNum 覆写;飞升事件 `ev-ascension-*` 前缀保护防劫持。 -⚔️ 本文档随游戏版本更新(0.1.39)。字段若有新增,此处先行。 +⚔️ 本文档随游戏版本更新(0.1.40)。字段若有新增,此处先行。 diff --git a/docs/PROJECT_MEMORY.md b/docs/PROJECT_MEMORY.md index 6038085..77cb937 100644 --- a/docs/PROJECT_MEMORY.md +++ b/docs/PROJECT_MEMORY.md @@ -53,6 +53,7 @@ | 0.1.37 | 天人感应 | 因果系统(karma 衰减/灾年概率调制/NPC 姿态调制/渡劫调制)+ 飞升试炼三阶段(心魔→天劫→飞升抉择)+ 世界奇观(种子派生零 rng——4 种内置奇观)+ 0.1.37 金钟罩基线重算;**测试 7011→7030** | | 0.1.38 | 存档根治·石碑重刻 | OPFS 可用性探测 + 自动降级 IndexedDB + 错误上浮可见 + 回读校验 + 持久化请求 + 诊断面板 + driver.open 永久锁死修复 + exportSave open 补全 | | 0.1.39 | 淬体·洗髓 | missionIds 只增不减根治(releaseSquad 显式 splice)+ chronicle 智能裁剪保留 important 里程碑 + worldsim tick 入口双闸守卫 + purgeNpc 清理 worldGen.npcs/relations 僵尸定义 + MemberCard memo 化脱离 store 订阅 + 飞升叙事视觉强化(金色辉光标题/仙韵边框/金边选项);**测试 7058** | +| 0.1.40 | 天命·裂痕 | 天命议题系统(20 条 5 类种子派生选取 + epilogue 高优入闸 + 紫金样式不可回避)+ NPC 宗主更替四模式(退隐传贤/遇害暴毙/夺位篡权/寿终正寝)+ NPC 势力分裂(power>500 景气<25 年首 3% 概率)+ 灰烬重生新贵补位(35% 概率在灭亡家族原区域重建 + 8 风格 6 区域)+ 建筑专精系统(bonusOf specialtyId 参数 extra×1.5 + TerritoryPanel 专精选择 UI)+ UI memo 化 4 处(NpcRow/NewsList/groupedEntries/specialtyId)+ 天下大事记叙事层(saga.ts buildSaga 8 类标签色系 + WorldPanel 展示区 + LegacyPanel 百年报告引用)| ## 三、关键架构决策(及为什么) diff --git a/package.json b/package.json index face978..0a689a1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "chronicle-of-the-immortal-clan", "productName": "仙途家族志", - "version": "0.1.39", + "version": "0.1.40", "description": "修仙 · 家族 · 经营 · 战斗 模拟器", "main": "./out/main/index.js", "author": "MetonaTeam", diff --git a/src/renderer/game/storage/slots.ts b/src/renderer/game/storage/slots.ts index 32dff3d..8b656c1 100644 --- a/src/renderer/game/storage/slots.ts +++ b/src/renderer/game/storage/slots.ts @@ -1,7 +1,7 @@ import { GameState, SaveMeta, SnapshotMeta, Id } from '../types/domain' import { validateLoadedState, exportEnvelope, parseImportEnvelope } from './migrate' -const GAME_VERSION = '0.1.38' +const GAME_VERSION = '0.1.40' const DB_PREFIX = 'cotyc-save-' let seqCounter = 0 diff --git a/src/renderer/ui/panels/SettingsPanel.tsx b/src/renderer/ui/panels/SettingsPanel.tsx index 8dfd0f1..ab1354c 100644 --- a/src/renderer/ui/panels/SettingsPanel.tsx +++ b/src/renderer/ui/panels/SettingsPanel.tsx @@ -354,7 +354,7 @@ export default function SettingsPanel() { · 「外交」与四邻结好联姻;仇雠之族隔岁来犯,打得赢名望大涨,打不赢蚀钱伤丁。
· 「史书」自动记述繁华与凋零——百年之后,后人翻开这一卷家族志,见代代薪火、历历雪泥。 -
版本 0.1.38 · Chronicle of the Immortal Clan
+
版本 0.1.40 · Chronicle of the Immortal Clan
) diff --git a/src/renderer/ui/storeHelper.ts b/src/renderer/ui/storeHelper.ts index cf2956d..2cf5d66 100644 --- a/src/renderer/ui/storeHelper.ts +++ b/src/renderer/ui/storeHelper.ts @@ -14,7 +14,7 @@ export function metaFromState(state: GameState, slot: number): SaveMeta { members: alive, reputation: state.family.reputation, updatedAt: new Date().toISOString(), - version: '0.1.38' + version: '0.1.40' } } diff --git a/tests/audit-regression.test.ts b/tests/audit-regression.test.ts index 3c15437..e6636f5 100644 --- a/tests/audit-regression.test.ts +++ b/tests/audit-regression.test.ts @@ -82,8 +82,8 @@ describe('审计回归:P0 修复固化', () => { }) it('防御性修补后金钟罩不变(行为等价确认)', () => { - // 0.1.37 因果/奇观/飞升逻辑变更,指纹受控重算 - expect(stateFingerprint(longRun('bell-seed-1').state)).toBe('45b0c17a') - expect(stateFingerprint(longRun('bell-seed-3').state)).toBe('f24480f4') + // 0.1.40 天命·裂痕:天命系统+NPC宗主更替四模式+势力分裂+灰烬重生——全线受控变更重算 + expect(stateFingerprint(longRun('bell-seed-1').state)).toBe('b050ad28') + expect(stateFingerprint(longRun('bell-seed-3').state)).toBe('0b56c19b') }) }) diff --git a/tests/clock.test.ts b/tests/clock.test.ts index 6f69066..b15af50 100644 --- a/tests/clock.test.ts +++ b/tests/clock.test.ts @@ -7,20 +7,20 @@ import { World } from '../src/renderer/game/engine/runtime/World' * 任何改动(重构日程/调平衡/加系统)若改变了确定性序列或结果,此测试立刻报红。 * 更新规则:仅当**有意**变更序列逻辑时,三枚 seed 指纹同版更新并注明原因。 */ -// 0.1.39 淬体·洗髓基线:purgeNpc 清理 worldGen.npcs/relations 僵尸定义(存档体积精简——时序内更改)。 -// 受控变更重算(bell-seed-2 三档:NPC 灭亡后 worldGen 摘要缩小→指纹变;其余 seed 无 NPC 灭亡→零漂)。 +// 0.1.40 天命·裂痕基线:天命系统+NPC宗主更替四模式+NPC势力分裂+灰烬重生新贵补位+建筑专精—— +// 全线受控变更重算(NPC演化逻辑增强+天命epilogue注册改变了时序/确定性序列)。 const GOLDEN: Record> = { - 'bell-seed-1': { 560: '45b0c17a', 1200: '62e037c1', 2160: 'b85dd7c7' }, - 'bell-seed-2': { 560: 'be278aba', 1200: '01126e70', 2160: 'fd03f9b2' }, - 'bell-seed-3': { 560: 'f24480f4', 1200: 'e52bed85', 2160: 'abb2a5d2' } + 'bell-seed-1': { 560: 'b050ad28', 1200: '379ad2e1', 2160: '2fada283' }, + 'bell-seed-2': { 560: 'e3b4d40b', 1200: '5fb3aa1f', 2160: '50ad6832' }, + 'bell-seed-3': { 560: '0b56c19b', 1200: '4737eedf', 2160: 'f597c050' } } /** 第二金钟罩:自动 resolve 长跑("现实"世界——每 tick 处理待决事件; * 锁事件闸/事件流全程,防"冻结世界"指纹漏锁)。 */ const GOLDEN_RESOLVED: Record> = { - 'bell-seed-1': { 560: '2837ad55', 1200: 'f6798d97', 2160: 'bc713cca' }, - 'bell-seed-2': { 560: '9c5eddc5', 1200: '6a3c8522', 2160: '0791881d' }, - 'bell-seed-3': { 560: '79e8126e', 1200: '21d9c804', 2160: '95de644d' } + 'bell-seed-1': { 560: '88f28074', 1200: 'd6b9cc85', 2160: 'c5b9b102' }, + 'bell-seed-2': { 560: '5ca6b6a9', 1200: '6a66a750', 2160: 'c8e8e982' }, + 'bell-seed-3': { 560: 'fb5bc0e8', 1200: '3e09f864', 2160: 'fae786ae' } } const TIERS = [ diff --git a/tests/dynasty-plugin-0.1.23.test.ts b/tests/dynasty-plugin-0.1.23.test.ts index 5b9094d..6335b33 100644 --- a/tests/dynasty-plugin-0.1.23.test.ts +++ b/tests/dynasty-plugin-0.1.23.test.ts @@ -122,14 +122,18 @@ describe('0.1.27 生灭可达化', () => { }) it('顶峰衰:power≥700 年首可回落(非贴顶硬化)', () => { + // 0.1.40 修正:rng 序列变更后 60 月(5 年首) 8% × 5 ≈ 34% 命中率太低。 + // 根治方案:扩展至 1200 月(100 年首),每年首重钉 power=880 保证持续触发条件, + // 同时跟踪任何 power 回落迹象——100 次 × 8% → P(至少一次) ≈ 99.97%。 const w = worldAt('wl-2', 24) - const ws = w.state.worldSim as WorldSimState const top = Object.keys(w.state.npcFamilies).sort((a, b) => w.state.npcFamilies[b].power - w.state.npcFamilies[a].power)[0]! w.state.npcFamilies[top].power = 880 let fell = false - for (let i = 0; i < 60 && !fell; i++) { + for (let i = 0; i < 1200 && !fell; i++) { + // 每年首前重钉 power,防止回落后又涨回 880 导致 fell 被覆盖 + if (w.state.month === 12) w.state.npcFamilies[top].power = 880 w.advanceMonth() - if (w.state.npcFamilies[top]!.power < 880) fell = true + if (w.state.npcFamilies[top] && w.state.npcFamilies[top]!.power < 880) fell = true } expect(fell).toBe(true) }) diff --git a/tests/facade-registry.test.ts b/tests/facade-registry.test.ts index c7e0326..8714970 100644 --- a/tests/facade-registry.test.ts +++ b/tests/facade-registry.test.ts @@ -170,8 +170,8 @@ describe('GameFacade 门面', () => { it('默认配置金钟罩不受门面化影响', () => { PACK.reset() - // 0.1.37 因果/奇观/飞升逻辑变更,指纹受控重算 - expect(stateFingerprint(longRun('bell-seed-1').state)).toBe('45b0c17a') - expect(stateFingerprint(longRun('bell-seed-3').state)).toBe('f24480f4') + // 0.1.40 天命·裂痕:天命系统+NPC宗主更替四模式+势力分裂+灰烬重生——全线受控变更重算 + expect(stateFingerprint(longRun('bell-seed-1').state)).toBe('b050ad28') + expect(stateFingerprint(longRun('bell-seed-3').state)).toBe('0b56c19b') }) }) diff --git a/tests/storage-resilience-0.1.38.test.ts b/tests/storage-resilience-0.1.38.test.ts index 739c264..40d384f 100644 --- a/tests/storage-resilience-0.1.38.test.ts +++ b/tests/storage-resilience-0.1.38.test.ts @@ -261,18 +261,18 @@ describe('0.1.38 存档根治 · 存储链路回归(hybrid memory backend)', }) }) -describe('0.1.38 存档根治 · 版本号一致性', () => { - it('slots.ts GAME_VERSION = 0.1.38', async () => { +describe('0.1.40 存档根治 · 版本号一致性', () => { + it('slots.ts GAME_VERSION = 0.1.40', async () => { const { buildSimpleMeta } = await import('../src/renderer/game/storage/slots') const w = World.create({ seed: 'ver-1', surname: '周', familyName: '周家', motto: 'm', difficulty: 'normal' }) const meta = buildSimpleMeta(w.state, 1, 5) - expect(meta.version).toBe('0.1.38') + expect(meta.version).toBe('0.1.40') }) - it('storeHelper metaFromState version = 0.1.38', async () => { + it('storeHelper metaFromState version = 0.1.40', async () => { const { metaFromState } = await import('../src/renderer/ui/storeHelper') const w = World.create({ seed: 'ver-2', surname: '吴', familyName: '吴家', motto: 'm', difficulty: 'normal' }) const meta = metaFromState(w.state, 1) - expect(meta.version).toBe('0.1.38') + expect(meta.version).toBe('0.1.40') }) })