v0.1.34a(修正): 新秘境改种子派生伪随机——零 rng 消耗(修复跨世界/跨跑分叉)

B0 原用 World.rng.chance/pick/int——序列漂移疑虑(实际为模块级全局 EXTRA_MISSIONS 残留污染);
现改为 seed 哈希派生(year/npcSuccessions 异或哈希——纯确定性零 rng),金钟罩序列零伤;
SecretQi/mission def 全走世界状态 s.wonders(每档独立),确定性复跑矩阵恢复绿;
金钟罩 0.1.34 基线固化(功法流派/时节共鸣/warFatigue/换代/断供受控变更——值变序列受控重算 62 例绿)
This commit is contained in:
2026-08-23 22:05:53 +08:00
parent a491b9c54a
commit 3fb64f6e78
7 changed files with 33 additions and 23 deletions
+15 -10
View File
@@ -4,7 +4,7 @@ import { WorldSimState, NpcDynamics, WORLDSIM, ERA_CONF, makeWorldSimState, NpcS
import { pack } from '../../data/registry'
import { ITEMS } from '../../data/items'
import { npcById, getNpcDefs, registerNpcDef, unregisterNpcDef } from '../../data/npcs'
import { allMissions, addMission, WONDER_TEMPLATES, type MissionDef } from '../../data/secrets'
import { allMissions, WONDER_TEMPLATES, type MissionDef } from '../../data/secrets'
import { MAJORS, MAJOR_ORDER } from '../../data/realms'
const MARKET_IDS = ['lingcao', 'lingkuang', 'beastcore', 'lingyu', 'lingmu', 'shoupi', 'lingguo', 'pill-qiyuan', 'pill-ningyuan']
@@ -17,9 +17,9 @@ export class WorldSim {
if (!w.state.worldSim) w.state.worldSim = initSim(w)
const ws = w.state.worldSim as WorldSimState
if (!ws.secretQi || Object.keys(ws.secretQi).length === 0) {
const defs = allMissions()
const defs = [...allMissions(), ...Object.values(ws.wonders ?? {})]
ws.secretQi = {}
for (const m of defs) ws.secretQi[m.id] = 50
for (const m of defs) ws.secretQi[(m as { id: string }).id] = 50
}
return ws
}
@@ -130,18 +130,23 @@ export class WorldSim {
npcTrade(this.w, s, rng.next()) // A4NPC 按 sells/buys 与池交易
driftMarket(s, rng.next(), this.w) // 波动项(保留噪声弹性)
// ---- B0. 新秘境灵机(0.1.34 万象归元:年首机率——乱世×2) ----
// ---- B0. 新秘境灵机(0.1.34 万象归元:种子派生伪随机——零 rng 消耗,确定性天生) ----
if (this.w.state.month === 1) {
const era2 = s.era === 'luanshi' ? 2 : 1
if (rng.chance(worldNum('newSecretChance') * era2)) {
const tpl = rng.pick(WONDER_TEMPLATES)
const seedS = rng.int(1000, 9999)
const ch = worldNum('newSecretChance') * era2
let sh = 0
for (let i = 0; i < this.w.state.seed.length; i++) sh = (sh * 31 + this.w.state.seed.charCodeAt(i)) >>> 0
const pick = ((sh ^ (this.w.state.year * 2654435761) ^ (s.npcSuccessions * 40503)) >>> 0) % 1000 / 1000
if (pick < ch) {
const tpl = WONDER_TEMPLATES[(sh + this.w.state.year) % WONDER_TEMPLATES.length]
const def: MissionDef = {
...tpl,
id: `m-wonder-${seedS}`,
name: `${tpl.icon}地灵诏——${'古幽玄凌'}${rng.int(1, 9)}`
id: `m-wonder-${(sh + this.w.state.year * 7919) % 9000 + 1000}`,
name: `${tpl.icon}地灵诏——${['古', '幽', '玄', '凌'][(sh + this.w.state.year) % 4]}`
}
addMission(def)
s.wonders = s.wonders ?? {}
s.wonders[def.id] = def as unknown as Record<string, unknown>
s.secretQi[def.id] = Math.max(50, s.secretQi[def.id] ?? 50)
s.newsFeed.push({ year: this.w.state.year, month: 1, src: '天机', text: `${def.name} 现世——灵光冲霄,远近皆见。`, kind: 'annal' })
this.w.log('info', `【天下】有异宝出世:${def.name}`)