Files
ChronicleOfTheImmortalClan/tests/matrix-final-circle-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

110 lines
4.3 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 { 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')
})
})