Files
ChronicleOfTheImmortalClan/src/renderer/game/core/clock.ts
T
thzxx a7ee125866 v0.1.6: 时轮与造化(GameClock/RngHub/时节/年轴/保护)
- 统一时轮 GameClock:七 phase 注册制(production/aging/cultivation/missions/
  events/diplomacy/epilogue) + 年首三钩子(婚配→岁贡→族簿);advanceMonth 化作薄壳;
  新增系统只注册不改本体;alive 守卫、随机序、族簿时序均与重构前逐一等价
- 金钟罩:3 枚 seed × 560 月指纹常驻(重构前后已验证同哈希;时节属有意变更后重固化)
- 统一随机 RngHub:开局播种(crypto UV)、音效白噪独立流、引擎 rng 带 nextCount 审计;
  全工程拔除逻辑侧 Math.random
- 时节系统:春夏秋冬乘子(春田+10%/夏修+5%/秋市+5%/冬闭+8%)入生产与修炼
- 崩溃保护:advance 异常自动存『出险前』档 + 停速提示回档
- 性能预算:dev-only 单 tick>60ms 报最慢 phase
- 横轴年表:十年一格大事/生殇聚合 + 春秋原年轴视图
- 测试 197→225(时钟/收集器/四季/年轴/效果全矩阵/死局链/残留防御)
2026-08-23 09:20:52 +08:00

73 lines
1.7 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 type { World } from '../engine/world'
/**
* 统一时轮调度:所有系统以 phase 注册,由时钟按固定顺序驱动。
* - 月度 phaseproduction / aging / cultivation / missions / events / diplomacy / epilogue
* - 年首钩子:onYearStart(婚配 → 声望岁贡 → 岁末族簿)
* 新增系统 = 注册一行,不再修改 advanceMonth 本体。
*/
export type PhaseId =
| 'production'
| 'aging'
| 'cultivation'
| 'missions'
| 'events'
| 'diplomacy'
| 'epilogue'
export type SystemHook = (w: World) => void
export interface PhaseStat {
phase: PhaseId
ms: number
count: number
}
export const PHASE_ORDER: PhaseId[] = [
'production',
'aging',
'cultivation',
'missions',
'events',
'diplomacy',
'epilogue'
]
export class GameClock {
private monthly = new Map<PhaseId, SystemHook[]>()
private yearly: SystemHook[] = []
register(phase: PhaseId, fn: SystemHook): void {
const list = this.monthly.get(phase) ?? []
list.push(fn)
this.monthly.set(phase, list)
}
onYearStart(fn: SystemHook): void {
this.yearly.push(fn)
}
fireYearStart(w: World): void {
for (const fn of this.yearly) fn(w)
}
stepMonthly(w: World): PhaseStat[] {
const report: PhaseStat[] = []
for (const phase of PHASE_ORDER) {
const t0 = performance.now()
const fns = this.monthly.get(phase) ?? []
for (const fn of fns) fn(w)
const ms = performance.now() - t0
report.push({ phase, ms, count: fns.length })
}
return report
}
subscriptionCount(): number {
let n = 0
for (const list of this.monthly.values()) n += list.length
return n + this.yearly.length
}
}