/** * 0.1.39 P3:worldsim 能力卡关停根治测试 * 验证关停后世界自主演进完全冻结——潮汐、NPC 动力学、时代弧、快讯不再推进。 * 注意:玩家行为(修炼耗草→tradeSettle 回写池、买卖交易回写池)不受 worldsim * 能力卡关停影响——这是玩家与世界的交互而非世界自主演进。 */ 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 { resetSaveBus, attachLogSink } from './world.helpers' import type { WorldSimState } from '../src/renderer/game/engine/sim/worldsim-data' function baseWorld(seed: string): World { const w = World.create({ seed, surname: '封', familyName: '封家', motto: 'm', difficulty: 'normal' }) resetSaveBus() attachLogSink(w) return w } describe('0.1.39 worldsim 关停根治', () => { it('sysEnabled("worldsim") 默认开 → toggleSystem 后关', () => { const w = baseWorld('ws-toggle-1') expect(w.sysEnabled('worldsim')).toBe(true) const after = w.toggleSystem('worldsim') expect(after).toBe(false) expect(w.sysEnabled('worldsim')).toBe(false) }) it('关停后 tick() 直接 return(入口双闸守卫)', () => { const w = baseWorld('ws-freeze-1') // 推进 12 月让 worldSim 有初始状态 for (let i = 0; i < 12; i++) w.advanceMonth() const ws = w.state.worldSim as WorldSimState expect(ws).toBeDefined() // 快照关键字段 const tideBefore = ws.tide const tideTicksBefore = ws.tideTicks const poolBefore = { ...ws.marketPool } // 关停 worldsim w.toggleSystem('worldsim') expect(w.sysEnabled('worldsim')).toBe(false) // 直接调 tick() 应被入口守卫拦截 new WorldSim(w).tick() // 状态完全冻结(tick 内所有逻辑未执行) expect(ws.tide).toBe(tideBefore) expect(ws.tideTicks).toBe(tideTicksBefore) expect(ws.marketPool).toEqual(poolBefore) }) it('关停后 advanceMonth 不再自主演进世界(潮汐/NPC/时代弧/快讯冻结)', () => { const w = baseWorld('ws-freeze-2') // 推进 24 月让世界有实质演化 for (let i = 0; i < 24; i++) w.advanceMonth() const ws = w.state.worldSim as WorldSimState expect(ws).toBeDefined() // 快照世界自主演进指标 const tideTicksBefore = ws.tideTicks const npcDynBefore = JSON.stringify(ws.npcDyn) const secretQiBefore = JSON.stringify(ws.secretQi) const eraBefore = ws.era const newsLenBefore = ws.newsFeed.length const calamityBefore = ws.calamity const warFatigueBefore = ws.warFatigue // 关停 w.toggleSystem('worldsim') // 推进 36 月——世界自主演进应纹丝不动 for (let i = 0; i < 36; i++) w.advanceMonth() // tick 内逻辑全部冻结 expect(ws.tideTicks).toBe(tideTicksBefore) // 潮汐不推进 expect(JSON.stringify(ws.npcDyn)).toBe(npcDynBefore) // NPC 动力学不变 expect(JSON.stringify(ws.secretQi)).toBe(secretQiBefore) // 秘境灵气不自恢复 expect(ws.era).toBe(eraBefore) // 时代弧不变 expect(ws.newsFeed.length).toBe(newsLenBefore) // 无新快讯 expect(ws.calamity).toBe(calamityBefore) // 灾年状态不变 expect(ws.warFatigue).toBe(warFatigueBefore) // 战争疲劳不变 }) it('重新开启后世界恢复演进(可逆性)', () => { const w = baseWorld('ws-resume-1') for (let i = 0; i < 12; i++) w.advanceMonth() const ws = w.state.worldSim as WorldSimState // 关停 12 月 w.toggleSystem('worldsim') const tideFrozen = ws.tide const ticksFrozen = ws.tideTicks for (let i = 0; i < 12; i++) w.advanceMonth() expect(ws.tide).toBe(tideFrozen) expect(ws.tideTicks).toBe(ticksFrozen) // 重新开启 w.toggleSystem('worldsim') expect(w.sysEnabled('worldsim')).toBe(true) for (let i = 0; i < 12; i++) w.advanceMonth() // 世界恢复演进——tideTicks 必须增长 expect(ws.tideTicks).toBeGreaterThan(ticksFrozen) }) })