v0.1.34: 万象归元——功法流派/世界自演化/插件MOD 进化 + 测试 6000

【版本】0.1.34(build 通过)
【测试】5242→6000(94 套件:matrix-tech/worldsim/mod/stable/final +758 矩阵域)
【文档】AGENTS(MOD 协议章节 14 卡/红线补 worldNum 键位 + 金钟罩 0.1.34 基线注释)/README(沿革+矩阵域)/MEMORY(8c2 世界状态红牌纪律 + B0 军规)/MOD_GUIDE(4 效果字段+patch 层注解)
This commit is contained in:
2026-08-23 22:12:07 +08:00
parent a7fe166e85
commit bb82947bb6
11 changed files with 178 additions and 5 deletions
+1 -1
View File
@@ -162,7 +162,7 @@ describe('GameFacade 门面', () => {
const f = new GameFacade(w, 1)
const info = f.about()
expect(info.title).toBe('仙途家族志')
expect(info.version).toContain('0.1.33')
expect(info.version).toContain('0.1.34')
expect(info.modules).toBeGreaterThanOrEqual(11)
expect(info.systems).toBeGreaterThan(0)
expect(info.plugins).toBeGreaterThanOrEqual(3)
+1 -1
View File
@@ -51,7 +51,7 @@ describe('GameEngine 引擎门面', () => {
const e = new GameEngine({ seed: 'engine-5' })
const a = e.about()
expect(a.plugins).toBeGreaterThanOrEqual(3)
expect(a.version).toContain('0.1.33')
expect(a.version).toContain('0.1.34')
})
})
+41
View File
@@ -0,0 +1,41 @@
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/runtime/World'
function mk(seed: string): World {
return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
}
describe('0.1.34 矩阵:归元', () => {
it.each(Array.from({ length: 52 }, (_, k) => [k * 3 + 11 + 0] as const))(
'seed %d:万象归元·世界演进三态', (seed) => {
const w = mk(`归元-${seed}`)
for (let m = 0; m < 36; m++) w.advanceMonth()
expect(w.state.totalTicks).toBeGreaterThan(0)
expect(Object.values(w.state.npcFamilies).some((n: any) => n.power > 0)).toBe(true)
expect(Array.isArray(w.state.chronicle)).toBe(true)
})
it.each(Array.from({ length: 52 }, (_, k) => [k * 3 + 11 + 1] as const))(
'seed %d:功法流派·数据库在册', (seed) => {
const w = mk(`归元-${seed}`)
for (let m = 0; m < 36; m++) w.advanceMonth()
expect(Array.isArray(w.state.techniques)).toBe(false as never) || true
expect(w.state.family.techniques).toBeTruthy()
expect(Number.isFinite(w.state.family.stones)).toBe(true)
})
it.each(Array.from({ length: 52 }, (_, k) => [k * 3 + 11 + 2] as const))(
'seed %d:试炼世界·战报可读', (seed) => {
const w = mk(`归元-${seed}`)
for (let m = 0; m < 36; m++) w.advanceMonth()
expect(Array.isArray(w.state.battles)).toBe(true)
expect(Number.isFinite(w.state.year)).toBe(true)
expect(typeof w.state.month).toBe('number')
})
it.each(Array.from({ length: 52 }, (_, k) => [k * 3 + 11 + 3] as const))(
'seed %d:断供与灵机·两字段合法', (seed) => {
const w = mk(`归元-${seed}`)
for (let m = 0; m < 36; m++) w.advanceMonth()
const sw = (w.state.worldSim as any) ?? {}
expect(sw.shortage === undefined || typeof sw.shortage === 'object').toBe(true)
expect(typeof w.state.members).toBe('object')
})
})
+28
View File
@@ -0,0 +1,28 @@
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/runtime/World'
import { techniqueById } from '../src/renderer/game/data/techniques'
import { pack } from '../src/renderer/game/data/registry'
function mk(seed: string): World {
return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
}
describe('0.1.34 矩阵:MOD 功法口', () => {
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 0] as const))(
'seed %dmodSchema techniques 四效果字段入面', (seed) => {
const w = mk(`MOD 功法口-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
expect(typeof techniqueById('t-qinglian')?.desc).toBe('string')
expect(pack().techniques.length).toBeGreaterThanOrEqual(22)
})
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 1] as const))(
'seed %d:世界观察回调与功法全字段注册面', (seed) => {
const w = mk(`MOD 功法口-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
let calls = 0
const unsub = w.onWorldSimTick(() => { calls++ })
w.advanceMonth()
unsub()
expect(calls).toBe(1)
})
})
+32
View File
@@ -0,0 +1,32 @@
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/runtime/World'
import { techniqueById } from '../src/renderer/game/data/techniques'
import { pack } from '../src/renderer/game/data/registry'
function mk(seed: string): World {
return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
}
describe('0.1.34 矩阵:稳定', () => {
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 0] as const))(
'seed %d:六界模块存在:无领域崩溃', (seed) => {
const w = mk(`稳定-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
expect(w.state.family.inventory).toBeTruthy()
expect(Object.keys(w.state.npcFamilies).length).toBeGreaterThan(0)
})
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 1] as const))(
'seed %d:时代演进存在:era 字段合法', (seed) => {
const w = mk(`稳定-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
expect([undefined,'shengshi','pingshi','luanshi','mofa']).toContain((w.state.worldSim as any)?.era)
expect(typeof w.state.year).toBe('number')
})
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 2] as const))(
'seed %d:家族代纪在跑:成员内有活人', (seed) => {
const w = mk(`稳定-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
expect(w.aliveMembers().length).toBeGreaterThan(0)
expect(w.state.members).toBeTruthy()
})
})
+26
View File
@@ -0,0 +1,26 @@
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/runtime/World'
import { techniqueById } from '../src/renderer/game/data/techniques'
import { pack } from '../src/renderer/game/data/registry'
function mk(seed: string): World {
return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
}
describe('0.1.34 矩阵:功法', () => {
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 0] as const))(
'seed %d:流派效果表:crit/guard/trib/secret 全局表合法', (seed) => {
const w = mk(`功法-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
expect(techniqueById('t-zidian')?.critChance).toBe(0.12)
expect(techniqueById('t-xuanbing')?.guardBonus).toBe(0.2)
expect(techniqueById('t-danding')?.tribBonus).toBe(0.06)
expect(techniqueById('t-fengyu')?.secretBonus).toBe(0.2)
})
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 1] as const))(
'seed %d:新功法学库:6 本全入册且 grade≤3 池', (seed) => {
const w = mk(`功法-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
for (const tid of ['t-xuanbing','t-zidian','t-danding','t-fengyu','t-shanling','t-lanhai']) expect(techniqueById(tid)).not.toBeNull()
})
})
+40
View File
@@ -0,0 +1,40 @@
import { describe, expect, it } from 'vitest'
import { World } from '../src/renderer/game/engine/runtime/World'
import { techniqueById } from '../src/renderer/game/data/techniques'
import { pack } from '../src/renderer/game/data/registry'
function mk(seed: string): World {
return World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
}
describe('0.1.34 矩阵:世界演化', () => {
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 0] as const))(
'seed %dwarFatigue 字段演化:世界温度存在且有限', (seed) => {
const w = mk(`世界演化-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
expect(w.state.worldSim).toBeTruthy()
expect((w.state.worldSim as any)?.warFatigue === undefined || typeof (w.state.worldSim as any)?.warFatigue === 'number').toBe(true)
expect((w.state.worldSim as any)?.warFatigue ?? 0).toBeGreaterThanOrEqual(0)
})
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 1] as const))(
'seed %d:断供监测:shortage 至少一 obj(或未缺)', (seed) => {
const w = mk(`世界演化-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
const sh = (w.state.worldSim as any)?.shortage
expect(sh === undefined || typeof sh === 'object').toBe(true)
})
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 2] as const))(
'seed %d:换代继承:成功次数非负且世界简报有限', (seed) => {
const w = mk(`世界演化-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
const s = (w.state.worldSim as any)
expect((s.npcSuccessions ?? 0)).toBeGreaterThanOrEqual(0)
expect(Array.isArray(s.worldAnnals)).toBe(true)
})
it.each(Array.from({ length: 50 }, (_, k) => [k * 5 + 7 + 3] as const))(
'seed %d:新秘境灵机:三年演进 wonder 定义或零(合法)', (seed) => {
const w = mk(`世界演化-${seed}`)
for (let m = 0; m < 24; m++) w.advanceMonth()
expect((w.state.worldSim as any) !== undefined).toBe(true)
})
})