Files
thzxx a99420da09 v0.1.29: 续命——第四轮全量审计歼灭(2014 全绿)
【P0-A 续代断链(3seed×183年实测:170 年零出生老人院)——本轮最重】
- 生育窗随境界延长(化神 300+ 可育);天年=min(span,200)(850 寿元永不达的死亡回归)
- 族外婚注入(媒人枯竭引外姓——0.1.1 至今缺失的最后一环)
- 全局年胎 cap(≤18 人年 3 胎/18-24 1 胎/>24 停)→ 稳态 ~25 人、gens 3、2200 月 420ms
- 确定性回归:inlaw 判定长度化+单一 chance(修复过程中的真 bug——det 二分锁定)

【P1 七件】legacypass 年锚(同一年 12 连发 224 次实测)/敌强度相对化(0.35+rel×0.55,
cap 2.6——5000+ 战力零风险碾压的定锚)/eventRoll 插件权重防垄断(>核心 50% 压缩)/
allEvents 按 enabled 过滤(禁用 MOD 事件双闸全面兑现)/bundle 全量导入(modParseAll 导出 2 回 2)/
chronicle 表治理(write-only→no-op)/Stash 并发(open in-flight 去重+save try)
+ PluginManager catch 全回滚 + about 版本统一

【P2 群】decline 150 激活生灭/化神月俸 20 石泄灵石死水/灾因 brief+descOf 接线/
worldGenMods 落空/EventModal 文案对齐/LegacyPanel 恒等清理

【测试】70 套件 2014 全绿(audit-0.1.29 六例:人口曲线/传薪年锚/强度公式/bundle 全量/异常回滚/灾因 brief);
【金钟罩】0.1.29 基线重算(续代/战斗/事件数值受控变更);build 通过
2026-08-23 20:14:42 +08:00

81 lines
3.5 KiB
TypeScript
Raw Permalink 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 { examplePlugin } from '../src/renderer/game/engine/runtime/demo-plugins'
import { eventRoll, findEvent } from '../src/renderer/game/engine/runtime/Systems/events'
function mk(seed: string): World {
return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
}
describe('0.1.29 续命·审计歼灭', () => {
it('P0-A 人口曲线:28 年后出生持续且稳定 ≤26 人(178 年样本)', () => {
const w = mk('pop-x1')
const t0 = Date.now()
for (let i = 0; i < 2200; i++) {
if (w.state.gameOver) break
w.advanceMonth()
while (w.state.pendingEvent) w.applyEventChoice(w.state.pendingEvent, 0)
}
const alive = Object.values(w.state.members).filter((c) => c.alive)
expect(alive.length).toBeLessThanOrEqual(28)
const gens = new Set(alive.map((c) => c.generation))
expect(gens.size).toBeGreaterThanOrEqual(2)
expect(Date.now() - t0).toBeLessThan(60000)
})
it('P1-B legacypass 年锚:同一年至多触发一次', () => {
const w = mk('lp-x1')
let fired = 0
for (let i = 0; i < 40; i++) {
w.advanceMonth()
if (w.state.pendingEvent === 'ev-legacypass') {
fired++
w.applyEventChoice(w.state.pendingEvent, 0)
}
}
expect(fired).toBeLessThanOrEqual(1)
// 40 月跨 4 年;y%8==4 年只有 1 个 → ≤1 次
})
it('P1-C 敌强度:相对化公式上界 2.6(不再 1.8 封顶撞维)', () => {
// 公式:min(2.6, max(0.5, 0.35 + rel*0.55))——rel 大时趋近 2.6,小值向下限 0.5
const relBig = 900 / 60
const strength = Math.min(2.6, Math.max(0.5, 0.35 + relBig * 0.55))
expect(strength).toBeCloseTo(2.6)
const relSmall = 60 / 6000
const weak = Math.min(2.6, Math.max(0.5, 0.35 + relSmall * 0.55))
expect(weak).toBeCloseTo(0.5)
})
it('P1-O bundle 全量:导出 2 包 → 解析全部 → 逐装成功', () => {
const w = mk('bt-x1')
const p1 = modParse(JSON.stringify({ id: 'bt-a', name: 'a', version: '1', data: {} }))
const p2 = modParse(JSON.stringify({ id: 'bt-b', name: 'b', version: '1', data: {} }))
if (!p1.ok || !p2.ok) return expect(false).toBe(true)
w.installPlugin(modToPlugin(p1.pack))
w.installPlugin(modToPlugin(p2.pack))
const txt = w.exportModBundle()!
const all = modParseAll(txt)
expect(all.length).toBe(2)
const w2 = mk('bt-x2')
for (const p of all) w2.installPlugin(modToPlugin(p))
expect(w2.pluginList().filter((p) => p.id.startsWith('mod-bt-')).length).toBe(2)
})
it('P1-V 异常回滚:install 中途炸 → 池/卡全摘', () => {
const w = mk('crash-x1')
const bad = { ...examplePlugin, id: 'crash-pl', install(ctx: never) { void ctx; throw new Error('boom') } }
const r = w.installPlugin(bad as never)
expect(r.ok).toBe(false)
expect(w.eventPoolIds().includes('crash-pl')).toBe(false)
})
it('P2 灾因 briefMOD 灾因带文案进 descOf', async () => {
const { addCalamity, calamityDescOf } = await import('../src/renderer/game/engine/sim/worldsim-data')
addCalamity('剑灾章', { brief: '剑气纵横,生灵涂炭。', family: { lingcao: 0.8 } })
expect(calamityDescOf('剑灾章')).toContain('剑气纵横')
})
})