Files
ChronicleOfTheImmortalClan/tests/tide-0.1.21.test.ts
T
thzxx 8b6f2f7189 v0.1.27: 活水长流——生灭盘活 + 修为回环 + 世鉴 + MOD 生态闭环(1054 全绿)
【世界模型(180 年实测驱动的机制修复)】
- 生灭可达化:探子模拟实测证实——原覆灭/新贵 183 年零触发(力量通胀+景气自校正);
  修复:脆弱判定放宽(power<110 弱即衰 / warLosses≥2 战损衰)+ yearGrowth 按 era 调制
  (盛世 0.7/平世 1/乱世 -0.8/末法 -1.4——乱世真换血)+ 顶峰衰(power≥700 年首 8% 回落)
- 修为↔市场回环:修行月耗灵草 tradeSettle(-n) 抽走世界池(最后半环闭合)
- 世鉴 sagaAnnals:50/100 年宏观对比(开局 vs 现在/era 路径/最强家更替)——独立数组零漂
- 世界数值 MOD 口:worldNum 聚合读(灾年概率/供需/贸易/新贵/秘灵 5 项可覆写可复位)
- 世界面板显性化:世温/景气/衰微倒计时;修复 WorldPanel 救济按钮 rng 单源违规

【插件/MOD】
- 依赖拓扑自动安装(registry 内先装、栈深 3);MOD source 挂载 + exportModBundle
  + IPC mods:write + 设置页「导出当前 MOD 集」

【测试】1054 全绿(47 套件,+7:乱世压力覆灭/顶峰衰/era 负增/世鉴/数值口/导出/拓扑);
【金钟罩】0.1.27 基线重算(双基线 18 值,生灭/回环受控变更);build 通过
2026-08-23 17:02:46 +08:00

86 lines
3.6 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 { WorldSim } from '../src/renderer/game/engine/sim/WorldSim'
import { WorldSimState, ERA_CONF, REGION_TIDE } from '../src/renderer/game/engine/sim/worldsim-data'
import { stateFingerprint } from './fingerprint.helper'
function worldMid(seed: string): World {
const w = World.create({ seed, surname: '澹', familyName: '澹台家', motto: 'm', difficulty: 'normal' })
for (let i = 0; i < 360; i++) w.advanceMonth()
return w
}
describe('0.1.21 大势流转', () => {
it('era 转移有延续档(窗口内可续任:flow 权重和 < 1', () => {
for (const k of Object.keys(ERA_CONF) as Array<keyof typeof ERA_CONF>) {
const sum = ERA_CONF[k].flow.reduce((a, [, wgt]) => a + wgt, 0)
expect(sum).toBeLessThan(1)
}
})
it('世界温度:景气高涨 → 向盛世转移权重提升(双向闭环)', () => {
const w = World.create({ seed: 't1', surname: '贺', familyName: '贺家', motto: 'm', difficulty: 'normal' })
w.advanceMonth()
const sim = new WorldSim(w)
expect(sim.worldTemperature()).toBeGreaterThan(0.4)
// 池压到高景气 → 温度高
const ws = w.state.worldSim as WorldSimState
ws.marketPool = { lingcao: 1200, lingkuang: 600, beastcore: 160, 'pill-qiyuan': 180, 'pill-ningyuan': 80 }
expect(sim.worldTemperature()).toBeGreaterThan(1.5)
})
it('十年鉴入独立史表(worldAnnals),newsFeed 裁剪后仍留存', () => {
const w = World.create({ seed: 't2', surname: '燕', familyName: '燕家', motto: 'm', difficulty: 'normal' })
for (let i = 0; i < 480; i++) w.advanceMonth()
const ws = w.state.worldSim as WorldSimState
expect((ws.worldAnnals ?? []).length).toBeGreaterThanOrEqual(3)
// 史表内容锚定(十年鉴 + 世鉴/顶峰衰快讯共在 newsFeed,史表只记十年鉴)
const last = (ws.worldAnnals ?? []).pop()!
expect(last.text).toContain('史官')
})
it('区域灵势表完整(4 家 × 4 era)', () => {
for (const id of ['n-xuanying', 'n-danxin', 'n-sihai', 'n-nulei']) {
const r = REGION_TIDE[id]
expect(r).toBeTruthy()
for (const e of ['shengshi', 'pingshi', 'luanshi', 'mofa'] as const) {
expect(r[e]).toBeTypeOf('number')
}
}
})
it('灾年 NPC 互攻概率提高(W4 全环)', () => {
const w = World.create({ seed: 't4', surname: '蓟', familyName: '蓟家', motto: 'm', difficulty: 'normal' })
w.advanceMonth()
const ws = w.state.worldSim as WorldSimState
const before = (ws.npcDyn['n-nulei']?.relationsWithOthers?.['n-xuanying'] ?? 0)
ws.calamity = '旱灾'
ws.calamityLeft = 6
expect(typeof before).toBe('number')
// 灾年期间长跑不炸(60 月)
for (let i = 0; i < 60; i++) {
w.state.worldSim = ws as never
w.state.month = 1
w.state.year++
w.advanceMonth()
}
expect(w.state).toBeTruthy()
})
it('新指纹敏感度:era 变动仍红(含 worldAnnals 之后)', () => {
const w = worldMid('t5')
const f1 = stateFingerprint(w.state)
const ws = w.state.worldSim as WorldSimState
ws.era = ws.era === 'mofa' ? 'shengshi' : 'mofa'
const f2 = stateFingerprint(w.state)
expect(f1).not.toBe(f2)
})
it('LogFeed 滑动窗语义(120 条上限的函数观点)', () => {
const arr = Array.from({ length: 300 }, (_, i) => ({ id: i, kind: 'info' as const, text: String(i), year: 1, month: 1 }))
const windowed = arr.slice(-120)
expect(windowed.length).toBe(120)
expect(windowed[0]!.id).toBe(180)
})
})