深渊信使开发日志 — 从「纸片人」到「能玩的游戏」
这篇文章记录了《深渊信使》从"技术演示"到"可以玩的游戏"的完整迭代过程。每一个改动背后都有一段辛酸的故事。
第一阶段:这游戏能玩吗?(2026-06-30)
问题:角色是纸片人
游戏最初加载了一个 GLTF 模型(character.glb,2.9MB)来替代程序化角色。但这个模型没有动画关节数据(userData.joints),导致移动时角色像纸片一样在地上滑行——没有任何肢体动作。
修复:禁用 GLTF 加载,只用程序化角色。
问题:没有游戏性
两个探索 agent 对代码进行了全面审计,结论是:游戏目前是一个「行走对话模拟器」。
核心循环是:走到NPC → 点击翻完8-13句对话 → 自动传送到下一个NPC → 重复5次 → 二选一结局 → 结束。
已有的系统(都完整但无游戏性影响):
- 5个地标 + 5个NPC + 5章线性主线 + 双结局
- 无线电解谜(调到52.9Hz只显示一段文字,不解锁任何东西)
- 漂流瓶系统(纯玩家自写,没有预设故事瓶)
完全缺失的:没有物品/背包系统、没有需要解密的谜题、没有探索奖励、没有能力解锁、没有支线任务、没有任何失败状态或挑战。
修复:重建女性角色 + 新增游戏系统
角色重建
重写了 buildCharacterMesh() 函数,构建了一个完整的女性角色:
- 立体身体:球体臀部 + 锥形躯干 + 胸部曲线(不再是薄胶囊体)
- 长发:发冠 + 后发束(带摆动动画)+ 侧发 + 刘海
- 服装:锥形裙装(带摆动动画)+ 装饰裙摆 + 围巾 + 靴子
- 配件:背包 + 背带 + 发光信件(玩家专属)
- 面部:眼睛(带高光点)+ 鼻子 + 嘴唇
同时为 5 个 NPC 各自配置了不同的发色、裙色和靴色。
动画系统更新
- 走路时:臀部摇摆 + 裙摆飘动 + 长发飘动 + 自然步态
- 待机时:呼吸动画 + 发丝微动
- 对话时:右手手势 + 头部倾斜
新增游戏系统
| 系统 | 内容 | 操作 |
|---|---|---|
| 记忆碎片 | 12个发光八面体散布星球表面 | 靠近按E收集,HUD显示 0/12 |
| 任务道具 | 5个道具(潮汐日志/荧光样本/族谱/骨笛/频率仪) | 必须先找到道具,NPC才肯说话 |
| 故事漂流瓶 | 7个预设剧情瓶(K的警告/苏晴日记/明月抄经等) | 散布在星球各处,按B拾取 |
| 无线电后果 | 调到52.9Hz后生成金色隐藏碎片 | 解锁前:纯文字;解锁后:实际道具 |
| 背包系统 | 显示已收集道具和碎片剧情 | 按I键开关 |
预设故事漂流瓶内容
7个瓶子各自包含一段剧情线索:
- 无名氏:「如果你找到这封信,说明你也听到了那个声音。52.9赫兹——它不是来自海底,它来自更深处。」
- K:「七座灯塔,七个守门人。澜城只是开始。记住这个频率,它是钥匙。」
- 苏晴(旧日记):「脑波数据不会说谎。这座岛在做梦。而且它快要醒了。」
- 明月(抄经):「万年之约已至。背上之城的命运,系于信使之手。」
- K:「我在澜城灯塔见过那扇门。不要打开它。频率相同意味着它们相连。」
- 老陈(航海日志):「潮汐从六秒变四秒,再到三秒。它呼吸得越来越快了。」
- 林溪(备忘):「所有线索指向同一个结论——这不是岛,是活物。而我必须做出选择。」
第二阶段:视角不对,移动诡异(2026-07-01)
以真人玩家视角体验 10 分钟后的诊断
一个真人玩家进入游戏后会发生什么?
| 时间 | 体验 | 感受 |
|---|---|---|
| 0-1 分钟 | 标题画面 → 进入游戏 | 标题画面不错,有氛围感 |
| 1-2 分钟 | 点击画面锁鼠标,WASD 走动 | 困惑:地面为什么是弯的?为什么走几步就绕回来了? |
| 2-3 分钟 | 找到第一个发光信标 | 信标很明显,但走过去的路很晕 |
| 3-5 分钟 | 和老陈对话(8 句话) | 故事不错,打字机效果有代入感 |
| 5-5.5 分钟 | 对话完,自动传送 | 突兀:我怎么突然到另一个地方了? |
| 5.5-7 分钟 | 找任务道具 + 和苏晴对话 | 道具在哪?没有提示,只能瞎转 |
| 7-8 分钟 | 收集到一个记忆碎片 | 碎片发光挺好看,但文字一闪就没了 |
| 8-10 分钟 | 第 3 个 NPC 对话 | 重复感:走 → 读 → 传送 → 走 → 读 → 传送... |
根本原因分析
问题 1:星球太小
- 星球半径只有 18 单位,周长约 113 单位
- 最大速度 5.0 单位/秒 → 23 秒绕星球一圈
- 相机距离 4.8 单位,相当于站在星球半径的 27% 远处
- 从这个距离看,地面明显向下弯曲,像站在一个巨大的球顶上
问题 2:自动传送杀死探索
- 对话完直接传送到下一个 NPC
- 玩家永远不需要自己找路
- 探索毫无意义
问题 3:碎片/道具没有引导
- 12 个碎片散布在星球上
- 没有地图标记、没有罗盘、没有提示
- 只能瞎转碰运气
问题 4:对话无法跳过
- 8-13 句打字机效果的对话
- 每句都要等打完才能点下一句
- 重复游玩时极其痛苦
修复:全面改造
星球放大 3 倍
`` PLANET_RADIUS: 18 → 50(2.78x) 所有3D物体等比放大 2.5x ``
所有常量等比调整:
| 常量 | 旧值 | 新值 | 原因 |
|---|---|---|---|
| CAMERA_DISTANCE | 4.8 | 14 | 相机拉远,看到更多地平线 |
| CAMERA_HEIGHT | 1.6 | 5 | 相机抬高,减少地面曲率感 |
| MAX_SPEED | 5.0 | 8.0 | 速度提升,但星球更大所以相对更慢 |
| JUMP_FORCE | 7.4 | 12 | 跳跃力配合更大的重力 |
| GRAVITY | 18 | 28 | 重力增加,跳跃不再飘 |
| INTERACT_DISTANCE | 2.5 | 6 | 交互距离配合更大的世界 |
| 地标检测距离 | 7.4 | 20 | 检测范围配合更大的世界 |
移动/相机修复
- 相机碰撞:最小距离从 2.0 → 5.0,不再被地面激进拉近
- 角色旋转:lerp 系数从 10 → 4,转向更平滑
- 雾效距离:34/126 → 50/200,配合更大的世界
- 相机远裁面:240 → 400
去掉自动传送
删除了 teleportToQuest() 的调用。玩家现在需要自己导航到下一个目标。
新增导航系统
- 指南针组件:右上角实时显示目标方向箭头 + 距离(米)
- 小地图标记:碎片(蓝色圆点)/ 道具(金色圆点)/ 目标NPC(粉色大圆点)
- 目标方向 API:
getTargetDirection()返回角度和距离
新手教程
首次进入游戏时显示 4 步操作指引:
- 你站在一颗微型星球上。用 WASD 移动,鼠标转动视角。
- 沿着发光信标找到 NPC,按 E 键对话。
- 收集发光的记忆碎片和任务道具,按 I 打开背包。
- 屏幕右上角的指南针会指引你前往下一个目标。
对话跳过按钮
对话面板右上角新增「跳过」按钮,点击立即显示完整文本。
第三阶段:人物都是躺着的(2026-07-01)
问题:角色朝向完全错误
修复了上面的问题后,进入游戏发现:所有角色都躺着,脚朝上。
根本原因:左手坐标系
``javascript // 原来的代码 const right = crossVectors(facing, normal) // facing × normal = LEFT(不是RIGHT!) ``
这产生了一个左手矩阵(行列式 = -1)。Three.js 的 setFromRotationMatrix 无法正确处理左手矩阵,导致角色朝向完全错误。
修复:右手坐标系
``javascript // 修复后 const right = crossVectors(normal, facing) // normal × facing = RIGHT(正确) ``
交换叉乘顺序后,产生正确的右手坐标系,角色正确站立在球面上。
第四阶段:人物只有一半,下半身陷进去了(2026-07-01)
问题:角色半截入地
修好朝向后,发现角色只有上半身可见,下半身陷进了地面。
根本原因:位置计算错误
角色位置设在 normal × PLANET_RADIUS,意味着角色的原点(y=0)在地面上。但角色的靴底在原点下方 0.34 单位,所以靴子陷进了地面。
修复:抬高角色
``javascript // 修复后 const surfacePosition = normal.clone().multiplyScalar(PLANET_RADIUS + 0.4 + this.jumpOffset) ``
把角色抬高 0.4 单位,靴底正好踩在地面上。同时修复了 NPC 的位置偏移。
完整改动清单
Engine.js(核心引擎)
| 改动 | 详情 |
|---|---|
| 角色重建 | 女性角色(裙装/长发/围巾/靴子/女性体态),消除纸片人 |
| 禁用 GLTF | 只用程序化角色,防止无动画模型覆盖 |
| 动画系统 | 走路时臀摆/裙摆/长发飘动,待机时呼吸+发丝微动 |
| 记忆碎片 | 12个发光八面体,靠近按E收集 |
| 任务道具 | 5个道具,NPC要求先找到才肯对话 |
| 故事漂流瓶 | 7个预设剧情瓶 |
| 无线电后果 | 52.9Hz解锁隐藏碎片 |
| 星球放大 | 半径 18→50,所有物体等比放大 2.5x |
| 相机修复 | 距离 4.8→14,高度 1.6→5,碰撞更宽松 |
| 旋转平滑 | lerp 系数 10→4 |
| 去掉传送 | 改为指南针导航引导 |
| 导航 API | getTargetDirection / getShardPositions / getItemPositions |
| 朝向修复 | 叉乘顺序修正为右手坐标系 |
| 地面修复 | 角色抬高 0.4 单位,靴底踩地 |
App.vue(UI层)
| 改动 | 详情 |
|---|---|
| 碎片计数 HUD | 右上角显示 0/12 |
| 背包面板 | 按I键开关,显示道具和碎片剧情 |
| 指南针组件 | 实时方向箭头 + 距离显示 |
| 新手教程 | 首次进入显示4步操作指引 |
| 对话跳过 | 右上角按钮点击显示全文 |
| 小地图标记 | 碎片(蓝)/道具(金)/目标NPC(粉) |
| 收集提示 | 碎片/道具靠近时的拾取横幅 |
| 剧情浮窗 | 碎片收集后的剧情文字展示 |
i18n.js(双语翻译)
新增 40+ 条双语翻译:
- 12个碎片剧情文本
- 5个任务道具名称
- 教程文本(4步指引)
- UI文本(背包/指南针/跳过/距离等)
style.css(样式)
新增 176 行样式:
- 教程覆盖层(毛玻璃背景 + 卡片布局)
- 指南针组件(圆形箭头 + 距离标签)
- 跳过按钮(半透明 + hover效果)
- 小地图标记(发光圆点)
- 背包面板(分区布局 + 道具卡片)
- 剧情浮窗(底部弹出 + 渐隐动画)
技术细节
构建统计
`` 29 modules transformed dist/assets/index.js 244.34 kB (gzip: 84.94 kB) dist/assets/three.js 558.90 kB (gzip: 141.68 kB) ✓ built in 33.70s ``
测试验证
Playwright 自动化测试确认:
- ✅ 0 console errors
- ✅ 碎片计数 0/12 正常显示
- ✅ 背包按I键正常开关
- ✅ 地图按M键正常开关
- ✅ WASD移动 + 空格跳跃正常
- ✅ 教程覆盖层正常显示和关闭
Git 提交历史
`` 3318bb8 feat: 重建女性角色 + 新增记忆碎片/任务道具/故事漂流瓶游戏系统 c9ff436 feat: 新增背包UI + 碎片计数HUD + 收集提示交互 ca8b55a feat: 任务道具数据 + 双语翻译(碎片剧情/道具名称/UI文本) d0a201d feat: 星球放大3倍 + 移动/相机修复 + 导航API 15d7407 feat: 新手教程 + 指南针导航 + 对话跳过 + 小地图标记 730757b fix: 修复角色朝向 — 右手坐标系 + 脚踩地面 ``
一句话总结
从一个「纸片人在小球上滑行」的技术演示,到一个有女性角色、有收集系统、有导航引导、有教程的「可以玩的3D探索游戏」。
每一步都是真实玩家的反馈驱动的迭代。没有完美主义,只有「这个问题最影响体验,先修它」。
如果你也在做独立游戏,希望这篇日志能让你少走一些弯路。至少你知道——你不是一个人在和纸片人战斗。