P0+P1+P2+P3 全部落地:剧情错触发、主操作台 11→4+7、揭幕仪式、4 步引导。 本文档对照方案 v1 逐节点梳理"实际跑起来时玩家会看到什么", 标记 8 处字面落地但仍需打磨的细节,输出 P4+ 建议清单。
always 条件,会被 useUnveilDetector 检测为"刚解锁" → 弹出"预警中枢上线"揭幕。⚠️ 见问题 #1setHasOpenedLedger(true) → 引导自动跳到第 2 步。requiredStaff: ['li'] → 后院启用揭幕 弹出。dazui_supply_shortage / duan_zhi_visit 现在会被正确选中(之前可能因为权重不够被埋没)。day_guo_front_door / martial_match_guo_guard 现在能正确触发(之前会穿帮)。setHasTriggeredEvent(true) → 引导跳到第 4 步。setOnboardingDismissed(true) → 写 localStorage,二次进游戏不再触发。bai_secret_old_friend / martial_match_bai_old_debt / night_rooftop_steps 现在能被正确选中。ling_tengyun_case / martial_match_xiucai_words 角色线解锁。AuctionTab 主操作台接入,玩家开始经历"客栈停业参拍"模式(沿用方案文档里描述的衙门重地 UI)。触发链路:staff[id].unlocked: false → true → useUnveilDetector 检测 → queueRef.push → 弹窗。
| StaffId | 角色 | 档案 | 触发时机 | 状态 |
|---|---|---|---|---|
tong | 佟湘玉 | 👩💼 离线+2%/级 | 默认 unlocked,不触发揭幕 | 元老 |
li | 李大嘴 | 🍳 菜品+5/级 | 默认 unlocked,不触发揭幕 | 元老 |
guo | 郭芙蓉 | 🥊 排山倒海 | 玩家花 200 铜钱招募 | 触发 |
bai | 白展堂 | 🥋 盗圣巡堂 | 玩家花 150 铜钱招募 | 触发 |
lu | 吕轻侯 | 🎓 子曰账法 | 玩家花 350 铜钱招募 | 触发 |
| Tab | 解锁条件 | 评估函数 | 状态 |
|---|---|---|---|
| 账本 | always | kind: 'always' | 核心 |
| 门客 | always | kind: 'always' | 核心 |
| 后厨 | always | kind: 'always' | 核心 |
| 行囊 | dayMin: 4 | ctx.day >= 4 | 核心 |
| 菜谱 | ≥ 2 道菜解锁 | ctx.unlockedDishesCount >= 2 | 第 8 日± |
| 后院 | 招募李大嘴 | staff.li.unlocked | 元老即解锁 |
| 设施 | 招募郭芙蓉 | staff.guo.unlocked | DAY 70± |
| 闯荡 | 招募白展堂 | staff.bai.unlocked | DAY 140± |
| 预警 | always | kind: 'always' | DAY 1 |
| 竞拍 | dayMin: 270 | ctx.day >= 270 | DAY 270 |
| 联机 | reputation ≥ 500 | ctx.reputation >= 500 | 中后期 |
修复方案:selectWeightedGameEvent 在权重计算前先调用 isStaffRequirementSatisfied(event, state.unlockedStaff),硬性短路 → 权重 0.01。
// selection.ts · L196 起的权重循环 const weights = events.map((event) => { if (!isDayWindowAllowed(event, state.day)) return 0.01; // 🔒 新增:硬性短路 if (!isStaffRequirementSatisfied(event, state.unlockedStaff)) return 0.01; ... }); // App.tsx · 调用处 selectWeightedGameEvent({ ..., unlockedStaff: getUnlockedStaffSet(current.staff), });
已标注的 12 个事件:mainline-tournament × 4 + role-guo-lu × 1 + role-bai-tong × 1 + role-dazui × 2 + side-night-risk × 2 + side-official × 1 + storyline-bai-tong-pilot × 1。
| localStorage Key | 用途 | 写入时机 | 状态 |
|---|---|---|---|
tongfu_unveil_dismissed_v1 | 揭幕仪式的"已展示"key 集合 | 玩家关闭任意揭幕弹窗 | 已实现 |
tongfu_onboarding_dismissed_v1 | 新手引导是否被跳过 | 点"跳过"或完成第 4 步 | 已实现 |
tongfu_onboarding_step_v1 | 新手引导当前进度(stepIdx) | — | 未实现 |
prevUnlockedTabsRef 初始化是空 Set,DAY 1 启动时所有"已经满足条件"的 tab(包括预警 always)都被检测为"新解锁",触发预警中枢揭幕。但预警从 DAY 1 就该常驻,不应该"揭幕"。
skipAutoUnveil: true。ConsoleTabsBar 只在 hover 时显示锁住进度,Tab 从灰→朱砂亮起的瞬间没有额外脉冲动画。玩家可能完全没注意到新开了哪个 Tab。揭幕仪式会弹窗,但玩家关掉弹窗后,再去看 Tab 条,可能已经忘了刚才解锁的是哪个。
animate-pulse 类 3 秒;同时弹一个角落 toast"行囊 已解锁 →"。招郭芙蓉会同时触发 2 个揭幕(郭芙蓉 + 设施 Tab)。dismiss 用 setTimeout(50ms) 取下一个,玩家刚按"接纳招募 →",下一个 0.05 秒后就弹出——体验像连弹。
stepIdx 是组件本地 state,没写 localStorage。玩家做到第 2 步退游戏,下次进游戏会从头开始(虽然不会从 0 触发,因为 onboardingDismissed 还是 false,但会从第 1 步重新显示)。
tongfu_onboarding_step_v1 写 stepIdx;初始化时读。CinematicUnveilModal 支持 kind: 'event_unveil',但 useUnveilDetector 没接入任何大事件触发(如擂台赛开幕 / 旧账风波 / 年终大戏)。这些是方案 v1 设计的"重头戏揭幕"。
event:xxx key 入队。当前所有 11 个 Tab 仍然平铺,5 个🔒的收纳 Tab 也会占据 Tab 条空间。LayoutTab 类型预留了 'more',但 ConsoleTabsBar 没渲染。
项目已有 YEAR1_PLAN_PHASES 12 月规划(keyNodes: 开业大吉/三日小结/招募吕秀才/食安风波/...),但 OnboardingCoach 没用它。引导只覆盖 4 步"操作型",不覆盖"剧情型"(月 3 食安风波/月 6 擂台赛/月 9 官府竞标/月 12 岁末大戏)。
ConfettiBurst 内部用 getBoundingClientRect 计算 originX/originY。Modal 是 fixed inset-0 z-130,理论上 OK,但首次渲染时容器可能还没稳定,粒子可能从屏幕外飞。
useLayoutEffect 替代 useEffect;在 onClose 后 50ms 内不要清空粒子。| P 级 | 项 | 改什么 | 工作量 | 影响 |
|---|---|---|---|---|
| P0 | ① DAY 1 预警误触发 | unveilTriggers.ts 初始化 prevUnlockedTabs | 0.5 小时 | 消除一启动就弹的尴尬 |
| P0 | ② Tab 解锁脉冲 + 角落 toast | ConsoleTabsBar + Toast 组件 | 1 小时 | 让玩家真看到新 Tab |
| P0 | ③ 揭幕间隔拉到 800ms | unveilTriggers.ts dismiss | 0.5 小时 | 消除连弹 |
| P1 | ④ onboarding 进度持久化 | OnboardingCoach + localStorage | 0.5 小时 | 中途中断不丢进度 |
| P1 | ⑥ "更多"折叠抽屉 | ConsoleTabsBar | 2 小时 | 11→6 一行清爽 |
| P1 ✅ | ⑤ event_unveil 触发接入 | 已实现 EVENT_UNVEIL_PROFILES + enqueueEventUnveil;监听 tournament setup/final/cooldown + day≥330 岁末 + old_ledger_opening | 已落地 | 擂台赛 / 旧账 / 岁末有仪式 |
| P2 | ⑦ year1Plan 12 步剧情引导 | OnboardingCoach 改成 N 步 | 3 小时 | 覆盖到第 12 个月 |
| P2 | ⑧ ConfettiBurst 时序 | useLayoutEffect + 延迟清空 | 0.5 小时 | 粒子更稳 |
| P2 | storyline-guo-lu-pilot 触发器 | storyline 任务触发接入 unveil | 1 小时 | 郭芙蓉入伙有专属揭幕 |
| P3 | 角色升级揭幕(Lv 5 / Lv 10) | unveilDetector 检测 level 跃迁 | 2 小时 | 养成的额外正反馈 |
| P3 | 移动端 CoachMark 适配 | OnboardingCoach 改 viewport < sm 时换位置 | 1 小时 | 移动玩家体验 |
| P3 | "跳过本步 / 跳过全部" 区分 | OnboardingCoach 拆按钮 | 0.5 小时 | 更细颗粒度 |
day_guo_front_door / martial_match_guo_guard 现在能被触发(之前因为 unlocked=false 被屏蔽)localStorage.tongfu_unveil_dismissed_v1 包含 "staff:guo" 和 "tab:facilities"martial_match_bai_old_debt / bai_secret_old_friend / night_rooftop_steps0.01