ABYSSAL ANSWERS · 学习手册

这是对 Krillion 交互模型的清洁室学习实现:保留“七轮开放题、限时回答、稀有度计分、向深海下潜”的产品骨架,题库、文案、品牌与美术均独立重写或生成。

原网站主要做什么?

Krillion 是开放式答案的每日知识游戏。玩家不是从选项里选择,而是在每题 25 秒内自由输入一个答案;系统按答案在预设统计/题库中的稀有程度分档,越少见的有效答案分数越高,潜水深度也越深。每日主局共七题,另有 Unlimited 与电影、体育、地理主题包。

原站可见页面包括首页每日局、主题包列表、Movies、Sports、Geography、Unlimited Classic 和购买恢复页。它的内容重点不是解释知识,而是让玩家在宽泛题目下快速联想,并用“别人是否也想到它”制造结果惊喜。

技术栈拆解

框架Next.js 16.3.1 App Router(本项目固定安全补丁版)
界面React 19.2.8、TypeScript、Tailwind CSS 4、自定义 CSS
动态场景Canvas 2D:水层、焦散、气泡、沉积、潜艇、粒子与下降镜头
声音Web Audio:首次手势后创建,静音状态持久化
服务端Route Handlers:公开题面与私有答案评分分离
本地状态Reducer 状态机 + 带版本号的当前局存档和完成局历史
质量Vitest、Testing Library、ESLint、严格 TypeScript

对原站运行时代码的检查显示,它同样采用 Next.js 16、React、Turbopack、Tailwind CSS 风格输出、Canvas 2D、Web Audio 和 localStorage;还加载了 Firebase/Google 登录、Stripe 支付链接、GA4 与 Vercel 托管相关代码。本地学习版刻意不接入登录、支付和分析。

完整状态流

loading → intro → preview → answering → feedback
                    ↑                         │
                    └──── next round ─────────┘
                                              └→ results

preview 使用 3 秒绝对截止时间,answering 使用 25 秒绝对截止时间。保存的是时间戳,不是“剩余秒数”,因此刷新页面不会把计时器重置。最后一题仍先展示反馈,再进入七轮总结。

截止前发出的评分请求会完成仲裁,不会被同一时刻的计时器抢先记为超时;截止后才发出的请求会被拒绝。恢复存档时还会核对当前题面、结果顺序和等级固定分值,异常副本不会进入状态机。

计分与深度

等级分数下潜
Plankton10100 m
Too Clever15150 m
Schooler30300 m
Rare60600 m
Deep Cut85850 m
One in a Krillion1001000 m

未命中和超时为 0 分。每 1 分等于 10 米,七题理论最高 700 分 / 7,000 米。本项目先做 Unicode 兼容归一化、去音标、标点折叠和别名匹配,不做模糊匹配,便于学习和测试。

为什么答案不能随题面一起发给浏览器?

GET /api/daily

{
  id,
  diveNumber,
  prompts: [{ id, text }]
}

只返回可公开的题号与题面。

POST /api/submit

{ diveId, promptId, answer }
→ { accepted, tier, score, quip }

服务器验证长度与字段,再访问私有答案表。

Canvas 与 DOM 的职责边界

代码地图

src/content/dive.ts私有题目、答案别名与稀有度数据
src/game/reducer.ts纯函数游戏状态机与累计成绩
src/game/use-game-machine.ts计时、请求、恢复与副作用编排
src/app/api/*去敏题面接口和服务器评分接口
src/game/ocean-engine.ts不触发 React 重渲染的 Canvas 循环
src/game/sound-engine.ts延迟初始化的合成音效
src/components/game/*HUD、题面、答题、反馈和结果组件

安全版本选择

工程把 Next.js 精确固定为 16.3.1,把 React 与 React DOM 精确固定为 19.2.8,不使用 ^、canary 或实验版。最初选择的 16.2.11 修复了 2026 年 7 月披露的问题;最终验收时 npm 又报告其内置 PostCSS/Sharp 出现新的 high advisories,因此升级到审计干净的 16.3.1。

参考:Next.js BlogCVE-2025-66478支持策略

扩展练习

  1. src/content/dive.ts 新增第八组独立题目,并把轮数抽成主题配置。
  2. 为每个主题增加单独的背景与色板,而不改 reducer 的状态转换。
  3. 把确定性等级替换为匿名聚合统计,同时保持评分接口不泄露明细。
  4. 把本地完成局历史做成趋势图,并按主题比较平均深度。
  5. 模拟断网、禁用 Canvas、禁用 Web Audio,确认 DOM 主流程仍可完成。