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 通过
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
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()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user