【A 市场实体化(真库存循环)】 - 世界呼吸:池月供给 × 潮汐span - 常驻需求(worldSupplyRate 2% vs worldDemandRate 1.5%) - NPC 上桌:def.sells/buys 逐月入池出池——池浅采不到→power-15%,池深抛货→市场暖意 - 玩家交易回写:buy 浅池价涨/sell 盈池价跌(tradeSettle 0.35 份额粒度);池深<35% 断供拒单(12% 是枯井) - marketPrice 统一走 marketMultFor;本地 POOL_BASE/TECH 复刻清除(worldsim-data 单源) 【B 世界格局博弈】 - 战争伤骨:劫掠胜负回写 power(败-18%/胜+6%)+ dead 字段 raidCount/warCooldownYear 启用 - 社交回响:赠礼回礼(30% 灵石/30% 灵草)+ power 微涨;联姻/和约/结盟皆涨 power - NPC 关系网:relationsWithOthers 填实(同风格亲30~55/异风格隙-35~15)+ 年首±5 漂移;世仇<-50 年首互攻(败方-18%) - 灾年共苦:灾年 NPC 贸易 ×0.7;tide 对供给 ±0.3 弹性 - 灾年持续 6 月渐退;灾起/灾散快讯(kind 标记) 【UI】 - 天下面板:池深百分比(含断供阈值 tooltip)/本族天下排位/灾年余月 - 快讯响应化:行情见顶抛售5/见底吃进5/灾年救济(50灵石→关系8) - MarketPanel 法帖价格改 techniquePrice()(硬编码清除) 【测试】994 全绿(38 套件,新增世界炉膛 8 例);金钟罩 0.1.17 基线固化
49 lines
1.9 KiB
TypeScript
49 lines
1.9 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { stateFingerprint, longRun } from './fingerprint.helper'
|
|
import { World } from '../src/renderer/game/engine/runtime/World'
|
|
|
|
/**
|
|
* 金钟罩:固定种子长跑 560 月的状态指纹。
|
|
* 任何改动(重构日程/调平衡/加系统)若改变了确定性序列或结果,此测试立刻报红。
|
|
* 更新规则:仅当**有意**变更序列逻辑时,三枚 seed 指纹同版更新并注明原因。
|
|
*/
|
|
// 0.1.17 世界真炉膛基线:市场实体化(供给/需求呼吸+NPC上桌+玩家买卖回写)
|
|
// + NPC博弈(互攻/关系网/战争伤骨)+ 灾年持续化后固化。
|
|
const GOLDEN: Record<string, Record<number, string>> = {
|
|
'bell-seed-1': { 560: 'c923fdd1', 1200: '2cb58265', 2160: 'a367ba40' },
|
|
'bell-seed-2': { 560: 'e98eb9fa', 1200: '3dd495e9', 2160: '17a588c2' },
|
|
'bell-seed-3': { 560: '5edde2cd', 1200: '476512f7', 2160: 'bc2d55d8' }
|
|
}
|
|
|
|
const TIERS = [
|
|
[560, '47 年(4 个十年)'],
|
|
[1200, '100 年'],
|
|
[2160, '180 年']
|
|
] as const
|
|
|
|
describe('金钟罩 · 长跑确定性指纹(三档:47/100/180 年)', () => {
|
|
for (const [seed, tiers] of Object.entries(GOLDEN)) {
|
|
for (const [months, label] of TIERS) {
|
|
it(`${seed} ${label}指纹 === ${tiers[months]}`, () => {
|
|
const w = run(seed, months)
|
|
expect(stateFingerprint(w.state)).toBe(tiers[months])
|
|
})
|
|
}
|
|
}
|
|
|
|
it('同 seed 两次长跑指纹一致(无状态污染)', () => {
|
|
const a = stateFingerprint(longRun('bell-seed-1').state)
|
|
const b = stateFingerprint(longRun('bell-seed-1').state)
|
|
expect(a).toBe(b)
|
|
})
|
|
})
|
|
|
|
function run(seed: string, months: number): ReturnType<typeof longRun> {
|
|
const w = World.create({ seed, surname: '钟', familyName: '钟家', motto: 'm', difficulty: 'normal' })
|
|
for (let i = 0; i < months; i++) {
|
|
if (w.state.gameOver) break
|
|
w.advanceMonth()
|
|
}
|
|
return w
|
|
}
|