# v0.4 回响编年史 · Chronicle of Echoes > 跨周目叙事时间轴系统。每次飞升自动铭刻一条纪元条目,记录本周目的解码、探险、星潮、天赋觉醒与里程碑,形成永恒叙事流。朝 v0.5「全 5 纪元叙事」目标推进。 ## 动机 - **回应 Issue #1**「就一直连连看?」的进一步反馈:星潮+星图解决了「玩法单一」,但仍缺**叙事深度**与**进度回顾**。 - 玩家完成多次飞升后无回顾入口,对「自己走过多远」缺乏感知,影响长线留存。 - v0.5 路线图为「全 5 纪元叙事」,编年史是其底层骨架——先把数据结构与展示框架立起来。 ## 核心模块 ### 数据模型(`src/lib/game/types.ts`) ```ts export interface ChronicleEntry { ascensionNumber: number; // 第几次飞升(1-based) epochName: string; // 程序化生成的纪元名(5 纪元循环) timestamp: number; durationSec: number; // 本周目持续时间 summary: { techsUnlocked: number; constellationsTotal: number; expeditionsCompleted: number; bossKills: number; starTidesEncountered: number; blueprintsAfter: number; crystalsDecoded: number; crystalsDecodedThisRun: number; }; perksThisAscension: string[]; // 本次飞升后选择的天赋 tidesThisRun: string[]; // 本周目新遇到的星潮 ID lore: string; // 程序化生成的叙事文本 milestones: string[]; // 里程碑标签 } export interface RunStartSnapshot { timestamp: number; techsUnlocked: number; expeditionsCompleted: number; bossKills: number; starTidesEncountered: string[]; crystalsDecoded: number; } ``` GameState 新增字段: - `chronicle: ChronicleEntry[]` — 编年史条目列表(上限 50) - `runStart: RunStartSnapshot` — 当前周目起始快照(用于 delta 计算) - `bossKills: number` — 累计 BOSS 击破数(跨周目) - `starTidesEncountered: string[]` — 累计遇到的星潮 ID 集合(去重) ### 编年史逻辑(`src/lib/game/chronicle.ts`,新建) - `EPOCH_NAMES` — 5 纪元 × 4 后缀 = 20 种纪元名组合(如「第一纪元 · 觉醒之晨」「第三纪元 · 虚空回望」) - `generateEpochName(ascensionNumber, seed)` — 按 ascensionNumber 循环 5 纪元,seed 决定后缀 - `buildLore(entry)` — 模板化叙事生成:开场 → 核心活动 → 星潮段落 → 觉醒段落 → 里程碑 → 收尾 - `detectMilestones(state, deltas)` — 9 种里程碑检测(首次飞升/首杀 BOSS/单周目解码 10+/技术狂人/星潮亲历者/星图六分等) - `computeRunDeltas(state)` — 基于 runStart 快照计算本周目 delta(持续时间/解码数/技术数/探险数/BOSS/新星潮) - `buildChronicleEntry(state, perks)` — 飞升时构建一条 ChronicleEntry - `createRunStartSnapshot(state)` — 飞升后创建新 runStart - `migrateChronicleFields(state)` — 旧存档兼容:补全 chronicle=[]/runStart/bossKills=0/starTidesEncountered=[] - `withPerks(entry, perks)` — 飞升后选天赋时回填 perksThisAscension,并重新生成 lore 包含天赋名 - `getPerkCategoryBreakdown(perks)` / `getCategoryName` / `getCategoryColor` — UI 辅助 ### 引擎接入(`src/lib/game/engine.ts`) - `performPrestige` 在重置前: 1. `buildChronicleEntry(state, [])` 构建本周目条目(perks 暂为空,待玩家选择后回填) 2. 追加到 `chronicle` 数组(上限 50 条) 3. `createRunStartSnapshot(state)` 创建新周目的快照 - 保留跨周目字段:`chronicle`, `bossKills`, `starTidesEncountered` - 重置 `runStart` 为新快照 ### Store 接入(`src/store/gameStore.ts`) - `init()` — 调用 `migrateChronicleFields` 补全旧存档 - `tickTide` — 新星潮触发时,将 `tide_${type}` 追加到 `starTidesEncountered`(去重) - `resolveCurrentNode` — BOSS 战胜利结算时,`bossKills++` - `chooseConstellationPerk` — 选择天赋后,调用 `withPerks` 回填最近一条 chronicle entry 的 `perksThisAscension`,并重新生成 lore ### UI 组件(`src/components/game/ChronicleDialog.tsx`,新建) - 顶部 BookOpen 图标按钮(带 badge 显示条目数) - 全屏对话框,深紫黑渐变背景 + 顶部三色装饰条 - 顶部总览统计:飞升次数 / BOSS 击破 / 星潮亲历 - 垂直时间轴: - 左侧渐变时间轴线 - 每条卡片左侧有发光圆形节点(5 纪元循环色:翠/玫/琥/紫/金),最新一条带 ping 动画 - 卡片含:#编号 / 纪元名(带 textShadow 光晕)/ 时间戳+持续时长 / 叙事文本(衬线字体)/ 6 项统计芯片 / 星潮徽章列表 / 天赋徽章 / 里程碑徽章 - 入场动画:fade-in + slide-up,错峰 80ms - 空状态:根据 ascensions 是否 > 0 显示不同提示 - 打开时播放 `chronicleOpen` 翻页音效 ### 音频(`src/lib/game/audio.ts`) - `chronicle` — 编年史铭刻音效:G3 基音 + C4/G4/C5/G5 多层泛音,深沉钟声感 - `chronicleOpen` — 翻页音效:A4→D5→A5 轻柔上升 + 短促气流 - 飞升成功时延迟 600ms 触发 `chronicle` sfx,与飞升音分层 ### 成就(`src/lib/game/achievements.ts`) 新增 6 项成就: - `ach_chronicle_1` 「首部编年」— 完成首次飞升(+40 洞见 · 产能 +6%) - `ach_chronicle_3` 「三纪元回响」— 完成 3 次飞升(产能 +10% · 洞见 +10%) - `ach_chronicle_5` 「五纪元闭环」— 完成 5 次飞升(产能 +15% · 洞见 +15%) - `ach_boss_1` 「首杀维度」— 击破首个 BOSS(+25 洞见 · 产能 +4%) - `ach_boss_5` 「维度猎手」— 累计击破 5 个 BOSS(产能 +10% · 洞见 +8%) - `ach_tides_all` 「星潮亲历者」— 经历全部 6 种星潮(产能 +8% · 洞见 +8%) ### 飞升对话框增强(`src/components/game/PrestigeDialog.tsx`) - 新增「编年史铭刻预告」卡片,提示本次飞升将记录入编年史 - **修复关键 BUG**:原 `disabled={newBp <= 0 || confirming}` 当 `confirming=true` 时按钮永久禁用,玩家无法完成飞升!现已改为 `disabled={confirming && !canReconfirm}` 并加 900ms 冷却窗口 - **修复 UX**:当 newBp=0(无可获蓝图)时不再永久禁用飞升按钮——v0.3.1 星图天赋 + v0.4 编年史已为飞升提供足够动机。按钮文字改为「飞升(无新蓝图)」 - 飞升成功 toast 增加「编年史已铭刻新纪元」提示 ### 统计面板增强(`src/app/page.tsx`) 新增 3 行统计: - BOSS 击破次数 - 星潮亲历数(X/6) - 编年史条目数(X 纪元) ## QA 验证 ### 修复的关键 BUG - 飞升按钮 `disabled` 逻辑错误导致玩家永远无法飞升(`confirming` 变 true 后按钮被禁用) - 验证:agent-browser 端到端测试,第一次点飞升 → 900ms 冷却 → 第二次点击成功触发,星图觉醒对话框弹出 ### 编年史端到端测试 1. 设置 contact=100 + 资源,触发飞升 → ascensions 1→2, chronicle 0→1 ✓ 2. 选择天赋「二周目经验」→ constellation 增加 c_cos_2, chronicle 末条 perksThisAscension=["c_cos_2"] ✓ 3. 打开编年史对话框 → 显示 1 条卡片,含完整 lore、统计芯片、星潮徽章、天赋徽章、里程碑 ✓ 4. 再次飞升 → ascensions 2→3, chronicle 1→2 ✓ 5. 第二条卡片正确显示新纪元名「第三纪元 · 虚空回望」+ 正确的星潮名「星核悸动」+ 正确的 duration delta(2分42秒) ✓ 6. 成就解锁:`ach_chronicle_1`「首部编年」+ `ach_prestige_3`自动检测 ✓ 7. 统计面板新增「BOSS 击破」「星潮亲历」「编年史条目」3 行 ✓ 8. VLM 视觉评估:8/10,无瑕疵,时间轴清晰,纪元颜色区分明显 ### 视觉细节 - 5 纪元循环色:翠 #34d399 / 玫 #fb7185 / 琥 #fbbf24 / 紫 #e879f9 / 金 #fcd34d - 时间轴节点带 boxShadow 光晕(12px + 24px 双层) - 最新条目带 animate-ping 脉冲 - 卡片入场动画:fade-in + slide-in-from-bottom-2,错峰 80ms - 叙事文本使用 font-serif 衬线字体增加文学感 - 统计芯片按类别用对应颜色 tint ### 旧存档兼容 - `migrateChronicleFields` 自动补全 chronicle=[]/runStart/bossKills=0/starTidesEncountered=[] - 玩家旧存档不丢失进度,新字段以默认值初始化 ## 文件清单 新增: - `src/lib/game/chronicle.ts` — 编年史核心逻辑 - `src/components/game/ChronicleDialog.tsx` — 编年史对话框 UI - `docs/repo/docs/09-回响编年史系统-v0.4.md` — 本文档 修改: - `src/lib/game/types.ts` — 新增 ChronicleEntry / RunStartSnapshot 类型 + GameState 字段 - `src/lib/game/config.ts` — INITIAL_STATE 新增 chronicle/runStart/bossKills/starTidesEncountered - `src/lib/game/engine.ts` — performPrestige 构建编年史条目 + 重置 runStart - `src/lib/game/achievements.ts` — 新增 6 项成就 - `src/lib/game/audio.ts` — 新增 chronicle / chronicleOpen 音效 - `src/store/gameStore.ts` — init 兼容 + tickTide 记录 + resolveCurrentNode BOSS 计数 + chooseConstellationPerk 回填 - `src/components/game/PrestigeDialog.tsx` — 修复 BUG + 编年史预告卡片 + 音效 - `src/app/page.tsx` — 头部编年史按钮 + 对话框渲染 + 统计面板新行 + 版本号 v0.4 ## 已知限制 / 后续 - 编年史上限 50 条(超过自动丢弃最早的) - v0.4 之前发生的飞升不会被回填(无数据可恢复)—— 空状态有对应提示 - 5 纪元叙事内容仍为模板化生成,v0.5 将加入手写剧情节点 - 编年史目前纯本地,v0.4 云存档+排行榜会将其纳入同步范围