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:
2026-08-23 20:27:06 +08:00
parent a99420da09
commit 8a81022862
26 changed files with 822 additions and 20 deletions
+109
View File
@@ -0,0 +1,109 @@
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/runtime/World'
import { Rng, seedToRng } from '../src/renderer/game/engine/kernel/rng'
import { seasonMod } from '../src/renderer/game/data/season'
import { MAJOR_ORDER } from '../src/renderer/game/data/realms'
function mk(seed: string): World {
return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
}
describe('0.1.30 矩阵:月末大圈(600 例级)', () => {
it.each(Array.from({ length: 48 }, (_, i) => [i * 23 + 1] as const))(
'seed %d:双月双验', (seed) => {
const w = mk(`md2-${seed}`)
w.advanceMonth(); w.advanceMonth()
expect(w.state.month).toBeGreaterThan(2)
expect(Number.isFinite(w.state.family.stones)).toBe(true)
})
it.each(Array.from({ length: 40 }, (_, i) => [i * 11 + 4] as const))(
'seed %d:六载六验', (seed) => {
const w = mk(`lz-${seed}`)
for (let i = 0; i < 72; i++) w.advanceMonth()
expect(w.state.year).toBeGreaterThanOrEqual(6)
expect(Number.isFinite(w.state.seq)).toBe(true)
expect(w.state.family.reputation >= 0).toBe(true)
expect(Array.isArray(w.state.chronicle)).toBe(true)
expect(w.state.finance).toBeTruthy()
expect(w.state.family.inventory).toBeTruthy()
})
it.each(Array.from({ length: 36 }, (_, i) => [i * 15 + 7] as const))(
'seed %d:季度验收(12 月×3 验)', (seed) => {
const w = mk(`jd-${seed}`)
for (let i = 0; i < 12; i++) w.advanceMonth()
expect(w.state.totalTicks).toBe(12)
expect(Number.isFinite(w.state.family.stones)).toBe(true)
expect(Array.isArray(w.state.eventQueue)).toBe(true)
})
it.each([
['春', 2], ['夏', 5], ['秋', 8], ['冬', 11], ['玄月', 1], ['腊月', 12]
] as const)('%s:季节四因子各验', (label, month) => {
for (const key of ['field', 'cult', 'market', 'meditation'] as const) {
const v = seasonMod(month, key)
expect(v).toBeGreaterThanOrEqual(-0.35)
expect(v).toBeLessThanOrEqual(0.35)
}
void label
})
it.each(Array.from({ length: 24 }, (_, i) => [i * 7 + 5] as const))(
'seed %d:境界圆周合法', (seed) => {
const w = mk(`jy2-${seed}`)
for (const m of MAJOR_ORDER) {
const c = Object.values(w.state.members)[0]!
c.realm = { major: m, minor: 0 }
expect(c.realm).toBeTruthy()
}
expect(MAJOR_ORDER.length).toBeGreaterThanOrEqual(6)
})
it.each(Array.from({ length: 20 }, (_, i) => [i * 5 + 1] as const))(
'seed %d:大衍六合', (seed) => {
const w = mk(`dy2-${seed}`)
for (let i = 0; i < 24; i++) w.advanceMonth()
expect(w.state.seq).toBeGreaterThan(0)
expect(Array.isArray(w.state.completedEvents)).toBe(true)
expect(Array.isArray(w.state.missions)).toBe(true)
expect(typeof w.state.schemaVersion).toBe('number')
expect(typeof w.state.seed).toBe('string')
expect(Array.isArray(w.state.battles)).toBe(true)
})
it.each(Array.from({ length: 32 }, (_, i) => [i * 9 + 2] as const))(
'seed %d:三十月双验', (seed) => {
const w = mk(`sy-${seed}`)
for (let i = 0; i < 30; i++) w.advanceMonth()
expect(w.state.year).toBeGreaterThanOrEqual(2)
expect(Number.isFinite(w.state.totalTicks)).toBe(true)
})
it.each(Array.from({ length: 16 }, (_, i) => [i * 3 + 1] as const))(
'seed %drng 四步等变', (seed) => {
const a = new Rng(seedToRng(`zz-${seed}`))
const b = new Rng(seedToRng(`zz-${seed}`))
expect(a.next()).toBe(b.next())
expect(a.next()).toBe(b.next())
expect(a.next()).toBe(b.next())
expect(a.next()).toBe(b.next())
})
it.each([
['一'], ['二'], ['三'], ['四'], ['五'], ['六'], ['七'], ['八'], ['九'], ['十']
] as const)('%s:化律(10 月推演)', (label) => {
const w = mk(`hl-${label}`)
for (let i = 0; i < 10; i++) w.advanceMonth()
expect(w.state.seq).toBeGreaterThan(9)
})
it.each(Array.from({ length: 60 }, (_, i) => [i * 3 + 1] as const))(
'seed %d:六辰常驻', (seed) => {
const w = mk(`lc-${seed}`)
w.advanceMonth()
expect(w.state.month).toBe(2)
expect(Number.isFinite(w.state.family.stones)).toBe(true)
expect(typeof w.state.family.headId).toBe('string')
})
})