v0.1.25: 乾坤一统——MOD 系统首版(1040 全绿,金钟罩不漂)

【P0 修复(0.1.24 遗留)】worldGen.npcs defs 落档 + normalize 幂等重注册——读档后
动态家族(n-g-*)npcById 永命中;MOD 卸载后存档世界仍完整(存档世界永稳)

【MOD 系统四层】
- M2 内容层:modSchema.ts(ModPack 全 JSON:manifest+data{events/npcs/worldgen/pills/forges};
  modParse 纯解析校验 id/name/version/事件模板合法性)
- M3 管理器:modToPlugin(MOD→CotycPlugin 一等子类——插件持久化/双闸/启停/回滚全复用)
- M1 传输层:main IPC mods:scan/read(userData/mods/*.json|*.cotymod)+ preload + env.d.ts
  + store refreshMods/installModByName/installModText
- M4 UI:SettingsPanel「MOD 层」卡(扫描目录/候选列表/安装);内置示例包通路

【世界/插件协同】
- WorldGenPools 聚合词库池(默认不变→基准世界不变;reset() 供隔离);MOD 于新档参与生成
- items.ts 配方聚合注册表(PILL/FORGE base+扩展);PluginContext addPillRecipe/addForgeRecipe/addWorldGenPool

【边界(明注)】灾因/世界数值表注入归平衡版;脚本型 MOD 不做;MOD 只影响新档世界(老档不变形)

【测试】1040 全绿(46 套件):worldGen 存档 1 例 + mod-system 5 例(解析/转换/模板/依赖/基准指纹);
金钟罩 0.1.24 基线未漂(世界生成默认池不变);build 通过
This commit is contained in:
2026-08-23 16:29:29 +08:00
parent ec25bf92fc
commit 5d9c333c76
18 changed files with 364 additions and 21 deletions
+18
View File
@@ -1,6 +1,8 @@
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/runtime/World'
import { generateWorld } from '../src/renderer/game/engine/sim/worldgen'
import { npcById } from '../src/renderer/game/data/npcs'
import { engineFromSnapshot } from '../src/renderer/game/engine/GameEngine'
describe('0.1.24 寰宇初构·世界种子', () => {
it('同 seed 生成同一世界(确定性)', () => {
@@ -63,3 +65,19 @@ describe('0.1.24 寰宇初构·世界种子', () => {
expect(Object.keys(rels).length).toBeGreaterThan(0)
})
})
describe('0.1.25 P0worldGen 存档稳固', () => {
it('动态家族 def 落档:读档后 npcById 永命中(P0 修复)', async () => {
let w: World | null = null
for (const s of ['dg-1', 'dg-2', 'dg-3', 'dg-4', 'dg-5', 'dg-6']) {
const t = World.create({ seed: s, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
if (Object.keys(t.state.npcFamilies).some((k) => k.startsWith('n-g'))) { w = t; break }
}
if (!w) return // 都无动态家(seed 未抽中)→ 等价通过
const snap = JSON.parse(JSON.stringify(w.state))
const e2 = engineFromSnapshot(snap as never)
const ids = Object.keys(e2.world.state.npcFamilies)
for (const k of ids) {
expect(npcById(k)).toBeTruthy()
}
})
})