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(时钟/收集器/四季/年轴/效果全矩阵/死局链/残留防御)
This commit is contained in:
2026-08-23 09:20:52 +08:00
parent 106db18017
commit a7ee125866
29 changed files with 700 additions and 49 deletions
+31 -1
View File
@@ -4,6 +4,7 @@ import { computeLegacy, resolveLegacy } from '../../game/core/legacy'
import { resolveLegacy as doesIt } from '../../game/core/legacy'
import { ResolveModal } from '../components/ResolveModal'
import { buildBiography } from '../../game/core/biography'
import { yearAxis, decadeLabel } from '../../game/core/yearaxis'
void doesIt
@@ -12,7 +13,7 @@ export default function LegacyPanel() {
const revision = useGameStore((s) => s.revision)
void revision
const [showResolve, setShowResolve] = useState(false)
const [view, setView] = useState<'dims' | 'chronicle' | 'report' | 'scroll'>('dims')
const [view, setView] = useState<'dims' | 'chronicle' | 'report' | 'scroll' | 'axis'>('dims')
if (!world) return null
const w = world
const s = w.state
@@ -54,6 +55,7 @@ export default function LegacyPanel() {
<button className="btn" onClick={() => setView('report')}></button>
<button className="btn" onClick={() => setView('chronicle')}></button>
<button className="btn" onClick={() => setView('scroll')}></button>
<button className="btn" onClick={() => setView('axis')}></button>
</div>
</div>
@@ -110,6 +112,8 @@ export default function LegacyPanel() {
</div>
)}
{view === 'axis' && <AxisView />}
{view === 'scroll' && <ScrollScroll />}
{view === 'chronicle' && (
@@ -133,6 +137,32 @@ export default function LegacyPanel() {
)
}
function AxisView() {
const world = useGameStore((s) => s.world)
if (!world) return null
const cells = yearAxis(world.state)
return (
<div className="card">
<div className="card-title"></div>
{cells.map((c) => (
<div key={c.from} className="axis-cell">
<div className="axis-decade">{decadeLabel(c.from, c.to)}</div>
<div className="axis-events">
<span className="tag good-t-bg"> {c.births}</span>
<span className="tag bad-t-bg"> {c.deaths}</span>
{c.events.slice(0, 6).map((e, i) => (
<span key={i} className={`tag ${e.kind === '战' || e.kind === '渡劫' ? 'bad-t-bg' : ''}`}>
{e.kind}·{e.year} {e.label}
</span>
))}
{c.events.length > 6 && <span className="dim2">{c.events.length - 6}</span>}
</div>
</div>
))}
</div>
)
}
function ScrollScroll() {
const world = useGameStore((s) => s.world)
if (!world) return null