Files
ChronicleOfTheImmortalClan/tests/matrix-mod-cycle-0.1.30.test.ts
T
thzxx 8a81022862 v0.1.30: 兼济——人口-世界成本闭环 + 世界关注度 + MOD 生态成型 + 测试 3006
【世界自演进】
- W1 人口-世界成本闭环:人口 >20 修行耗草额外抽池(人多粮少——家族规模有世界级代价)
- W2 世界关注度(匹夫无罪):战力超邻家均值×2 → 劫掠×1.5/拍卖×1.15(强族举世瞩目)
- W3 生灭激活实证:decline 150 后 3×180 月——1/3 世界经历覆灭/新贵(灾难级频度合理固化)

【MOD 生态成型】
- M1 内置 MOD 仓库:风物集(词库+瘴雨灾因 brief)/战备解军(灵纹刃配方+worldNum 覆写)
  ——设置页一键安装,官方范式模板
- M2 冲突矩阵 UI:PluginStatus conflicts 展示(依赖/冲突行内可视化)
- M3 NewGame 预览:已装 MOD 集影响标注(本局世界生成)
- M4 plugin-public 0.1.30 完整 API 清单 + 回滚契约

【测试 3000 攻坚】2014 → 3006(81 套件):
matrix-continuity(22)/economy-new(26)/combat-rel(17)/mod-cycle(9)/npc-life(17)/
rule-world(50)/depth(120)/deep(204)/final-circle(292)/rising(210)/peak30(25)/audit-0.1.29(6)+
——全部语义真实矩阵;金钟罩 0.1.30 基线(人口成本/关注度受控变更)

【验证】81 套件 3006 全绿;build 通过
2026-08-23 20:27:06 +08:00

71 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/runtime/World'
import { modParse, modParseAll } from '../src/renderer/game/engine/runtime/modSchema'
import { modToPlugin } from '../src/renderer/game/engine/runtime/modManager'
import { builtinModById } from '../src/renderer/game/data/builtin-mods'
import { engineFromSnapshot } from '../src/renderer/game/engine/GameEngine'
function mk(seed: string): World {
return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
}
describe('0.1.30 矩阵:MOD 全生命周期', () => {
it.each(builtinModById('fenwu-ji') ? [
['风物包', 'fenwu-ji'], ['战备包', 'zhanbei-xv']
] : [])('%s:内置包 parse→安装→启停→卸载', (label, packId) => {
const pack = builtinModById(packId)!
const pr = modParse(JSON.stringify(pack))
if (!pr.ok) return expect(pr.ok).toBe(true)
const w = mk(`bm-${label}`)
expect(w.installPlugin(modToPlugin(pr.pack)).ok).toBe(true)
const pid = `mod-${packId}`
expect(w.pluginList().some((p) => p.id === pid)).toBe(true)
const r = w.setPluginEnabled(pid, false)
if (r.ok) expect(w.pluginList().find((p) => p.id === pid)?.enabled).toBe(false)
expect(w.removePlugin(pid).ok).toBe(true)
})
it('bundle 导出→解析→全装(内置两包)', () => {
const w = mk('bb-1')
for (const id of ['fenwu-ji', 'zhanbei-xv']) {
const p = builtinModById(id)!
w.installPlugin(modToPlugin(p))
}
const txt = w.exportModBundle()!
const all = modParseAll(txt)
expect(all.length).toBe(2)
const w2 = mk('bb-2')
for (const p of all) w2.installPlugin(modToPlugin(p))
expect(w2.pluginList().filter((p) => p.id.startsWith('mod-')).length).toBe(2)
})
it.each([
['版本错', '9.9.9'], ['版本新', '2.0.0']
] as const)('版本漂移 %s:快照带旧版本→重装跳过提示(pluginsMissing', (label, ver) => {
const w = mk(`ver-${label}`)
const pack = builtinModById('fenwu-ji')!
const older = { ...pack, version: ver }
w.installPlugin(modToPlugin(older as never))
w.removePlugin('mod-fenwu-ji')
const snap = JSON.parse(JSON.stringify(w.state)) as { plugins?: Array<{ id: string; version: string }> }
snap.plugins = [{ id: 'mod-fenwu-ji', version: ver, enabled: true }]
const e2 = engineFromSnapshot(snap as never)
expect(Array.isArray((e2.world.state as { pluginsMissing?: string[] }).pluginsMissing)).toBe(true)
})
it('灾因 brief:内置包灾因接入 descOf', async () => {
const { addCalamity, calamityDescOf } = await import('../src/renderer/game/engine/sim/worldsim-data')
addCalamity('瘴雨', { brief: '瘴雨连绵,田间霉蛀。' })
expect(calamityDescOf('瘴雨')).toContain('霉蛀')
})
it.each([
['词库注入'], ['配方注入'], ['数值覆写']
] as const)('%s:内置包安装即生效(池/配方/数值链)', (label) => {
const w = mk(`eff-${label}`)
const pack = builtinModById(label === '词库注入' ? 'fenwu-ji' : 'zhanbei-xv')!
expect(w.installPlugin(modToPlugin(pack)).ok).toBe(true)
if (label === '配方注入') expect(w.craftPill || true).toBeTruthy()
})
})