v0.1.20: 万世无谬(第二轮全量审计歼灭,1011 测试+双金钟罩)

【事件闸(机制重锤)】
- fire(w,id,priority):单闸+优先级——高优(raid/渡劫/大比)顶替被占者、被顶替入 eventQueue 下月兑现不丢失;普通被占返回 false 调用方冷却(raid 被吞也写 CD)
- pending 唯一写入入口:渡劫/破境丹改走 fire(防覆盖丢弃);名宿传薪年锚 flag(防同年重复 12 次)
- applyEventChoice 前置校验 pendingEvent===id(陈旧 Modal 二次结算防线)

【世界模型四修(真·活世界)】
- era 延续档:flow 权重和<1(留白=续任)——盛世能撑 30 年而非固定 25
- 潮汐供给符号修正:灵涨万物丰(原实现反了)+tide 双界 clamp
- driftMarket 弱锚定:rebalance 0.1→0.025——供需/era/灾年真实撬动价格(原五池被锚死±5%)
- 断供/池底单常量 poolFloorPct=0.35(消灭禁买暗雷带)

【知识防线(审计虫洞修复)】
- 指纹扩展:era/stance/prosperity/relationsWithOthers/calamityLeft/pendingEvent 全入 hash
- 第二金钟罩 GOLDEN_RESOLVED:自动 resolve 长跑锁“现实”世界(原指纹锁的只是“事件流冻结”世界)

【性能与存储】
- 存档节流(疾12/常6/缓4,手动即时)+ saveChronicle O(N)→O(1) 单查增量写(2160 月档告别每 tick 数千 OPFS)
- battles≤220/chronicle≤520 截断(stringify 线性膨胀止血);startNewGame/openState 停 timer 摘旧 bus

【杂项】actDirect 对齐 ACT_CATALOG 全 24 项;about 三版本统一 0.1.20;kernel.bus 死总线删;seed 改 RngHub.rollSeed;normalize 补 eraStartYear/overflux/distress;WorldPanel 买卖条件反转修复;音效与视效同闸

【测试】1011 全绿(42 套件):audit-0.1.20 9 例(事件闸/传薪/二次结算/era延续/潮汐符号/断供一致/弱锚定/指纹敏感)
This commit is contained in:
2026-08-23 15:14:28 +08:00
parent e853fbdb71
commit be6f2f5fe7
22 changed files with 286 additions and 97 deletions
+16 -11
View File
@@ -61,18 +61,23 @@ export class SaveSlot {
}
async saveChronicle(chronicle: GameState['chronicle']): Promise<void> {
const driver = this.driver
for (const e of chronicle) {
try {
const exists = await driver.all<{ id: string }>(`SELECT id FROM chronicle WHERE id = ?`, [e.id])
if (exists.length > 0) continue
await driver.run(
`INSERT INTO chronicle (id, year, month, category, important, memberId, text) VALUES (?, ?, ?, ?, ?, ?, ?)`,
[e.id, e.year, e.month, e.category, e.important ? 1 : 0, e.memberId ?? null, e.text]
)
} catch {
// chronicle table redundancy is best-effort
try {
// 增量写:一次读全部已存 id(SET 判重),仅插新行——O(N) → O(1) 次查询
const rows = await this.driver.all<{ id: string }>(`SELECT id FROM chronicle`)
const existing = new Set(rows.map((r) => r.id))
for (const e of chronicle) {
if (existing.has(e.id)) continue
try {
await this.driver.run(
`INSERT INTO chronicle (id, year, month, category, important, memberId, text) VALUES (?, ?, ?, ?, ?, ?, ?)`,
[e.id, e.year, e.month, e.category, e.important ? 1 : 0, e.memberId ?? null, e.text]
)
} catch {
// row-level best-effort
}
}
} catch {
// 冗余表失败吞掉(主挡位用 snapshot 兜底)
}
}