# 奇幻酒馆项目开发经验手册 日期:`2026-03-24` ## 1. 项目本质判断 这个项目不是单纯的前端页面项目,也不是单纯的大模型接入项目,而是 4 条链路同时存在的复合型项目: 1. 叙事链路:剧情文本、选项文本、角色对话、聊天上下文。 2. 状态链路:角色、怪物、NPC、场景、背包、装备、战斗状态、CD、蓝耗、死亡、掉落。 3. 演出链路:角色进场、近战贴身、受击、死亡、逃跑、镜头跟随、场景切换、前探预览。 4. 工具链路:NPC 形象编辑器、行为编辑器、预设数据、校验脚本、本地调试环境。 经验结论: - 任何需求只要影响两条以上链路,就不能只改 UI。 - 先判断需求落在哪些链路,再决定改哪些文件。 - 这类项目最怕“看起来改好了”,但状态、动画、提示词和运行逻辑其实没对齐。 ## 2. 架构拆分经验 已经验证更稳的结构是: - `App.tsx` 保持尽量薄,只做外层挂载。 - `GameShell.tsx` 负责主流程壳层:开始页、世界选择、角色选择、游戏内主界面切换。 - 各类状态和流程尽量放进 hooks: - `useGameFlow` - `useCombatFlow` - `useStoryGeneration` - `useNpcInteractionFlow` - `useInventoryFlow` - `useEquipmentFlow` - 各类独立 UI 面板拆成独立组件: - `AdventurePanel` - `CharacterPanel` - `InventoryPanel` - `MapModal` - `AdventureEntityModal` 经验结论: - 按职责拆,不按文件长度拆。 - 状态修改尽量集中在 hook 内,不要散落在多个按钮回调里。 - 预览系统、编辑器系统、正式游戏流程要尽量复用同一套业务逻辑,而不是各写一套。 ## 3. AI 与本地规则的边界 目前最稳定的边界是: - AI 负责生成: - `storyText` - `actionText` - 对话文本 - 基于上下文的语气、叙事张力、选项措辞 - 本地规则负责决定: - 哪些 function 当前可执行 - 技能是否在 CD - 蓝量是否足够 - 伤害、回复、掉血、死亡、掉落 - 场景切换是否合法 - 背包、装备、属性、队伍变化 经验结论: - 涉及数值、资源、状态迁移的部分,不要交给模型临场决定。 - 模型应被限制在“叙事表达层”,不要替代规则系统。 - 用户每次选择后只做一次模型推理,因此提示词必须一次性包含足够边界,不能再依赖后处理改写和过滤。 ## 4. Function 驱动设计经验 当前更合理的设计方向是: - 所有可选行为都落到 function。 - 每个 function 只有这些核心字段: - `id` - `text` - `description` - `category` - `功能代码` - 运行时先汇总当前场景的 function,再结合角色、状态、敌人、场景实体、资源状态做合法性过滤。 - 模型只在“当前合法 function 集合”内生成选项文本和剧情文本。 经验结论: - 选项不是自由散文,而是 function 的叙事包装。 - function 必须和角色、状态、场景、实体绑定,不能做成完全漂浮的公共动作池。 - “每次选择只能并且必须命中一个 function” 是保持状态稳定的关键。 ## 5. 战斗与动画的经验 战斗部分已经沉淀出的几个重要规则: ### 5.1 结算时机 - 用户点击选项后,后台状态应立即推进到“动画完成后的结果状态”,并把这个新状态放入后续推理上下文。 - 但扣血、死亡表现、消失等视觉结果要在动画播完后再体现在画面上。 这样做的好处: - 模型推理可以立即开始,不被动画阻塞。 - 画面依然保留正确的演出节奏。 - 状态、上下文、下一轮推理不会落后于动画。 ### 5.2 近战位移 - 近战动画不能按固定像素移动。 - 必须按左右锚点、舞台宽度和目标位置计算真实接近距离。 - 宽屏下如果只“往前走一点点”,基本就是位移基准用了屏幕百分比或固定偏移,而不是双方真实锚点差值。 ### 5.3 死亡与退出战斗 - 怪物血量归零时先播死亡动画。 - 死亡动画完成后怪物再消失。 - 若敌方死亡,战斗状态应退出,切回空闲状态,并重新切换可用 function 集合。 ### 5.4 逃跑与压迫感 - 逃跑镜头要跟着玩家,不是跟怪物。 - 玩家向前跑,怪物被越甩越远,才能形成“甩开追兵”的感觉。 - 相反,如果镜头锚在怪物侧,会让玩家像没动一样。 ## 6. 遭遇、场景与地图经验 这部分已经验证有效的设计原则: - 场景和背景图一一绑定,不切场景就不换背景。 - 场景切换必须由选项命中的 function 驱动,而不是每回合自动变化。 - 每个场景预设自己的怪物、NPC、宝藏池。 - 玩家“继续向前探路”时,不是立刻随机弹结果,而是先预生成前方实体,再通过移动和镜头演出把它带到正式交互位。 经验结论: - “探索”也应该是一种可演出的 function,而不只是一次文字刷新。 - 同一时刻只应遇到一个主实体,避免一回合同时出现多只怪物造成状态混乱。 - 地图系统适合做成场景连接图,由具体 function 触发前往某个场景。 ## 7. 移动端优先的 UI 经验 已经验证有效的 UI 方向: - 先保证移动端一屏成立,再兼容网页宽屏。 - 开始页、世界选择、角色选择都要像游戏流程,而不是产品介绍页。 - 世界选择适合纵向焦点滑动。 - 角色选择适合横向翻卡和中心焦点展示。 - 冒险页中: - 上方是画面演出 - 中间是自适应剧情文本 - 底部是固定的选项与功能入口 经验结论: - 剧情区域不能写死高度,应填满画面下方和底部操作条上方之间的剩余空间。 - 队伍、背包更适合作为弹出面板,不应该切走主流程。 - 地图弹窗、队伍面板、背包详情都必须按手机窄屏重新组织,不要沿用桌面弹窗思路。 ## 8. 选择页与游戏内界面经验 这轮迭代里比较明确的 UI 结论有: - 开始页只保留核心按钮,视觉简洁更像正式游戏。 - 世界选择页要突出当前聚焦卡,其他卡随滑动连续改变透明度和大小。 - 角色选择页中: - 中间卡片不能模糊 - 左右卡片要做正确方向的倾斜 - 中间角色可播放 `run` 动画 - 角色名称显示在动画下方 - 属性和背景信息要紧凑,不能压缩掉上方卡片滑动空间 - 游戏内按钮应尽量图标化,把更多空间留给剧情和选项。 ## 9. NPC 形象编辑器经验 NPC 编辑器这部分已经沉淀出一些通用原则: - 这套 Medieval Fantasy Characters 素材不是传统逐帧全身序列帧,发型、脸型、胡子、武器等部件不能按“每帧都变化”的思路处理。 - 主手武器、副手武器、手、身体、头部、头饰需要明确图层关系。 - 主手武器必须真正握在手里,不能只靠大概位置“看起来差不多”。 - 因为素材高度重叠,编辑器里必须支持: - 底部组件模块点击选择 - 键盘上下左右微调 - 拖拽微调 - 回滚按钮 经验结论: - 视觉编辑器如果没有“可控选择 + 微调 + 回滚”,用户会很难调重叠素材。 - 选项命名不能直接暴露英文源文件名,最好转成更贴近视觉理解的中文名称。 - 编辑器产出的相对位置数据必须能直接落回项目运行时,不然就只是一个孤立工具。 ## 10. 大模型接入与本地调试经验 这部分踩坑非常集中,结论也比较清晰: ### 10.1 前端不能直连目标模型接口 - 浏览器直连时会遇到 CORS。 - 即使接口本身可用,浏览器环境也可能被跨域限制。 - 更稳的方案是在开发服务器侧做代理,再由前端请求本地 `/api/llm/...`。 ### 10.2 需要日志,但日志要聚焦 已经证明有价值的日志包括: - 单次推理耗时 - 原始提示词文本 - 原始返回中的解析后文本 - 失败时的模型名、状态码和错误正文 ### 10.3 开发服务器要统一入口 本项目本地正确启动方式应统一走: ```bash node scripts/vite-cli.mjs --port=3000 --host=0.0.0.0 ``` 经验结论: - 只要本地存在旧进程、旧脚本或错误端口映射,就很容易出现“代码改了但界面还是旧的”假象。 - 遇到这类问题,优先检查实际启动脚本、端口占用和返回模块内容,而不是先怀疑 UI 代码没生效。 ## 11. 编辑器与正式运行时的关系 已经验证最稳的做法是: - 编辑器预览直接复用正式运行时函数。 - 预览不自己模拟一套战斗和 function 执行逻辑。 - 运行时怎么结算,编辑器就怎么调用。 经验结论: - 只要编辑器预览和正式逻辑分成两套,后面一定会越来越不一致。 - 预览系统的价值不是“看起来像”,而是“执行路径就是正式路径”。 ## 12. 后续继续开发时建议遵循的顺序 推荐流程: 1. 先补数据结构和类型。 2. 再补 function 规则和过滤条件。 3. 再补 hook 流程与状态迁移。 4. 再补动画和演出。 5. 最后再做 UI 细修。 6. 每轮改动后至少做一次类型检查和本地启动验证。 不推荐的流程: 1. 先堆 UI。 2. 再临时塞状态。 3. 最后补运行逻辑。 这类项目里,后者几乎一定导致返工。 ## 13. 一句话总结 这个项目最重要的经验不是“做了多少页面和功能”,而是: **必须把 AI 文本生成、本地规则、动画演出、场景状态、编辑器工具这几套系统严格分层,再通过 function 和统一状态流把它们重新接起来。** ## 14. 相关文档 如需继续细看已有沉淀,可结合以下文档一起阅读: - `docs/experience/PROJECT_DEVELOPMENT_EXPERIENCE.md` - `docs/experience/MOBILE_UI_DEV_EXPERIENCE.md` - `docs/experience/CODEX_IMPLEMENTATION_EXPERIENCE_2026-03-24.md` - `docs/experience/AGENT_UI_CHANGELOG.md`