深渊信使开发日志 — 从「纸片人」到「能玩的游戏」

这篇文章记录了《深渊信使》从"技术演示"到"可以玩的游戏"的完整迭代过程。每一个改动背后都有一段辛酸的故事。


第一阶段:这游戏能玩吗?(2026-06-30)

问题:角色是纸片人

游戏最初加载了一个 GLTF 模型(character.glb,2.9MB)来替代程序化角色。但这个模型没有动画关节数据(userData.joints),导致移动时角色像纸片一样在地上滑行——没有任何肢体动作。

修复:禁用 GLTF 加载,只用程序化角色。

问题:没有游戏性

两个探索 agent 对代码进行了全面审计,结论是:游戏目前是一个「行走对话模拟器」

核心循环是:走到NPC → 点击翻完8-13句对话 → 自动传送到下一个NPC → 重复5次 → 二选一结局 → 结束。

已有的系统(都完整但无游戏性影响):

完全缺失的:没有物品/背包系统、没有需要解密的谜题、没有探索奖励、没有能力解锁、没有支线任务、没有任何失败状态或挑战。

修复:重建女性角色 + 新增游戏系统

角色重建

重写了 buildCharacterMesh() 函数,构建了一个完整的女性角色:

同时为 5 个 NPC 各自配置了不同的发色、裙色和靴色。

动画系统更新

新增游戏系统

系统内容操作
记忆碎片12个发光八面体散布星球表面靠近按E收集,HUD显示 0/12
任务道具5个道具(潮汐日志/荧光样本/族谱/骨笛/频率仪)必须先找到道具,NPC才肯说话
故事漂流瓶7个预设剧情瓶(K的警告/苏晴日记/明月抄经等)散布在星球各处,按B拾取
无线电后果调到52.9Hz后生成金色隐藏碎片解锁前:纯文字;解锁后:实际道具
背包系统显示已收集道具和碎片剧情按I键开关

预设故事漂流瓶内容

7个瓶子各自包含一段剧情线索:

  1. 无名氏:「如果你找到这封信,说明你也听到了那个声音。52.9赫兹——它不是来自海底,它来自更深处。」
  2. K:「七座灯塔,七个守门人。澜城只是开始。记住这个频率,它是钥匙。」
  3. 苏晴(旧日记):「脑波数据不会说谎。这座岛在做梦。而且它快要醒了。」
  4. 明月(抄经):「万年之约已至。背上之城的命运,系于信使之手。」
  5. K:「我在澜城灯塔见过那扇门。不要打开它。频率相同意味着它们相连。」
  6. 老陈(航海日志):「潮汐从六秒变四秒,再到三秒。它呼吸得越来越快了。」
  7. 林溪(备忘):「所有线索指向同一个结论——这不是岛,是活物。而我必须做出选择。」

第二阶段:视角不对,移动诡异(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:星球太小

问题 2:自动传送杀死探索

问题 3:碎片/道具没有引导

问题 4:对话无法跳过

修复:全面改造

星球放大 3 倍

`` PLANET_RADIUS: 18 → 50(2.78x) 所有3D物体等比放大 2.5x ``

所有常量等比调整:

常量旧值新值原因
CAMERA_DISTANCE4.814相机拉远,看到更多地平线
CAMERA_HEIGHT1.65相机抬高,减少地面曲率感
MAX_SPEED5.08.0速度提升,但星球更大所以相对更慢
JUMP_FORCE7.412跳跃力配合更大的重力
GRAVITY1828重力增加,跳跃不再飘
INTERACT_DISTANCE2.56交互距离配合更大的世界
地标检测距离7.420检测范围配合更大的世界

移动/相机修复

去掉自动传送

删除了 teleportToQuest() 的调用。玩家现在需要自己导航到下一个目标。

新增导航系统

新手教程

首次进入游戏时显示 4 步操作指引:

  1. 你站在一颗微型星球上。用 WASD 移动,鼠标转动视角。
  2. 沿着发光信标找到 NPC,按 E 键对话。
  3. 收集发光的记忆碎片和任务道具,按 I 打开背包。
  4. 屏幕右上角的指南针会指引你前往下一个目标。

对话跳过按钮

对话面板右上角新增「跳过」按钮,点击立即显示完整文本。


第三阶段:人物都是躺着的(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
去掉传送改为指南针导航引导
导航 APIgetTargetDirection / getShardPositions / getItemPositions
朝向修复叉乘顺序修正为右手坐标系
地面修复角色抬高 0.4 单位,靴底踩地

App.vue(UI层)

改动详情
碎片计数 HUD右上角显示 0/12
背包面板按I键开关,显示道具和碎片剧情
指南针组件实时方向箭头 + 距离显示
新手教程首次进入显示4步操作指引
对话跳过右上角按钮点击显示全文
小地图标记碎片(蓝)/道具(金)/目标NPC(粉)
收集提示碎片/道具靠近时的拾取横幅
剧情浮窗碎片收集后的剧情文字展示

i18n.js(双语翻译)

新增 40+ 条双语翻译:

style.css(样式)

新增 176 行样式:


技术细节

构建统计

`` 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 自动化测试确认:

Git 提交历史

`` 3318bb8 feat: 重建女性角色 + 新增记忆碎片/任务道具/故事漂流瓶游戏系统 c9ff436 feat: 新增背包UI + 碎片计数HUD + 收集提示交互 ca8b55a feat: 任务道具数据 + 双语翻译(碎片剧情/道具名称/UI文本) d0a201d feat: 星球放大3倍 + 移动/相机修复 + 导航API 15d7407 feat: 新手教程 + 指南针导航 + 对话跳过 + 小地图标记 730757b fix: 修复角色朝向 — 右手坐标系 + 脚踩地面 ``


一句话总结

从一个「纸片人在小球上滑行」的技术演示,到一个有女性角色、有收集系统、有导航引导、有教程的「可以玩的3D探索游戏」。

每一步都是真实玩家的反馈驱动的迭代。没有完美主义,只有「这个问题最影响体验,先修它」。

如果你也在做独立游戏,希望这篇日志能让你少走一些弯路。至少你知道——你不是一个人在和纸片人战斗