用于减少 LLM 常见编码失误的行为准则。可按需与项目特定说明合并使用。
权衡: 这些准则更偏向谨慎而不是速度。对于非常简单的任务,请自行判断。
不要想当然。不要掩饰困惑。把权衡说清楚。
在实现之前:
- 明确说明你的假设。如果不确定,就提问。
- 如果存在多种理解方式,把它们列出来,不要默默选一个。
- 如果有更简单的方案,直接指出来。必要时应当提出异议。
- 如果某件事不清楚,就停下来。说明困惑点并发问。
只写解决问题所需的最少代码。不要做推测式扩展。
- 不要添加未被要求的功能。
- 不要为一次性代码引入抽象。
- 不要加入未被要求的“灵活性”或“可配置性”。
- 不要为不可能发生的场景编写错误处理。
- 如果你写了 200 行,而 50 行就够,重写。
问问自己:“一个资深工程师会觉得这里过度设计了吗?” 如果答案是会,那就继续简化。
只动必须动的部分。只收拾你自己制造的问题。
在修改现有代码时:
- 不要“顺手改进”相邻代码、注释或格式。
- 不要重构没坏的东西。
- 遵循现有风格,即使你个人会写得不一样。
- 如果你发现无关的死代码,可以提一句,但不要删除。
当你的改动产生了遗留项时:
- 删除那些因你的改动而变得未使用的导入、变量或函数。
- 不要删除原本就存在的死代码,除非有人明确要求。
判断标准:每一行变更都应当能直接追溯到用户请求。
先定义成功标准,再循环验证直到满足。
把任务转换成可验证的目标:
- “加上校验” -> “先为非法输入编写测试,再让测试通过”
- “修复这个 bug” -> “先写出能复现问题的测试,再让它通过”
- “重构 X” -> “确保重构前后测试都通过”
对于多步骤任务,先写一个简短计划:
1. [步骤] -> 验证:[检查项]
2. [步骤] -> 验证:[检查项]
3. [步骤] -> 验证:[检查项]
强成功标准能让你独立推进并反复验证。弱成功标准(例如“把它弄好”)则会不断需要澄清。
如果这些准则在发挥作用,你会看到: diff 中不必要的改动更少,因过度设计导致的返工更少,并且澄清问题会出现在实现之前,而不是犯错之后。
- 本项目统一使用
pnpm作为包管理器;安装、运行、构建、脚本执行默认使用mise exec node@24 -- pnpm ...或mise exec node@24 -- pnpm exec ...。 - 除非用户明确要求,否则不要在本项目中使用
npm install、npm run、npx作为默认命令。 - 当用户提到
progress、changelog、文档归档、提交前整理文档、项目背景更新时,优先使用仓库私有 skill:.agents/skills/project-doc-maintainer/。 - 对 medium / large 提交,默认先运行该 skill 的
commit工作流,再执行提交。 - 提交前的底层命令统一使用:
mise exec node@24 -- pnpm docs:analyze -- --stagedmise exec node@24 -- pnpm docs:sync -- --stagedmise exec node@24 -- pnpm docs:archivemise exec node@24 -- pnpm docs:guard -- --staged
git hook只做轻量守门,不负责生成复杂文档内容。
- 每次新会话进入本项目,或用户在当前会话里第一次提出非闲聊、非极小改动任务时,先读取:
docs/context/project.mddocs/progress.md
- 这两个文件用于建立最小项目记忆:
docs/context/project.md负责告诉你这个项目是什么、边界是什么、目录职责是什么。docs/progress.md负责告诉你当前到了什么进展、正在做什么、下一步要做什么。
- 不要假设这些信息已经常驻在上下文里;需要时应主动重新读取,而不是只依赖记忆。
- 涉及整体技术路线、架构边界、分层方式时,再读取
docs/context/architecture.md。 - 涉及页面、路由、前端组织、游戏宿主层实现时,再读取
docs/context/frontend.md。 - 涉及 Cloudflare、OpenNext、Wrangler、部署配置时,再读取
docs/context/deployment.md。 - 涉及具体游戏时,优先读取
docs/context/games/<slug>.md;如果不存在,再根据代码现状判断是否需要新建。 - 涉及“为什么这样做”“之前定过什么方案”“这次是否偏离既有结论”时,再读取
docs/decisions/下相关文档。 - 涉及提交前整理、阶段性总结、发布说明、变更归档时,再读取
CHANGELOG.md、docs/README.md,并优先使用.agents/skills/project-doc-maintainer/。
- 在开始实现前,你应当能够回答:
- 这个项目的背景和目标是什么。
- 当前阶段进展是什么。
- 这轮任务与哪个 active track 或 next focus 相关。
- 当前改动是否会影响 progress、decision 或 changelog。
- 如果这些问题还答不上来,先补读相关 docs,再继续实现。
- 如果本轮工作改变了当前阶段、里程碑、下一步重点,完成实现后应更新
docs/progress.md。 - 如果本轮工作形成了有意义的用户可见变更或工程机制变化,应更新
CHANGELOG.md。 - 如果本轮工作沉淀了稳定约束、目录职责或方案定稿,应更新
docs/context/*或docs/decisions/*,而不是只写在对话里。
- 这是一个基于
Next.js的 Web 游戏中心项目,不是单个独立游戏仓库。 - 项目目标是承载多个可开发、可游玩的浏览器游戏,每个游戏有独立入口与相对独立的实现边界。
- 默认采用“一个宿主应用 + 多个游戏路由”的组织方式,而不是为每个游戏单独维护一个分散子工程。
- 近期主线以 2D 小游戏为主,文档与实现默认体现 2D 优先、3D 可扩展。
- 2D 游戏默认优先使用 Phaser 路线。
- 3D 游戏若运行在 React 宿主内,默认优先使用 React Three Fiber。
- 只有在用户明确要求或默认路线明显不适合时,才切换到 plain Three.js、Babylon.js、PlayCanvas 或其他运行时方案。
- 游戏中心宿主层继续使用
Next.js + React + TypeScript,不要默认把每个小游戏做成独立Vite工程。
- 每个游戏应当有独立路由入口,例如
/1024、/snake、/tetris。 - 每个游戏应尽量保持独立的代码、资源、配置边界,避免不同游戏之间直接耦合。
- 宿主层负责统一导航、入口展示、说明文案、全局样式边界,以及后续可扩展的存档、账户、排行榜等能力。
- 游戏自身负责玩法逻辑、资源加载、局内状态与交互。
- 新增游戏时,优先复用宿主层已有模式,不要为单个游戏引入一套完全独立的应用结构。
- simulation state 与 renderer 必须分离,渲染层不是游戏真实状态的来源。
- 菜单、HUD、设置、说明文案优先使用 DOM 层承载,不默认塞进 canvas 或 WebGL 场景。
- 游戏资源应使用稳定 key 或 manifest 管理,不让文件路径直接充当公开接口。
- 高频刷新、逐帧驱动的玩法循环不要依赖 React 普通重渲染驱动。
- 游戏代码优先按“玩法系统 / 渲染适配 / UI / 资源”分层,而不是把所有逻辑堆在页面组件里。
- 只在当前需求确实需要时补充基础设施,不提前抽象通用游戏引擎层。
- 核心循环是什么。
- 玩家有哪些主要操作。
- 胜利、失败、重开条件是什么。
- 目标平台是桌面端、移动端,还是同时支持。
- 依赖哪些资源类型,例如 sprite、tilemap、音效、3D 模型。
- 是否需要局外菜单、局内 HUD、暂停态、存档态。
- 每个游戏至少验证:进入、开始、主玩法、暂停或退出、失败或胜利、重开。
- 至少覆盖桌面与手机视口的基本可用性。
- canvas / WebGL 场景不能只做 DOM 断言,必须结合截图或实际画面检查。
- 若存在明显状态切换,需验证状态切换前后画面与交互一致性。
- 若后续引入自动试玩,再补充确定性时间步进和文本态输出约束。
- 使用
chrome-devtools、Playwright、agent-browser等浏览器自动化执行测试截图、录屏或其他临时产物时,统一写入.local/或其子目录,不要放在仓库根目录。
- 遇到新游戏需求时,先做轻量设计,再进入实现,不直接堆代码。
- 涉及玩法、输入、状态机时,先定义成功标准与验收点。
- 默认优先复用宿主层已有模式,避免每个小游戏都发展出一套独立架构。
- 如果技术路线与以上默认约束不一致,应先在文档或说明中明确偏离原因。