【资源物品大扩容】 - ItemKind 6 值:resource/material/pill/talisman/brew/artifact——市场分群/背包/售卖/modSchema 全链 - 新材料七种:灵玉/灵木/兽皮/灵果(POOL_BASE+MARKET_IDS+worldgen 偏移四同步入世界池)、 灵露/丹砂/符纸(道具料) - 循环接入:新建筑灵果园(灵果)/灵木坊(灵木);productionTick 泛化逐建筑读 produceTable 全键; 秘境掉落材料化(灵玉/兽皮/灵木);材料类同向微漂(物产同源生态) 【新用途】 - 符箓:war 战斗开战武备自动消耗(talismanWarPrep 零 rng) - 灵酿:渡劫伤后自动回气 +5 - 新丹方和灵丹/虚元丹 + 玉澜刃/灵酿铸器配方 【测试 5009】86 套件(+1000:matrix-treasure-a/b 950 + 断链修整); 【金钟罩】0.1.32 基线重算(物品/池/生产泛化受控变更);build 通过
84 lines
3.7 KiB
TypeScript
84 lines
3.7 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
||
import { World } from '../src/renderer/game/engine/runtime/World'
|
||
import { generateWorld } from '../src/renderer/game/engine/sim/worldgen'
|
||
import { npcById } from '../src/renderer/game/data/npcs'
|
||
import { engineFromSnapshot } from '../src/renderer/game/engine/GameEngine'
|
||
|
||
describe('0.1.24 寰宇初构·世界种子', () => {
|
||
it('同 seed 生成同一世界(确定性)', () => {
|
||
const a = generateWorld('world-1')
|
||
const b = generateWorld('world-1')
|
||
expect(a.npcs.length).toBe(b.npcs.length)
|
||
expect(a.npcs[0]!.id).toBe(b.npcs[0]!.id)
|
||
expect(a.feuds).toEqual(b.feuds)
|
||
})
|
||
|
||
it('不同 seed 生成不同世界(势力随机 4~8 家)', () => {
|
||
const seen = new Set<string>()
|
||
for (const s of ['w1', 'w2', 'w3', 'w4', 'w5']) {
|
||
const g = generateWorld(s)
|
||
expect(g.npcs.length).toBeGreaterThanOrEqual(4)
|
||
expect(g.npcs.length).toBeLessThanOrEqual(8)
|
||
seen.add(g.npcs[0]!.id)
|
||
}
|
||
expect(seen.size).toBeGreaterThan(1)
|
||
})
|
||
|
||
it('势力名单无重名(去重保证)', () => {
|
||
for (const s of ['n1', 'n2', 'n3', 'n4']) {
|
||
const g = generateWorld(s)
|
||
const names = g.npcs.map((n) => n.name)
|
||
expect(new Set(names).size).toBe(names.length)
|
||
}
|
||
})
|
||
|
||
it('初始关系网:世仇/盟友对存在且对称', () => {
|
||
const g = generateWorld('wrel')
|
||
expect(g.feuds.length).toBeGreaterThanOrEqual(1)
|
||
expect(g.alliances.length).toBeGreaterThanOrEqual(1)
|
||
for (const [a, b] of [...g.feuds, ...g.alliances]) {
|
||
expect(g.relations[a]?.[b]).toBe(g.relations[b]?.[a])
|
||
expect(g.relations[a]?.[b]).toBeDefined()
|
||
}
|
||
})
|
||
|
||
it('开局时界(era 三态合法)与市场偏移存在', () => {
|
||
const g = generateWorld('wera')
|
||
expect(['shengshi', 'pingshi', 'luanshi']).toContain(g.eras)
|
||
expect(Object.keys(g.marketOffset).length).toBe(9)
|
||
})
|
||
|
||
it('世界创建即随机:同 seed 同势力、不同 seed 不同势力', () => {
|
||
const w1 = World.create({ seed: 'now-1', surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
|
||
const w2 = World.create({ seed: 'now-1', surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
|
||
const w3 = World.create({ seed: 'now-2', surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
|
||
expect(Object.keys(w1.state.npcFamilies).join()).toBe(Object.keys(w2.state.npcFamilies).join())
|
||
expect(Object.keys(w1.state.npcFamilies).join()).not.toBe(Object.keys(w3.state.npcFamilies).join())
|
||
})
|
||
|
||
it('开局即恩怨:关系网入档并生效(首月快讯/大样)', () => {
|
||
const w = World.create({ seed: 'now-3', surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
|
||
w.advanceMonth()
|
||
const ws = w.state.worldSim as { npcDyn: Record<string, { relationsWithOthers: Record<string, number> }> }
|
||
const first = Object.keys(w.state.npcFamilies)[0]!
|
||
const rels = ws.npcDyn[first]?.relationsWithOthers ?? {}
|
||
expect(Object.keys(rels).length).toBeGreaterThan(0)
|
||
})
|
||
})
|
||
describe('0.1.25 P0:worldGen 存档稳固', () => {
|
||
it('动态家族 def 落档:读档后 npcById 永命中(P0 修复)', async () => {
|
||
let w: World | null = null
|
||
for (const s of ['dg-1', 'dg-2', 'dg-3', 'dg-4', 'dg-5', 'dg-6']) {
|
||
const t = World.create({ seed: s, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
|
||
if (Object.keys(t.state.npcFamilies).some((k) => k.startsWith('n-g'))) { w = t; break }
|
||
}
|
||
if (!w) return // 都无动态家(seed 未抽中)→ 等价通过
|
||
const snap = JSON.parse(JSON.stringify(w.state))
|
||
const e2 = engineFromSnapshot(snap as never)
|
||
const ids = Object.keys(e2.world.state.npcFamilies)
|
||
for (const k of ids) {
|
||
expect(npcById(k)).toBeTruthy()
|
||
}
|
||
})
|
||
})
|