# AI Agent Project **Repository Path**: wuruipeng_admin/ai-agent-project ## Basic Information - **Project Name**: AI Agent Project - **Description**: 用于AI Agent日常化协作开发用 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-21 - **Last Updated**: 2026-10-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: AI ## README # Snake3D 贪吃蛇 3D 桌面端。Electron + React + TypeScript + Three.js(React Three Fiber)。 不是「跑起来就算」的 demo 仓库:它把**约束、版本、文档、提交**四件事一起工程化,用来验证一件事—— 当 AI agent 参与开发时,靠一套可加载的规则文件能不能把产出稳定在同一个水准上。 | 项 | 值 | |---|---| | 仓库 | `ai-agent-project`(Gitee),**本地克隆目录名与仓库同名**,文档中的根目录一律写这个 | | 形态 | Electron 桌面应用(Windows / macOS) | | 渲染 | React 19.3.1 + Three.js 0.186.1,走 R3F 9.8.2 声明式场景 | | 逻辑 | 纯 TypeScript,零框架依赖,可单测 | | 进程 | 主进程 `app/main`、预加载 `app/preload`、渲染层 `src`、契约 `shared` | | Node | **v18.0.0 / 18.x**(`.npmrc` 开了 `engine-strict`,不匹配直接拒绝安装) | | 状态 | `v0.2.0`(tag `v0.2.0`)**P5 已收尾**:P5-1 音效与每关 BGM、P5-2 开场动画、P5-5 选关背景已入库,另有 P4 兜底修复与打包体积优化(134.8MB → 109.3MB);P5-3/4/6/7/8 未启动、已挂起。**下一步是 P6(Boss 战),当前只留了接缝,未开工**。P4 28 条 + P5 3 条实机验收推迟 | --- ## 一、快速开始 ```bash # 0. 确认 Node 是 18.x(本项目所有版本都由它反推,换版本装不上) node -v # 期望 v18.x npm -v # 期望 8.6.0 # 1. 安装(有 lockfile 时优先 npm ci,精确还原) npm ci # 2. 开发(主进程 / preload / 渲染进程一起起,渲染层带 HMR) npm run dev ``` > **两个必踩的坑,先看再跑** > > 1. **PATH 上的 Node 必须是 18。** `npm.cmd` 本身可以跑 18,但它派生的 `preinstall` 钩子会走 PATH 上的 `node`。 > 如果 PATH 上是 20/22,守卫脚本会报「Node 版本不匹配」——这不是脚本错,是调用链的 Node 不一致。 > 2. **`ELECTRON_RUN_AS_NODE=1` 会让 Electron 不弹窗。** 某些工具链会预设这个变量,Electron 会退化成纯 Node。 > 启动前 `unset ELECTRON_RUN_AS_NODE`(CMD:`set ELECTRON_RUN_AS_NODE=`)。 首次安装会额外下载约 100MB 的 Electron 二进制,走 `.npmrc` 里的 `electron_mirror`(npmmirror)而不是 GitHub。 --- ## 二、为什么版本这么"旧" 这是本仓库最反直觉的部分:**没有任何一个版本是"选最新的"**,全部由 Node 18.0.0 反推。 三条实测教训(不是推测,是装到一半炸出来的): | 现象 | 真相 | 结论 | |---|---|---| | `electron@41.10.7` 装不上 | 41.7.2 起 `engines.node` 被改成 `>=22.12.0`,且改动回填到 40.10.6 | 锁 **41.7.1**(最后一个支持 18 的) | | `vite@6` 声明支持 18,启动即崩 | `engines` 写 `^18.0.0`,代码却用 `node:fs/promises` 的 `constants`(需 ≥18.13) | 降到 **5.4.21** | | `electron-builder@25/26` 装不上 | 25 起 `app-builder-lib` 拉 `minimatch@10 → brace-expansion@5.0.8+`(node 20+) | 降到 **24.13.3** | 还有一条更贵的教训:**不要用 `overrides` 硬降 engines 违规的包**。 把 `brace-expansion` 钉到 5.0.6 确实能装,但一跑就 `brace_expansion_1.default is not a function`——导出形态变了。 正确做法是降父包。当前 `overrides` 只剩一条 `camera-controls: 2.10.1`(drei 10 要 `^3.1.0`,3.x 全线要求 node ≥20.11), 代价是**不能使用 `` 组件**,项目用固定正交相机,不需要它。 ### 依赖矩阵(完整版见 `.claude/rules/node-baseline.md`) | 包 | 版本 | 卡点 | |---|---|---| | electron | 41.7.1 | 41.7.2+ 要 node ≥22.12 | | electron-vite | 3.1.0 | 4+ 要 node ≥20.19 | | vite | 5.4.21 | 6 的 engines 撒谎(见上表) | | electron-builder | 24.13.3 | 25+ 的 minimatch 链要 node 20+ | | react / react-dom | 19.3.1 | R3F 9 的 peer 是 `>=19 <19.4`,写 `^19` 会漂到 19.4+ 报 ERESOLVE | | three / R3F / drei | 0.186.1 / 9.8.2 / 10.7.9 | — | | typescript | 5.3.3 | 5.4+ 超出 typescript-eslint 6 的支持区间,lint 会静默降级 | | eslint | 8.57.1 | 9 起要 node ≥18.18,且默认 flat config 与 ts-eslint 6 不兼容 | | vitest / jsdom | 3.2.7 / 26.1.0 | vitest 4、jsdom 27 都要 node ≥20 | | ~~@vitest/coverage-v8~~ | 不安装 | 传递链要 node 20+,所以 `test:cov` 这个脚本不存在 | 版本写法统一**精确锁**(无 `^` / `~`),`.npmrc` 里 `save-exact=true` + `engine-strict=true` 双保险。 新增依赖前必须走准入流程:`npm view engines` 的区间要包含 **18.0.0 这个精确点**, `^18.18.0` 不算通过(18.0.0 < 18.18.0)。 --- ## 三、基础架构 ### 目录 ``` ai-agent-project/ ← 项目根,同时是渲染层的 Vite root ├── index.html ← 渲染入口(在根,不在 src 下) ├── app/ ← Node 侧 │ ├── main/ ← 主进程 │ │ ├── index.ts ← 单实例锁、生命周期、平台差异 │ │ ├── window.ts ← 建窗唯一入口:安全配置 + CSP + 导航拦截 │ │ ├── ipc/index.ts ← handler 集中注册,出参校验,统一返回形态 │ │ └── services/save.ts ← 原子写 + 损坏备份(结构校验与迁移在 shared/save-schema.ts) │ └── preload/index.ts ← contextBridge 唯一出口 ├── shared/ ← 三端共享:ipc-contract / save-schema / levels / settings ├── src/ ← 渲染侧 │ ├── game/ ← 纯逻辑(零 react/three 依赖,可单测) │ ├── scene/ ← Three.js / R3F(camera 取景 · entities 蛇与食物 · loaders 资源管线) │ ├── ui/ ← DOM 层:Hud / 悬浮数字 / 标题 / 选关 / 教程 / 结算 / 背景层 │ ├── flow/ ← 阶段机 + GameSession/GameLoop + BGM 接线 │ ├── audio/ ← BGM 单例:注册表 / 时序 / 淡入淡出 │ ├── input/ store/ styles/ ├── scripts/ ← check-node / audit-engines / vite-plugin-csp ├── build/ ← 打包图标与资源(入库) └── .claude/ ← rules / skills / docs(规范即代码) ``` ### 分层与数据流 三层依赖单向,反方向一律禁止: ``` 主进程 app/main → 只能依赖 shared/(禁止 import src/、禁止 import three/react) 预加载 app/preload → 只能依赖 shared/(只暴露白名单方法,不暴露 ipcRenderer 本体) 渲染层 src → 只能依赖 shared/(禁止 import electron、禁止 require、禁止直接读写文件) ``` 渲染层内部按「命令进、快照出」单向流动: ``` input/ ──命令──▶ game/(权威状态,纯函数,固定步长 tick) │ 每 tick 产出不可变快照 ▼ store/(zustand:只读快照 + UI 状态) │ │ ▼ ▼ scene/(R3F) ui/(DOM) ``` 两条硬约束:**逻辑推进只走固定 tick,不许拿 `useFrame` 的 delta 当步长**; **游戏权威状态在 `game/`,store 不参与计算**,否则会出现双写抖动。 当前棋盘是 **50×50 世界单位、连续坐标(非网格)**,逻辑步长 `FIXED_DT_S = 0.016`、单帧最多补 5 步; 常量在 `game/config/{board,snake,food}.ts`,核心在 `game/core/`(`snake/` 与 `food/` 两个子模块 + `step` 的 7 个组合槽位, 玩法判定在 `core/rules/`),相机取景数学在 `scene/camera/framing.ts`(纯函数,可单测)。 ### 进程通信 ``` 渲染层 window.api.save.load() → preload: ipcRenderer.invoke(IPC.saveLoad) → 主进程 ipcMain.handle → 读 userData/save.json ← { ok: true, data: SaveData } | { ok: false, error: string } ``` | 规则 | 说明 | |---|---| | channel 名 | 只允许来自 `shared/ipc-contract.ts` 的 `IPC` 常量,三端禁止手写字符串 | | 通信方式 | 只用 `invoke` / `handle`,不用 `send` + `on`(传不回错误) | | 入参 | 主进程落盘前必过 `isSaveData` 校验 | | 失败 | 统一 `{ ok: false, error }`,不把异常抛给渲染层 | 现有通道:`save:load`、`save:write`、`app:version`、`window:toggle-fullscreen`、`window:set-size`、`app:quit`。 ### 安全基线(不得放宽) ```ts webPreferences: { contextIsolation: true, nodeIntegration: false, sandbox: true, webSecurity: true, webviewTag: false, nodeIntegrationInSubFrames: false } ``` 配套:`setWindowOpenHandler` 一律 deny(仅 https 交系统浏览器)、`will-navigate` 拦截非内部地址、 阻止 `will-attach-webview`、CSP 分开发/生产两套(生产无 `unsafe-eval`,构建期由 `scripts/vite-plugin-csp.ts` 注入 meta)。 > Electron 41 已超出官方维护窗口,拿不到 Chromium 安全补丁。所以「不加载任何远程内容」是**硬约束**,不是风格偏好。 > 哪天要联网、内嵌页、打开外链,先升级 Node,再升 Electron。 ### Windows / macOS 差异 | 关注点 | Windows | macOS | |---|---|---| | 关窗 | 退出应用 | 留在 Dock,`activate` 时重建窗口 | | 应用标识 | `setAppUserModelId('com.snake3d.app')` | no-op | | 菜单栏 | `autoHideMenuBar` | 保留系统菜单 | | 存档 | `%APPDATA%/snake3d/save.json` | `~/Library/Application Support/snake3d/save.json` | | 安装包 | nsis 安装版(x64,向导式;`portable` 已于 2026-10-23 移除) | dmg(x64 + arm64) | | 签名 | 未签名(`signAndEditExecutable: false`) | `identity: null` 跳过 | --- ## 四、规范体系(`.claude/`) ``` .claude/ ├── rules/ 13 份约束,00-index.md 是唯一入口 ├── skills/ 15 个技能(14 个实现类 + ai-commit),README.md 是地图 └── docs/ 按 {版本}/{需求}/ 归档,01 需求 → 05 用例 ``` `.claude/rules/00-index.md` 是入口,定义 8 条**全局红线**(不可豁免)与「按场景加载」矩阵: | # | 红线 | |---|---| | R1 | 禁止虚构:没实际跑过不许说"通过" | | R2 | 逻辑层纯净:`src/game/**` 不得 import react / three / DOM API | | R3 | tick 与帧解耦:逻辑步长只走固定 tick | | R4 | 安全三件套不放宽;渲染进程不直连 `ipcRenderer` | | R5 | 资源必须释放:Geometry / Material / Texture / 监听 / 定时器 | | R6 | 改前先读:引用前必须真读过文件,不凭记忆写 API | | R7 | Node 18.0.0 基线不可破:不用 `--force`、不关 `engine-strict` | | R8 | 禁止固化单一形态:不假设"只有一条蛇/一张固定棋盘/一个输入源" | 规则分三级:**红线**(无豁免)/ **黄线**(可豁免但要留痕)/ **绿线**(设计方向,小任务可简化)。 豁免必须写在代码里,格式固定: ```ts // [RULE-EXEMPT 2026-10-21] code-quality#no-any:three 的类型定义此处为外部 union,收敛成本高于收益 ``` 冲突时按序裁决:`node-baseline` > 全局红线 > `electron-security` > `architecture` > `extensibility` > 领域规则 > `code-quality` 黄绿线 > 既有代码风格。 | 文件 | 管什么 | |---|---| | `node-baseline.md` | Node 18 反推的版本矩阵、依赖准入四步、报错速查(**最高优先级**) | | `project-stack.md` | 技术栈、目录、命令、打包、14 条版本陷阱 | | `architecture.md` | 三层依赖表、渲染层单向流、状态归属、结构接缝、反模式 | | `extensibility.md` | 接缝不写空壳、未来形态封闭清单、单例禁令、可抽离检查表 | | `game-core.md` | 连续坐标与边界策略、固定步长、`step` 组合顺序、逃脱值累加、多蛇就绪 | | `rendering-three.md` | 单 Canvas、`useFrame` 六条红线、实例化阈值、资源释放、性能验收线 | | `electron-security.md` | 安全三件套、双套 CSP、IPC 契约、preload 白名单、存档原子写 | | `typescript-conventions.md` | strict 全家族、禁 `enum`/`any`、品牌类型、路径别名 | | `code-quality.md` | 7 条红线 + 命名/注释要求 + 分规模审查清单 | | `testing.md` | 覆盖率门槛、15 项必测、五项交付验证 | | `git-conventions.md` | 9 个 type、10 个 scope、分支命名、ignore 口径 | | `document-driven.md` | `01`–`05` 三段式归档模板与触发条件 | --- ## 五、AI agent 开发理念 这套东西不是为了"让 AI 写得更快",而是为了**让 AI 的产出可验证、可追溯、可复现**。七条: **1. 约束前置,而不是事后 review** 规则写成文件放在 `.claude/rules/`,会话起始先读 `00-index.md`。等 AI 写完再挑错,成本是前者的十倍; 而且挑错的还是人,等于没省。 **2. 单一真相源,禁止第二份定义** 版本只在 `node-baseline.md`、channel 名只在 `shared/ipc-contract.ts`、游戏状态枚举只在对应类型文件、 type/scope 只在 `git-conventions.md`。其他地方只能引用,不能复述。复述就是漂移的起点。 **3. 禁止虚构,验证必须留证据** 「构建通过」「测试通过」这类话必须有命令输出兜底,没有产物不算完成(R1)。 所以本仓库的交付文档里,每条验证都写命令和结果,包括**没验证的项**也明写「未做 + 原因 + 风险」。 **4. 先读再写,API 不许凭记忆** R6。AI 最容易犯的错是"看起来像"的 API——`useFrame` 的参数、Electron 的 `webPreferences` 字段、 某个包的导出形态。凭记忆写出来的代码 90% 能编译,10% 运行即崩,而这 10% 最难查。 **5. 红线不留豁免口,黄线豁免要留痕** 「安全三件套」和「Node 基线」没有商量空间;代码风格之类的允许破例,但必须在代码里写 `[RULE-EXEMPT]` 和理由。 **没有留痕的豁免等于技术债**,下次没人知道为什么这么写。 **6. 文档驱动交付,不是文档补作业** 中/大任务走 `01 需求 → 02 技术方案 → 03 实施清单 → 04 Review → 05 用例`。 `02` 必须含「版本决策表」(逐包列 `engines` 原文 + 是否含 18.0.0),因为**决策理由比决策本身更容易丢**。 **7. 提交即元数据** AI 提交统一加 `[AI]` 标记 + `Co-Authored-By`,走 `/ai-commit` 技能: 变更体检 → 文档同步 → 风险审查 → 门禁三连 → 规范化 message。 这样 `git log` 能程序化统计「哪些改动是 AI 做的、动了哪些 scope」,出问题时能快速定位影响面。 还有一条隐性的:**踩过的坑要写回规则**。Vite 6 的 engines 撒谎、`overrides` 硬降导致运行时报错, 这些都已经沉淀进 `node-baseline.md` 和 `project-stack.md` 的陷阱表。规则不是一次写好的,是被事故打出来的。 --- ## 六、常用命令 | 命令 | 作用 | |---|---| | `npm run dev` | 三端开发模式(渲染层 HMR,主进程改动重启) | | `npm run typecheck` | 类型校验,node + web 双配置(`build` 前置也会跑一次,但开发过程中要单独跑) | | `npm run lint` / `lint:fix` | ESLint(`--max-warnings 0`) | | `npm run format` / `format:check` | Prettier | | `npm test` / `test:watch` | Vitest(**没有覆盖率**,见第二节) | | `npm run build` | 先 typecheck,再出 `out/{main,preload,renderer}` | | `npm run build:win` | 出 nsis 安装包到 `release/${version}/`(当前 0.2.0 约 109MB;体积核对用 `-c.directories.output=release/_sizecheck`) | | `npm run build:mac` | 出 dmg(x64 + arm64),**必须在 macOS 上执行** | | `npm run build:unpack` | 只解包不封装,排查打包问题用 | | `npm run audit:engines` | 审计整棵依赖树的 `engines` 是否都含 18.0.0 | 交付前五项验证:`typecheck` → `lint` → `test` → `build` → 手跑一局。任一项没跑,交付说明必须写明原因。 --- ## 七、提交约定 ```bash /ai-commit # 按守则走完整流程 /ai-commit -q # 跳过审查,门禁照跑 /ai-commit undo # 撤销最近一次提交,改动回暂存区 ``` 格式(详见 `.claude/rules/git-conventions.md`): ``` feature(game): [AI] 新增食物逃脱与小鸟下蛋 - 逃脱值改为按步累加,支持计时冻结与延迟启动 - 小鸟停留 8s 后下蛋,下蛋期移速 5%、头顶显示圆环 Co-Authored-By: Claude ``` | 规则 | 说明 | |---|---| | type | `feature` / `fix` / `perf` / `refactor` / `style` / `docs` / `test` / `chore` / `build`——用 `feature` 不用 `feat` | | scope | `main` / `preload` / `shared` / `game` / `scene` / `ui` / `input` / `store` / `build` / `rules` | | 只提交不 push | 除非当次明确要求 | | 产物不入库 | `node_modules/` `out/` `release/` `dist/` `coverage/` 已 ignore;暂存前有白名单正则校验 | --- ## 八、当前进度与已知限制 **已完成** - **工程基座**:三端构建链路、IPC 契约与存档读写(原子写 + schema 迁移)、安全基线、CSP 注入、跨平台窗口行为。 - **规范体系**:13 份规则 + 8 条红线 + 15 个技能 + 开发理念与提交守则。 - **P0 流程骨架**:8 阶段状态机(`flow/machine.ts` 纯函数 + `FlowRoot` 按相位渲染)、存档 schema 与迁移、标题/选关/教程/结算/暂停占位闭环。 - **P1 蛇移动与外观**:连续坐标自由转向、体节等弧长跟随、贴墙滑行、嘴部开合、饥饿掉节、固定步长 + 补步上限、滚轮缩放 1×~4×、`starved` → 悬浮数字 `-1`。 - **P1.5 素材接入**:背景图(`cover` 全屏不拉伸 + 6s 水滴波纹折射 + 暗角)、BGM 单例(注册表 + 淡出/补时/淡入 + 同域不打断)。 - **P1.6 实测反馈修正**:启动即播(冷启动 0 延迟 + 预加载)、波纹不等间隔与细环、选关/教程/结算白色 50% 毛玻璃、标题 CSS 3D 立体 + 4s 摇摆 + 波纹期加剧。 - **P2 食物系统**:四类食物(蛋/虫/蛙/鸟)3 槽位、按槽独立补位、权重 5:3:1 刷新、游走与青蛙跳跃、逃脱值按步累加(小鸟下蛋期冻结)、小鸟 8s 下蛋 + 头顶圆环、圆-圆吞食与「先补节后 1:1 折分」、吃到飘 `+N`;表现层四种程序化灰盒 + 蛇头回弹。 - **P2 试玩三轮修正**:食物视觉与判定半径 ×2、生成间距外扩、虫子 15%→10%、每节移速 +1%→+2%、相机取景上移(`AIM_SHIFT_RATIO = 0.12`,解决"地图偏下 / 放大看不到底")。 - **P3 成长与计分 + 关卡系统**:积分唯一写入口(`rules/score.ts`,加减分共用下限规则)、胜负判定下沉(`rules/outcome.ts`,先达标后超时、总积分口径)、`step` 槽位 6 接入并修掉"不吃食物就早退导致超时永不触发"、饥饿扣分、关卡体节上限递增(10/15/20/20)、通关解锁 + 最高分/最短用时落盘、末关「敬请期待后续内容更新」→ 确定回标题、结算用时装整秒。 - **未完成 / 已知缺口**: | 项 | 状态 | 处理 | |---|---|---| | P4 UI(正式 HUD、设置、教程三页、弹窗、选关、天空背景、关卡滤镜 / 草地花纹 / 45° 光照、视角拖拽) | **代码完成** | 门禁四绿(typecheck / lint / 416 条单测 / build);**实机验收 28 条待用户执行**(本机 Electron GPU 崩溃);清单见 `v0.2.0/正式UI/05-测试用例.md` §二 | | P5 打磨(音效 / 每关 BGM / 开场闪电收幕 / 模型与材质 / 特效 / 真阴影 / 草地纹理 / 分包) | **已收尾(部分交付)** | 已入库:P5-1 音效 + 每关 BGM、P5-2 开场动画、P5-5 选关卡片背景;另有 P4 兜底修复(窗口状态/教程文案/字体子集)与打包体积优化(134.8MB → **109.3MB**)。P5-3/4/6/7/8 **未启动、已挂起**,见 `.claude/docs/v0.2.0/P5打磨/03-实施清单.md` §十一 待办;复盘见同目录 `04-Review记录.md`。**逐字彩虹描边做过一版,2026-10-23 用户实机否决、已整体移除** | | P6 Boss 战 | **下一步,未开工(仅留接缝)** | P5 只交付了数据与曲目接缝(`LevelConfig.boss`、`stageBoss`、`phaseToTrack(..., bossActive)`),**没有任何 Boss 实体、触发函数或玩法分支**;开工前先答 `HANDOVER.md` §10.4 的 5 个问题 | | 存档展示(原记为 P6,现顺延为 P7) | 部分 | 解锁与成绩写入已在 P3 打通,缺设置页与成绩展示页 | | 美术资源 | 部分 | 背景图 / BGM / 音效 / 圆体字已入库;**蛇与食物仍是程序化几何**——P5-3 定案"不做 GLB,改材质升级",`public/models/` 继续空着(加载管线保留为接缝) | | 覆盖率 | 无 | `@vitest/coverage-v8` 装不上,只有通过/失败;升级 Node 后补 | | 手工 GUI 验收 | 用户已确认整体 | P1 移动/贴墙/缩放/掉节飘字、P2 进食与操作、P2 取景上移、**P3 完整 playthrough 与关卡/解锁**经实机确认;逐条签字未做,清单见 `v0.2.0/蛇移动与外观/03`、`v0.2.0/食物系统/03`、`v0.2.0/成长与计分/03` | | Windows / macOS 打包 | Windows 部分验证 | `build:win` 可稳定出包(0.2.0 = 109.3MB),`win-unpacked` 直跑 15s 无崩溃;**`setup.exe` 的安装流程未执行**(会写用户目录+建快捷方式,需手动或授权)。macOS `build:mac` 仍未验证 | | 应用图标 | 缺(待办 T1) | 当前打包报 `default Electron icon is used`;补 `build/icon.ico`(≥256²)与 `build/icon.icns` 后加 `win.icon` | | 代码签名 | 无 | 对外分发前需证书;mac 未签名需「右键 → 打开」 | --- ## 九、文档索引 | 想了解 | 去哪 | |---|---| | 规则总入口 | `.claude/rules/00-index.md` | | 玩法需求(唯一真相源) | `.claude/docs/v0.2.0/核心玩法/01-需求分析.md` | | P0 流程骨架的方案与落地 | 同目录 `02-技术方案.md` / `03-实施清单.md` / `04-Review记录.md` | | P1 蛇移动与外观(含缩放、悬浮数字) | `.claude/docs/v0.2.0/蛇移动与外观/{02,03,04}` | | P2 食物系统(四类食物、逃脱、下蛋、吞食结算、取景上移) | `.claude/docs/v0.2.0/食物系统/{02,03,04}` | | P3 成长与计分 + 关卡系统(积分写入口、胜负判定、体节上限递增、解锁与存档) | `.claude/docs/v0.2.0/成长与计分/{03,04,05}` | | P5 打磨(音效与每关 BGM、开场动画、选关背景、待办清单与复盘) | `.claude/docs/v0.2.0/P5打磨/{02,03,04}` | | Boss 战规划(P6,**未启动**,只有接缝) | `.claude/HANDOVER.md` §十 | | 背景图与 BGM 的接入口径(换素材怎么做) | `.claude/docs/v0.2.0/背景图与音频素材/{03,04,05}` | | 每个模块怎么写 | `.claude/skills/README.md`(14 个实现技能的加载地图) | | 将来怎么扩展(双人/联机/换图) | `.claude/rules/extensibility.md` | | 版本为什么这么锁 | `.claude/rules/node-baseline.md` | | 目录、启动、打包细节 | `.claude/docs/v0.1.0/脚手架搭建/02-技术方案.md` | | 落地过程与验证记录 | 同目录 `03-实施清单.md` | | 踩坑复盘(12 条) | 同目录 `04-Review记录.md` | | 待手测用例 | 同目录 `05-测试用例.md` | | 提交守则 | `.claude/skills/ai-commit/SKILL.md` | --- ## 变更记录 | 日期 | 变更 | |---|---| | 2026-10-21 | 初始化工程与规则体系;按 Node 18.0.0 锁定全量依赖 | | 2026-10-22 | 新增 `ai-commit` 技能、精确化 `.gitignore`、首次推送到 Gitee | | 2026-10-22 | 新增本 README;修正 `check-node.cjs` 中残留的 Vite 6 口径 | | 2026-10-22 | 文档根目录名统一为仓库名 `ai-agent-project`(原写作 `design`) | | 2026-10-22 | 需求 v0.2.0 定案:小鸟下蛋期冻结逃脱计时 + 头顶圆环(消除移速与下蛋门槛的互斥)、第 4 关回选关、选关单页最多 3×3 超页分页、标题打包圆体;`game-core.md` 全文重写,新增 `extensibility.md` 与红线 R8 | | 2026-10-22 | P0 落地:流程状态机 + 存档 schema + 清理 7 个旧口径文件 + 打包站酷快乐体子集;`git-conventions` 主干名改 `master` | | 2026-10-22 | P1 落地:`game/core`(连续坐标、等弧长跟随、贴墙滑行、饥饿)+ `input/` + 蛇渲染与资源管线 + `flow/GameSession`;棋盘 20×20 → 50×50、滚轮缩放 1×~4×、掉节飘 `-1` | | 2026-10-22 | P1.5 素材接入:背景图 `cover` + 水滴波纹、BGM 单例与切歌链路(`src/audio/`);新增 `v0.2.0/背景图与音频素材` 归档 | | 2026-10-22 | P1.6 实测修正:启动即播(`preloadBgm` + 冷启动 0 延迟)、波纹 0/0.18/1.0s + 环宽 5%、选关/教程/结算白色 50% 毛玻璃、标题 CSS 3D + 4s 摇摆 + 波纹期加剧 | | 2026-10-22 | P2 落地:`game/config/food.ts` + `game/core/food/**`(生成/游走/下蛋/逃脱/补位/吞食)+ `core/rules/eat.ts` + `scene/entities/food/**` 四种灰盒与下蛋圆环;`GameState.foods` 改槽位容器,`step` 槽位 4/5 接通,删 `Space` 调试键 | | 2026-10-22 | P2 试玩三轮修正:食物视觉/判定 ×2、虫子 10%、每节 +2%(满节 24%)、相机取景上移(新增 `scene/camera/framing.ts` + 15 条单测);测试 139 → 229 条 | | 2026-10-23 | P3 落地:`core/rules/{score,outcome}.ts`(积分唯一写入口 / 先达标后超时)、`step` 槽位 6 接通并修掉"不吃食物就早退导致超时永不触发"、饥饿扣分、`LevelConfig.segmentsMax` 逐关递增(10/15/20/20)、`flow/save-progress.ts` + `store.writeSave` 解锁落盘、末关「敬请期待」→ 回标题;测试 229 → 267 条;新增 `v0.2.0/成长与计分` 归档 | | 2026-10-23 | P2 补丁(P3 试玩发现):小鸟「圆环读满却不出蛋」——`refillDelayEatenS` 与 `lay.durationS` 同为 1.2s 撞帧导致补位抢走唯一空槽;`stepFoods` 拆 A 占用/B 落蛋/C 预留/D 补位(新增 `food/slots.ts`),`stepLay` 判定拆 `canStart`/`canPlaceEgg`;测试 267 → 270 条 | | 2026-10-23 | P4 落地:浮层栈(`ui.layers`)+ ESC 单点路由(`resolveEscape`)、正式 HUD(顶部 UI 条 / 1P·2P / 左下角暂停)、设置浮层(四档窗口尺寸 / 全屏 / BGM / SFX / 游戏说明)+ 窗口 IPC 6 → 9 通道(`set-fullscreen` / `get-state` / `state-changed`)、三页教程(`flow`\|`readonly` 双模式)、四类弹窗、选关正式化(2×2 / 分页 / 滤镜 / 锁态 / 关卡信息)、SFX 池(素材占位)、全局字体变量、`publicUrl` 修掉 `file://` 资源 404;测试 270 → 340 条 | | 2026-10-23 | **P5 收尾 + v0.2.0 发版**:P5-1 音效与每关 BGM、P5-2 开场动画、P5-5 选关背景入库;补 P4 兜底(窗口状态常驻同步 / 夹取与显示器监听 / 教程末页文案 / 字体子集自动收集);打包 134.8MB → **109.3MB**(裁剪 locale、移除 portable、`files` 排除 `node_modules`)并移除未使用的 `@ffmpeg-installer/ffmpeg`;测试 **464 条 / 47 文件**;新增 `P5打磨/04-Review记录.md`,P5-3/4/6/7/8 挂起 | | 2026-10-23 | P4 追加:对局地图外由纯黑改为**浅色天空 + 蓝白云彩**(`ui/background/{clouds,SkyBackdrop}` + `styles/sky.css`,3 层云视差、`--tile-w` 同源实现无缝循环、`prefers-reduced-motion` 全停);`GameCanvas` 显式 `alpha` 契约;修掉 `.floaters` 被 Canvas 盖住的层叠问题;测试 340 → 355 条 | | 2026-10-23 | P4 追加 2:局内视觉强化——**关卡色滤镜**(`ui/theme/level-tint.ts` + `ui/game/LevelTint`,与选关卡片同表,第 1 关不渲染节点);**草地四层**(`scene/entities/board/`:底板 + 斜向相位场波纹 + 2-3 格连片草丛 + 四边尖刺,纯函数布局 + 3 次 draw call);**右侧 45° 主光**(`scene/lights/`:环境光降 0.42 + 半球光 + 主光 0.95 + 冷色补光,平行光 target 指向棋盘中心);层叠表扩为 天空0/Canvas1/滤镜2/飘字3/暂停4;测试 355 → 372 条 | | 2026-10-23 | P4 追加 3:**视角拖拽**(I-09 / I-10)——左键拖拽改俯仰 30°~85° 与方位 0~360°、右键回默认(只归位角度,缩放不变);`scene/camera/orbit.ts` 用**可变对象 + `invalidate`** 承载角度(不进 React state),`CameraRig` 改 `useFrame` 每帧写相机;`input/snapshot.ts` 的 `alignDirToView` 让方向键跟随视角(按 W 永远朝屏幕上方);教程第 3 页补三条说明;测试 372 → 416 条(含俯角 × 方位 × 画幅 × 棋盘全组合的"四角仍入画",以及 jsdom 真发指针事件的拖拽接线测试) | | 2026-10-23 | **P4 封版**(`6d6441d`,108 个文件 / +8377 / -792):代码与 `.claude/docs/v0.2.0/正式UI/{02,03,04,05}` 同批入库;实施清单补 **§十三 变更文件清单**(新增 67 / 修改 37 / 删除 4,含 4 个删除过渡件的取代关系)与 **§十四 变更记录**;`HANDOVER.md` 按 P5 重写「P5 的输入」(8 块已按观感收益排序、给出完成标志与建议的两个提交批次)、补 §9.4 临时件清理清单、修正目录树与技能归属里 3 处失效路径 |