进入游戏后起始位置错误:角色出生在罗格营地栅栏外 #539

Closed
opened 2026-10-01 09:21:48 +00:00 by troytt · 1 comment
Owner

现象

进入游戏后,角色出现在罗格营地(Rogue Encampment)木栅栏外的树林里,而不是营地内的起始位置。

user-start-pos.png

截图中还能看到:

  • 画面上散布多个土黄色方块(疑似未解析到美术资源的单位/对象占位绘制);
  • 角色旁边有一个绿色矩形标记。

复现环境

  • 页面:play.html(本地 8080),分支 refactor/remove-legacy-sp @ 3c1ed16
  • 服务器:www.laiseek.xyz(PvPGN + D2GS 1.13c),Realm Sanctuary
  • 账号 / 角色:troytt / troytt(刺客,1 级,资料片,软核,天梯,新建角色首次进入)
  • 场景:Act 1 城镇,新建游戏后首次进入
  • 时间:2026-10-01 17:1x(UTC+8)

期望(1.13c)

新角色进入 Act 1 时应位于罗格营地内的起始点(营地内部可行走区域),与 D2GS 下发的玩家坐标一致。

待排查方向(未验证,仅供定位)

  • 服务器 0x59 AssignPlayer / 0x15 ReassignPlayer 坐标与客户端 DRLG 关卡原点(LoadAct / 房间 reveal)之间的坐标换算;
  • 客户端生成的罗格营地布局(随种子的城镇方向变体)是否与服务器一致(mapSeed / 预设 lvlprest 选择);
  • 渲染相机是否跟随服务器坐标,还是使用了本地推算的出生点;
  • 土黄色方块是否为缺失美术的单位兜底绘制(与 anti-silent-failure 规则相关)。

验证要求

修复后应在无头浏览器 / bot 中对比服务器下发坐标与客户端渲染位置,并覆盖多个地图种子(城镇方向变体)。

## 现象 进入游戏后,角色出现在罗格营地(Rogue Encampment)木栅栏外的树林里,而不是营地内的起始位置。 ![user-start-pos.png](https://git.projectdiablo2.cn/attachments/f856733b-87c9-4d10-84ae-5c7be0034593) 截图中还能看到: - 画面上散布多个土黄色方块(疑似未解析到美术资源的单位/对象占位绘制); - 角色旁边有一个绿色矩形标记。 ## 复现环境 - 页面:`play.html`(本地 8080),分支 `refactor/remove-legacy-sp` @ `3c1ed16` - 服务器:`www.laiseek.xyz`(PvPGN + D2GS 1.13c),Realm `Sanctuary` - 账号 / 角色:`troytt` / `troytt`(刺客,1 级,资料片,软核,天梯,新建角色首次进入) - 场景:Act 1 城镇,新建游戏后首次进入 - 时间:2026-10-01 17:1x(UTC+8) ## 期望(1.13c) 新角色进入 Act 1 时应位于罗格营地内的起始点(营地内部可行走区域),与 D2GS 下发的玩家坐标一致。 ## 待排查方向(未验证,仅供定位) - 服务器 `0x59 AssignPlayer` / `0x15 ReassignPlayer` 坐标与客户端 DRLG 关卡原点(LoadAct / 房间 reveal)之间的坐标换算; - 客户端生成的罗格营地布局(随种子的城镇方向变体)是否与服务器一致(mapSeed / 预设 lvlprest 选择); - 渲染相机是否跟随服务器坐标,还是使用了本地推算的出生点; - 土黄色方块是否为缺失美术的单位兜底绘制(与 anti-silent-failure 规则相关)。 ## 验证要求 修复后应在无头浏览器 / bot 中对比服务器下发坐标与客户端渲染位置,并覆盖多个地图种子(城镇方向变体)。
Author
Owner

已修复,合并到 main:b3452a4(修复 87b074d,测试 c7331bf + b3452a4)。

根因

