v0.8.2: 工单大清理 - 编年史分页+限时挑战+星潮深化+云排行榜+手写叙事+socket多人星潮+UI打磨
工单 #8 编年史上限+分页: - engine.ts: slice(-50)→slice(-200) - ChronicleDialog.tsx: 加分页(每页10条)+上一页/下一页+页码显示 工单 #5 限时挑战 (subagent 10-a): - beacon.ts: BeaconTimedChallenge + getTimedSlotKey(4h时段) + generateTimedChallenge - BeaconPanel.tsx: amber主题限时区块 + 倒计时 + <30min紧急状态 - gameStore: trackBeacon 加 timedJustCompleted + claimTimedBeacon action 工单 #3 星潮类型深化 (subagent 10-a): - starTide.ts: +3种星潮 surge(emerald)/eclipse(rose)/prism(fuchsia) - TideModifiers: +targetLenBonus/bossWinRateBonus/autoDecodeIntervalMult - decode.ts: generatePuzzle 加 targetLenBonus 参数 - achievements: ach_tides_all 阈值 6→9 工单 #4/P2 云排行榜 (subagent 10-b): - mini-services/leaderboard-service/ (端口3030, Hono+bun, 内存1000条) - API: GET/POST /api/leaderboard + /stats + CORS + 防刷 - beacon.ts: fetchCloudLeaderboard/submitCloudScore - BeaconPanel: 本地Top20/全球Top100 双tab + YOU徽章高亮 工单 #9 手写叙事 (subagent 10-c): - chronicle.ts: EPOCH_LORE 5纪元×3节点=15段手写叙事(80-150字/段) - buildLore 优先手写节点, fallback 模板, 11个变量替换 P3 socket 多人星潮 (subagent 10-c): - mini-services/star-tide-service/ (端口3031, socket.io) - 每10-15min广播global-tide, 60s持续, 6种类型权重 - useGlobalTide hook + triggerGlobalTide action - StarTideIndicator 加 🌐 全球星潮标记 P2 UI打磨: - page.tsx: CrystalOrb 区加装饰全息环(3层旋转) + 四角标记 + 顶部状态条 + 底部铭文 QA: lint零错误 + dev HTTP200 + VLM 8/10 + 2个mini-service运行中(3030/3031)
This commit is contained in:
+227
@@ -445,3 +445,230 @@ Stage Summary:
|
||||
- ✅ P1-b 信标链: 4里程碑(3/7/14/30天) + grace续命, amber→rose渐变
|
||||
- ✅ 在线游玩 v0.8.1: https://gitea-pages.atdunbg.xyz/Super_Z/echo-nexus/
|
||||
- 下一阶段工单: P2 UI样式细节打磨 / P2 云存档+云排行榜 / P3 全纪元叙事
|
||||
|
||||
---
|
||||
Task ID: 10-a
|
||||
Agent: full-stack-developer
|
||||
Task: #5 限时挑战 + #3 星潮类型深化
|
||||
|
||||
Work Log:
|
||||
- 阅读项目上下文:worklog.md(v0.8.1,10 大系统)+ beacon.ts(873行,日+周+链)+ starTide.ts(209行,6种星潮)+ gameStore trackBeacon/tickTide + BeaconPanel.tsx,确认四色全息规范与现有架构
|
||||
- **工单 #5 限时挑战**:
|
||||
- beacon.ts(873→1162行)新增限时挑战系统:
|
||||
- BeaconTimedChallenge/BeaconTimedProgress 接口 + isTimed 字段加入 BeaconScoreEntry
|
||||
- getTimedSlotKey(UTC 0/4/8/12/16/20 点切分,"timed_YYYY-MM-DD_HH")+ timedSlotKeyToSeed(FNV-1a)
|
||||
- generateTimedChallenge(确定性,难度 routine,goal=日基准×0.3-0.5,5类型公式)
|
||||
- loadTimedProgress/saveTimedProgress/addTimedProgress/claimTimedReward(排行榜 isTimed)
|
||||
- msUntilNextTimedSlot + TIMED_SLOT_MS=4h + BEACON_TIMED_KEY
|
||||
- gameStore.ts:trackBeacon 返回值新增 timedJustCompleted,三进度同时更新;新增 claimTimedBeacon action
|
||||
- BeaconPanel.tsx(753→944行):日挑战与周挑战之间插入限时挑战区块(amber 主题)
|
||||
- Hourglass图标+TIMED标题+slotKey+倒计时 + 进度+奖励+领取按钮(emerald)
|
||||
- 紧急状态:距时段结束<30min 切 rose 脉冲动画+"即将结束"徽章
|
||||
- 2新动画 timed-glow(amber)/timed-urgent(rose) + 排行榜 TIMED 徽章
|
||||
- **工单 #3 星潮深化**:
|
||||
- starTide.ts(209→289行):TideType 新增 surge/eclipse/prism
|
||||
- surge(emerald ⇈): crystalsPerSec×2.5 + targetLenBonus=2(解码目标序列+2,更长更难)
|
||||
- eclipse(rose ◐): crystalsPerSec×0.7 + bossWinRateBonus=0.2(BOSS胜率+20%)
|
||||
- prism(fuchsia ◬): insightMultAdd=1.0(洞见×2) + autoDecodeIntervalMult=0.7(自动解码-30%)
|
||||
- TideModifiers 新增 targetLenBonus/bossWinRateBonus/autoDecodeIntervalMult 可选字段
|
||||
- TIDE_WEIGHTS 新增3种各12(总136)+ getTideModifiers 3新case
|
||||
- decode.ts:generatePuzzle 新增 targetLenBonus 参数(surge用,targetLen+stepLimit同步增加)
|
||||
- gameStore.ts 3处修饰器应用:
|
||||
- startDecode:surge 时传 targetLenBonus → 谜题更长
|
||||
- autoDecodeTick:prism 时 interval×=autoDecodeIntervalMult
|
||||
- resolveCurrentNode:eclipse 时 bossWinRate 加 tideBossBonus
|
||||
- achievements.ts:ach_tides_all 阈值6→9;page.tsx StatsPanel 星潮亲历 /9
|
||||
- QA 验证:
|
||||
- lint 零错误(exit 0)+ dev HTTP 200 + 编译<30ms
|
||||
- BeaconPanel VLM 8.5/10(限时区块可见)+ 最终 9/10
|
||||
- 三新星潮 localStorage 注入触发截图 VLM:surge 8/10、prism 7/10、eclipse 8/10
|
||||
- 日/周/信标链/6旧星潮全部保留无回归
|
||||
|
||||
Stage Summary:
|
||||
- ✅ beacon.ts +289行(限时挑战完整系统:4h时段+确定性+进度+领奖+排行榜)
|
||||
- ✅ starTide.ts +80行(3新类型 surge/eclipse/prism + 3新修饰器字段)
|
||||
- ✅ decode.ts generatePuzzle 支持 targetLenBonus(surge 谜题+2)
|
||||
- ✅ gameStore.ts trackBeacon 三进度同步 + claimTimedBeacon + 3处新星潮修饰器
|
||||
- ✅ BeaconPanel.tsx +191行(amber 限时区块 + 紧急状态 + TIMED 徽章)
|
||||
- ✅ 严格四色规范:限时amber/surge-emerald/eclipse-rose/prism-fuchsia,零蓝色
|
||||
- ✅ 确定性:限时挑战同时段同种子同结果(FNV-1a slotKey 哈希)
|
||||
- ✅ lint 零错误 + dev HTTP 200 + VLM 全部≥7/10
|
||||
|
||||
---
|
||||
Task ID: 10-b
|
||||
Agent: full-stack-developer
|
||||
Task: P2/#4 云排行榜 mini-service(信标本机榜升级为云端 Top100)
|
||||
|
||||
Work Log:
|
||||
- 前置阅读:worklog(v0.8.1 项目状态)+ beacon.ts(BeaconScoreEntry / loadLeaderboard / pushLeaderboardEntry / claimBeaconReward / claimWeeklyReward / claimTimedReward)+ BeaconPanel.tsx(排行榜 UI 渲染)+ Caddyfile(?XTransformPort=端口号 转发规则)+ examples/websocket(mini-service 参考)+ .zscripts/dev.sh(mini-service 启动模式)
|
||||
- 发现 worklog 信息滞后:beacon.ts 实际已扩到 1161 行(v0.8.2 已加限时挑战 + claimTimedReward),BeaconPanel 已扩到 953 行
|
||||
- 创建 mini-service:
|
||||
- `mini-services/leaderboard-service/package.json`:独立 bun 项目,type=module,scripts `dev: bun --hot index.ts` + `start: bun index.ts`,依赖 hono ^4.6.14
|
||||
- `mini-services/leaderboard-service/index.ts`(182 行):
|
||||
- Hono + cors 中间件(origin: * 全开放,跨端口必须)
|
||||
- 内存数组存储(最多 1000 条,按 score 降序,同分按时长→时间戳排序)
|
||||
- 防刷:同 dateKey+challenge 10s 内只接受 1 次提交(Map 记录 lastSubmitAt),返回 429 + retryAfterMs
|
||||
- GET /api/leaderboard → Top100 + total
|
||||
- POST /api/leaderboard body {entry} → 校验 schema → 推入 → 排序 → 返回 {entries, total, rank}
|
||||
- GET /api/leaderboard/stats → {totalSubmissions, uniquePlayers, topScore}
|
||||
- GET / → 健康检查 {service, version, ok, uptime}
|
||||
- 端口固定 3030,`export default { port, fetch }` 标准 bun 模式
|
||||
- `mini-services/leaderboard-service/README.md`:API 文档 + 联调规范
|
||||
- mini-service 启动调试:bun --hot 在本沙盒环境下会因文件 watcher 异常被 kill;改用 `bun index.ts`(无 --hot)+ 双 fork `( ... & )` 模式启动,PPID=1,uptime 4+ 分钟稳定
|
||||
- eslint.config.mjs 新增 ignores "mini-services/**"(mini-service 独立项目,不参与主项目 lint)
|
||||
- beacon.ts 扩展(1161 → 1290 行,+129 行):
|
||||
- 三个 claim 函数返回值新增 `entry: BeaconScoreEntry`(非破坏性扩展):
|
||||
- `claimBeaconReward` 返回 `entry`(daily)
|
||||
- `claimWeeklyReward` 返回 `entry`(weekly)
|
||||
- `claimTimedReward` 返回 `entry`(timed)
|
||||
- 新增云排行榜模块(v0.8.2 P2/#4):
|
||||
- `BEACON_CLOUD_PORT = 3030` 常量
|
||||
- `BEACON_CLOUD_LAST_SUBMIT_KEY = "echo-nexus-beacon-cloud-last-submit-v1"` 本地 key
|
||||
- `CloudLeaderboardResponse` / `CloudSubmitResponse` / `CloudStatsResponse` 接口
|
||||
- `loadLastCloudSubmitTimestamp()` / `saveLastCloudSubmitTimestamp(ts)` 工具
|
||||
- `fetchCloudLeaderboard(): Promise<BeaconScoreEntry[]>` — GET 相对路径 + ?XTransformPort=3030
|
||||
- `submitCloudScore(entry): Promise<number>` — POST,成功返回 rank,失败返回 -1,自动记录 ts 供全球榜高亮
|
||||
- `fetchCloudStats(): Promise<CloudStatsResponse | null>` — 全局统计
|
||||
- 所有 fetch 用相对路径 + `?XTransformPort=3030`,**禁止** localhost:3030
|
||||
- gameStore.ts 集成:
|
||||
- import 新增 `submitCloudScore`
|
||||
- `claimWeeklyBeacon` action:领奖成功后 `void submitCloudScore(res.entry)`(fire-and-forget,不 await,不阻塞)
|
||||
- `claimTimedBeacon` action:同上
|
||||
- `claimBeaconReward` (daily) 由 BeaconPanel 直接调用,不通过 gameStore
|
||||
- BeaconPanel.tsx 重写(953 → 1170 行,+217 行):
|
||||
- 新增 import: fetchCloudLeaderboard / submitCloudScore / loadLastCloudSubmitTimestamp + 4 个 lucide 图标(RefreshCw/Globe/WifiOff/Loader2)
|
||||
- 新增状态: lbTab ('local'|'global') / cloudEntries / cloudLoading / cloudError / cloudFetched / mySubmitTs / cloudFetchingRef
|
||||
- 新增 `refreshCloudLeaderboard()` callback:拉取云端榜 + 防并发(ref)+ 空 entries 时显示提示
|
||||
- useEffect: 切到全球 tab 自动拉取(仅首次)+ 初始化读取 mySubmitTs
|
||||
- handleClaimDaily: 领奖成功后 `void submitCloudScore(res.entry).then(rank => ...)` — 若用户在全球 tab 自动刷新
|
||||
- handleClaimTimed/Weekly: 领奖后更新 mySubmitTs + 若在全球 tab 自动刷新
|
||||
- 排行榜 UI 重写为双 tab:
|
||||
- 顶部「本地」(amber 主题) / 「全球」(emerald 主题) 切换按钮 + 全球 tab 专属刷新按钮(旋转动画)
|
||||
- 子标题:本地"本机 Top N · 离线可用" / 全球"全球 Top N · 已同步 / 同步中…"
|
||||
- 本地榜保留原 v0.8.2 渲染(max-h-200px overflow-y-auto)
|
||||
- 全球榜:
|
||||
- 加载中:Loader2 spinner + "正在拉取全球榜…"
|
||||
- 空榜+错误:WifiOff 图标 + 错误文案 + 重试按钮
|
||||
- 空榜+无错:Globe 图标 + "尚无全球记录"提示
|
||||
- 有数据:渲染前 100 条,每条带排名(1-3 名用 Crown/Medal/Award 图标)/ 难度色 / WEEK·TIMED 徽章 / 用时 / 分数
|
||||
- 玩家自己的记录通过 timestamp 匹配 mySubmitTs 高亮:emerald 边框 + emerald 阴影 + YOU 徽章 + emerald 分数色 + 加粗排名
|
||||
- QA 验证:
|
||||
- `bun run lint` 零错误零警告(eslint.config.mjs 把 mini-services 加入 ignores)
|
||||
- dev.log 全程无错误,所有编译 < 300ms
|
||||
- mini-service curl 全通过:
|
||||
- GET / → 200 {service, version, ok, uptime}
|
||||
- GET /api/leaderboard (空) → 200 {entries:[], total:0}
|
||||
- POST /api/leaderboard → 200 {entries, total, rank:1}
|
||||
- GET /api/leaderboard (有数据) → 200 {entries:[...], total:N}
|
||||
- GET /api/leaderboard/stats → 200 {totalSubmissions, uniquePlayers, topScore}
|
||||
- OPTIONS 预检 → 204 + 完整 CORS 头(Allow-Origin: *)
|
||||
- 重复 POST(同 dateKey+challenge 10s 内)→ 429 {error:"Rate limited", retryAfterMs}
|
||||
- 网关路由验证:Caddy :81 → localhost:3030 通过 ?XTransformPort=3030 正确转发,返回 JSON 200
|
||||
- agent-browser 集成测试(通过 :81 端口访问,绕过 Next.js 404):
|
||||
- 信标 tab 选中(用 KeyboardEvent Enter 激活 Radix Tabs,因 pointerdown 被覆盖层拦截)
|
||||
- 切到「全球」tab → 自动拉取 → 显示"全球 Top 6 · 已同步" → 渲染 6 条记录
|
||||
- 刷新按钮可点击,旋转动画正常
|
||||
- POST 测试:浏览器 fetch 提交 score=9999 → 返回 rank=1 → 刷新后榜首显示 10.00K
|
||||
- YOU 高亮:手动设置 localStorage[BEACON_CLOUD_LAST_SUBMIT_KEY] 后刷新 → 榜首显示 emerald 边框 + YOU 徽章
|
||||
- VLM 视觉评分(目标 ≥7/10):
|
||||
- 全球榜含 YOU 高亮:**8/10**(双tab切换清晰,全球榜记录完整,难度色与标签规范,视觉层次佳)
|
||||
- 本地榜:**8/10**(双tab切换逻辑清晰,本地tab内容完整,四色规范应用,信息层级合理)
|
||||
|
||||
Stage Summary:
|
||||
- ✅ mini-service 独立项目:自己的 package.json + bun.lock + node_modules,依赖 hono ^4.6.14,不污染主项目
|
||||
- ✅ 端口 3030 + Caddy 网关:前端用相对路径 `fetch('/api/leaderboard?XTransformPort=3030')`,**禁止** localhost:3030
|
||||
- ✅ CORS 全开放:origin: * + OPTIONS 预检自动处理,前端跨端口无忧
|
||||
- ✅ 内存存储 + 防刷:1000 条上限,同 dateKey+challenge 10s 限 1 次
|
||||
- ✅ 三个 claim 入口全部接入云提交:claimBeaconReward(BeaconPanel 直接调)/ claimWeeklyBeacon / claimTimedBeacon(gameStore action 内)
|
||||
- ✅ 本地榜保留:loadLeaderboard / pushLeaderboardEntry 未删除,作为离线 fallback
|
||||
- ✅ 双 tab UI:本地(amber 主题,立即可用)/ 全球(emerald 主题,按需拉取)+ 刷新按钮 + 加载态 + 错误重试
|
||||
- ✅ 玩家高亮:通过 timestamp 匹配 localStorage[BEACON_CLOUD_LAST_SUBMIT_KEY],emerald 边框 + YOU 徽章
|
||||
- ✅ lint 零错误 + dev HTTP 200 + VLM 8/10
|
||||
- ✅ mini-service 启动稳定:uptime 4+ 分钟,PPID=1(双 fork 模式)
|
||||
- 下一阶段工单:P3 #10-c 全球星潮同步(star-tide-service 已在 mini-services 目录中)
|
||||
|
||||
---
|
||||
Task ID: 10-c
|
||||
Agent: full-stack-developer
|
||||
Task: #9 手写叙事节点 + P3 socket 多人同步星潮
|
||||
|
||||
Work Log:
|
||||
- 前置阅读:worklog.md(v0.8.1,四色规范 emerald/rose/amber/fuchsia,禁止蓝色,10 大系统)+ chronicle.ts(680 行)+ starTide.ts(297 行,9 种星潮)+ gameStore.ts(1332 行)+ StarTide.tsx(170 行)+ StarTideOverlay.tsx + Caddyfile(:81 网关 ?XTransformPort 转发规则)+ 前序 10-a/10-b 工单(限时挑战/3 新星潮/云排行榜 mini-service)
|
||||
- **状态确认**:本任务为重试,发现上次重试已落地主体代码,本次为验证 + 补 QA + 启动 mini-service + 追加 worklog
|
||||
- **工单 #9 手写叙事节点**(chronicle.ts 已就绪):
|
||||
- EPOCH_LORE 常量:5 纪元 × 3 节点(opening/middle/ending)= 15 段手写叙事,每段 80-150 字文学性
|
||||
- 5 纪元主题:1 觉醒(emerald)/2 谐振(rose)/3 遗迹(amber)/4 飞升(fuchsia)/5 终末
|
||||
- 每段含 fallback + variants(按 ctx 命中条件挑变体):
|
||||
- 第一纪元:解码者(≥15)/学者(techs≥5)/里程碑密集(≥2) + 深度轮回(asc>5)
|
||||
- 第二纪元:探险者(≥3)/解码者(≥15)/觉醒天赋 + 深度轮回
|
||||
- 第三纪元:BOSS 猎手(≥2)/深度探险(≥4)/星潮亲历(≥3)/BOSS 收尾 + 深度轮回
|
||||
- 第四纪元:觉醒天赋/蓝图接近完整(≥5)/里程碑密集 + 深度轮回
|
||||
- 第五纪元:里程碑密集(≥3)/星潮汹涌(≥3)/觉醒天赋 + 深度轮回
|
||||
- 变量替换:{decodedThisRun}/{techsThisRun}/{expThisRun}/{bossKillsThisRun}/{blueprintsAfter}/{milestonesCount}/{milestonesList}/{tideCount}/{tideNames}/{perksList}/{minutes}
|
||||
- buildLore 改造:优先 buildHandwrittenLore,无匹配(ascensionNumber 异常)时 fallback 到 v0.4 模板拼接
|
||||
- 验证:bun 脚本测试 5 纪元 × 2 上下文(minimal/rich)= 10 个 case 全通过,文字长度 233-273 字(含收尾段),变体匹配正确,变量替换无残留 {xxx}
|
||||
- **P3 socket 多人同步星潮**:
|
||||
- **mini-service(mini-services/star-tide-service/)**:
|
||||
- 独立 bun 项目,package.json type=module + scripts dev:bun --hot index.ts + start:bun index.ts,依赖 socket.io ^4.8.3
|
||||
- index.ts(250 行):
|
||||
- 端口固定 3031,path:"/"(Caddy 据此转发)
|
||||
- 6 种星潮类型表(crystal/resonance/ruins/void/core/silence)+ 权重表 + rollTide
|
||||
- DURATION_SEC=60s 全球星潮持续;FIRST_TIDE_DELAY_MS=60s(QA 友好,env 可覆盖);MIN/MAX_GAP_MS=10-15 分钟随机间隔
|
||||
- 调度:startTide → io.emit("global-tide", {type,name,startedAt,endsAt,durationSec}) → 60s 后 endTide → io.emit("tide-ended", {endedAt,nextTideAt}) → scheduleNextTide(10-15 分钟随机)
|
||||
- 客户端连接:socket.emit("tide-state", {current, nextTideAt, serverTime}) 立即推送
|
||||
- 客户端可 emit "get-next-tide" → 服务端响应 "next-tide-info" {current, nextTideAt, serverTime, remainingMs}
|
||||
- dev/QA 用 "admin-trigger-tide":立即触发一次全球星潮(不等待下次定时器)
|
||||
- 优雅退出:SIGTERM/SIGINT → 清 timer → io.close → httpServer.close → exit(0)
|
||||
- README.md:API/事件文档
|
||||
- **前端集成**:
|
||||
- src/hooks/useGlobalTide.ts(127 行):
|
||||
- 单例 socket(sharedSocket + connectRefCount 引用计数,多组件挂载共享同一连接)
|
||||
- io("/?XTransformPort=3031", {transports:["websocket","polling"], reconnection:true, reconnectionAttempts:Infinity})
|
||||
- 监听 "global-tide" → triggerRef.current(type),用 startedAt+type 去重(防重连重复触发),过期 tide 不触发
|
||||
- 监听 "tide-state" → 连接/重连时若服务端正有进行中的全球星潮,补触发
|
||||
- 主动 emit "get-next-tide" 保险
|
||||
- 导出 adminTriggerGlobalTide(dev 控制台 QA 用),window.__adminTriggerGlobalTide 暴露
|
||||
- gameStore.ts 新增 triggerGlobalTide action + globalTide state:
|
||||
- GLOBAL_TIDE_DURATION_MS = 60_000 常量
|
||||
- GlobalTideState 类型 {type, startedAt, endsAt, id}
|
||||
- TideEvent 新增 isGlobal?: boolean 字段
|
||||
- triggerGlobalTide(type):创建 newTide(60s)+ newGlobalTide,覆盖本地 activeTide(即使本地有进行中的星潮也会被替换),加入 _tideEvents 队列 with isGlobal:true
|
||||
- tickTide 改造:globalTide 优先 → 全球星潮进行中本地不触发新星潮;全球星潮结束时设 globalTide:null + activeTide:null + lastTideEnd + silenceCompensation + ended 事件 with isGlobal:true
|
||||
- partialize 排除 globalTide(瞬态运行时状态,不持久化)
|
||||
- page.tsx 顶层挂载 useGlobalTide()
|
||||
- StarTide.tsx UI 升级:
|
||||
- StarTideIndicator:读 globalTide → isGlobal 标记 → 加 🌐 emoji + ring-1 ring-amber-300/60 + 强化 boxShadow + 渐变背景 + title 改为 "🌐 全球星潮 · {meta.desc}";duration 用 globalTide.endsAt-startedAt 计算(60s)避免越界
|
||||
- StarTideOverlay:全球星潮多一道顶部琥珀色光带 + global-tide-sweep 2.5s 扫光动画 + inset boxShadow 加深(160px vs 120px)
|
||||
- StarTideNotifier:toast 文案区分全球/本地("🌐 全球星潮降临:{name}" + "全球玩家同步经历 · {desc}")
|
||||
- **QA 验证**:
|
||||
- `bun run lint` 零错误零警告
|
||||
- dev.log 全程无错误,编译 < 70ms,HTTP 200
|
||||
- mini-service 启动稳定:pid 9456,PPID=1(双 fork 脱离 dev.sh),uptime 19+ 分钟,端口 3031 监听正常
|
||||
- curl http://localhost:3031/ → {"code":0,"message":"Transport unknown"}(socket.io-only 服务预期响应)
|
||||
- curl http://localhost:3031/socket.io/?EIO=4&transport=polling → 正确握手 {"sid":...,"upgrades":["websocket"]}
|
||||
- 网关路由验证:curl http://localhost:81/socket.io/?EIO=4&transport=polling&XTransformPort=3031 → 通过 Caddy 转发到 3031,返回正确握手
|
||||
- socket.io 端到端测试(bun 脚本 /tmp/test-socket.ts):connect ✅ → tide-state ✅ → emit admin-trigger-tide → 504ms 内收到 global-tide {type:ruins, startedAt, endsAt, durationSec:60} ✅
|
||||
- agent-browser 集成测试(通过 http://localhost:81/ 走 Caddy 网关,socket.io 才能正确路由):
|
||||
- 页面加载 200,window.__adminTriggerGlobalTide 已挂载(useGlobalTide hook 已挂载)
|
||||
- 调用 adminTriggerGlobalTide() → 1-3s 内 StarTideIndicator 渲染 🌐 芯片
|
||||
- DOM 验证:芯片文本 "🌐✷虚空低语57s",title "🌐 全球星潮 · 虚空传来回响,洞见获取翻倍"(isGlobal:true 路径生效)
|
||||
- 第二次触发:"🌐⬢遗迹共振59s",title "🌐 全球星潮 · 远古遗迹苏醒,探险力 +5、生命 +30"
|
||||
- 全球星潮结束(60s 后)→ activeTide:null + globalTide:null + lastTideEnd 更新 → 本地 tickTide 恢复正常节奏
|
||||
- VLM 视觉评分:**8/10**(确认 🌐 地球图标 + 汉字名称"遗迹共振" + 倒计时"59s" 全部可见;颜色 emerald/amber/fuchsia/rose 四色规范,零蓝色)
|
||||
- 编年史 buildLore 验证(bun 脚本测试 5 纪元 × 2 上下文 = 10 case):
|
||||
- 全部产出 233-273 字文学性叙事,包含开场+中段+结尾+收尾段
|
||||
- fallback 路径:默认文本,无变量替换
|
||||
- variant 路径:按 ctx 命中条件挑变体,{decodedThisRun}/{bossKillsThisRun}/{milestonesList}/{perksList} 等变量正确替换
|
||||
- 纪元名生成正确:第一纪元·初鸣之夕 / 第二纪元·光谱涌动 / 第三纪元·星辉汇聚 / 第四纪元·以太共振 / 第五纪元·永恒闭环
|
||||
|
||||
Stage Summary:
|
||||
- ✅ 工单 #9:chronicle.ts EPOCH_LORE 5 纪元 × 3 节点 = 15 段手写叙事(每段 80-150 字文学性),buildLore 优先手写节点 + fallback 模板,buildChronicleEntry/regenerateLoreFromEntry/withPerks 全部接入;10 case 测试通过,变体匹配 + 变量替换正确
|
||||
- ✅ P3 socket 多人同步星潮:mini-services/star-tide-service 独立 bun 项目,socket.io 端口 3031,每 10-15 分钟随机广播 global-tide(60s 持续),admin-trigger-tide 供 QA 触发;前端 useGlobalTide hook + gameStore.triggerGlobalTide + globalTide 状态 + tickTide 全球优先 + StarTide UI 🌐 标记 + toast 区分全球/本地
|
||||
- ✅ 网关规范:socket.io 严格用 `io("/?XTransformPort=3031")`,path "/",禁止 localhost:3031 直连;Caddy :81 → localhost:3031 转发正确
|
||||
- ✅ 离线容错:socket.io 自动重连(Infinity attempts),断连期间本地 tickTide 继续按原节奏工作,玩家不会被卡住;globalTide 不持久化(瞬态运行时状态)
|
||||
- ✅ 防重连重复触发:useGlobalTide 用 startedAt+type 去重(Set 上限 32 条 FIFO 清理),过期 tide 不触发
|
||||
- ✅ 本地星潮保留:全球星潮是增强而非替换,全球星潮结束后本地 tickTide 恢复正常节奏
|
||||
- ✅ mini-service 启动稳定:pid 9456,PPID=1,uptime 19+ 分钟,端口 3031 监听正常
|
||||
- ✅ lint 零错误 + dev HTTP 200 + VLM 8/10(🌐 全球星潮标记清晰可见)
|
||||
- ✅ 严格四色规范:全球星潮琥珀色扫光(amber)+ 各星潮本色(emerald/rose/amber/fuchsia),零蓝色
|
||||
- 下一阶段工单:可考虑 v0.9 收尾(全球星潮成就/编年史全球星潮高亮/星图天文台全球星潮增强天赋)
|
||||
|
||||
Reference in New Issue
Block a user