服务器给的出生坐标一直是对的(玩家站在营地地面上),是客户端画错了位置,有两个原因:

  1. 投影比例只有一半:viewport-profile.ts 按 16×8 px 的格子投影 sub-tile,而 1.13c 地砖是 160×80 px = 5×5 个 32×16 px 的 sub-tile。所以玩家、相机和所有单位都画在离关卡原点一半距离的位置。
    • 例:seed 0x31595789,服务器坐标对应营地地面 local (137,123),旧代码画到了 (68.5,61.5),正好是栅栏外面。
  2. 渲染的关卡选错了:画面用的是 MapService "最后构建的关卡"。在北门附近出生时,服务器会推送 Blood Moor 的房间(0x07),整张地图就被换成了 Blood Moor。

修复

  • 投影改为 1.13c 的 32×16 sub-tile 格子,屏幕和世界坐标可以精确互相换算,点击拾取也一起修正。
  • 新增 MapService.findLevelViewAtWorldSubTile:按玩家的服务器坐标选包含它的关卡。
  • 删除了几处静默回退:默认城镇 || 1、坐标偏移猜测、LoadAct 吞异常、无地图时默认可行走。在关卡和服务器坐标都就绪之前,只显示黑屏加 HUD。

验证

  • tests/client/spawn-position-539.test.ts:覆盖 5 份新录的 fresh game 抓包(10-d2gs-spawn-seed-*)、所有已有抓包,以及 3 种营地布局。断言渲染出的玩家和相机等于服务器坐标、站在营地可行走地面上、能走到 waypoint,并且 Blood Moor 的房间推送不会切换渲染的关卡。
  • 合并后全量检查:typecheck 0 error,build 通过,抓包回放 strict 14 个文件、3201 条记录、unknown/opaque/errors 全为 0,vitest 0 失败(已知的 tier4 180s 超时用例单独重跑通过)。修复分支上跑过浏览器端到端 verify-play,9/9 通过。

修复后截图(人物在营地内):

issue539-after.png

图里的黄褐色方块和绿色矩形是 object/NPC 缺美术时画的占位色块,另开了 #540 跟进。

已修复,合并到 main:`b3452a4`(修复 `87b074d`,测试 `c7331bf` + `b3452a4`)。 ## 根因 服务器给的出生坐标一直是对的(玩家站在营地地面上),是客户端画错了位置,有两个原因: 1. **投影比例只有一半**:`viewport-profile.ts` 按 16×8 px 的格子投影 sub-tile,而 1.13c 地砖是 160×80 px = 5×5 个 32×16 px 的 sub-tile。所以玩家、相机和所有单位都画在离关卡原点一半距离的位置。 - 例:seed `0x31595789`,服务器坐标对应营地地面 local (137,123),旧代码画到了 (68.5,61.5),正好是栅栏外面。 2. **渲染的关卡选错了**:画面用的是 MapService "最后构建的关卡"。在北门附近出生时,服务器会推送 Blood Moor 的房间(0x07),整张地图就被换成了 Blood Moor。 ## 修复 - 投影改为 1.13c 的 32×16 sub-tile 格子,屏幕和世界坐标可以精确互相换算,点击拾取也一起修正。 - 新增 `MapService.findLevelViewAtWorldSubTile`:按玩家的服务器坐标选包含它的关卡。 - 删除了几处静默回退:默认城镇 `|| 1`、坐标偏移猜测、LoadAct 吞异常、无地图时默认可行走。在关卡和服务器坐标都就绪之前,只显示黑屏加 HUD。 ## 验证 - `tests/client/spawn-position-539.test.ts`:覆盖 5 份新录的 fresh game 抓包(`10-d2gs-spawn-seed-*`)、所有已有抓包,以及 3 种营地布局。断言渲染出的玩家和相机等于服务器坐标、站在营地可行走地面上、能走到 waypoint,并且 Blood Moor 的房间推送不会切换渲染的关卡。 - 合并后全量检查:typecheck 0 error,build 通过,抓包回放 strict 14 个文件、3201 条记录、unknown/opaque/errors 全为 0,vitest 0 失败(已知的 tier4 180s 超时用例单独重跑通过)。修复分支上跑过浏览器端到端 verify-play,9/9 通过。 修复后截图(人物在营地内): ![issue539-after.png](https://git.projectdiablo2.cn/attachments/f59b719e-74bb-42f0-89be-edcbce335c2d) 图里的黄褐色方块和绿色矩形是 object/NPC 缺美术时画的占位色块,另开了 #540 跟进。
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: troytt/diablo2-web#539
No description provided.