Files
shenandClaude Sonnet 5 47baf6c0c6 Metin2 game client (P0–P11) + mobile asset pipeline
Networked client on the existing Godot 4.7 + libgr2 renderer:
- net: m2dev wire protocol (libsodium KX + XChaCha20), auth/select/game
  phases, EntityStore world model, ~all GC/CG headers. char create/delete,
  private shop / mall / cube, SHOP_GC_START_EX, guild, party (+ CG_PARTY_SET_STATE),
  quests, dragon soul, refine, safebox, exchange.
- UI: in-game windows migrated 1:1 from the reference uiscript/root .py —
  char status (/stat), inventory+equipment, select-item ([SELECT_ITEM] quest
  token), system-option + game-option + ESC system menu, private-shop 39-grid,
  party info board, shop tabs, atlas, minimap, quickbar, chat, …
- EterGrnLib polish: GR2 material blend/two-sided, LOD crossfade, motion-event
  dispatch, contact shadow, ray-AABB picking, weapon grip pre-transform.

Portable asset IO (A1) — all extension/libgr2/formats/mtproto reads routed
through godot::FileAccess (res:// PCK works on iOS/Android); standalone-lib
*_path() kept for the non-Godot CTests. AssetResolver + PropertyRegistry
switched to a baked index (bake_asset_index.gd) instead of std::filesystem.

Mobile builds: build-{android,ios}.sh, export-android.sh, pack-assets.sh,
gen-debug-keystore.sh. Assets ship as a zip mounted at runtime by
project/asset_pack.gd (adb push now; HTTP download is a drop-in later).

ctest 10/10, 34 GDScript suites, macOS/iOS/Android all build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EJxkHiNKS4kybHS3XKyAJ
2026-08-31 20:02:12 +09:00

93 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M4 · 逼近真实负载(可选)
> 总纲:[`../PLAN.md`](../PLAN.md) §06。
> 本文件是 M4 的详细施工文档。**可选** —— M3 全绿已经能给出 go/no-go 结论,M4 只是把结论从"骨骼网格能跑"推到"接近真实负载也能跑"。
---
## 目标
在 M3 已验证的基础上,加 GPU 蒙皮、eterpack 加载、多角色 + 地面 + 简单光照、LOD 切换,
把性能结论从简化场景推到接近真实的负载。
## 前置
- [M3](./M3-mobile.md) 全部门禁通过。
- [M2](./M2-anim-skinning.md) 的 CPU 蒙皮作为 GPU 蒙皮的对拍基准。
## 交付物
| 产物 | 位置 |
|---|---|
| GPU 蒙皮路径(`vs_pnt_skinned` 全量启用 + 骨骼矩阵 texture 上传) | `engine/skinning.cpp` `app/shaders/` |
| eterpack 加载路径接入 | `reuse/EterPack/` + `engine/scene.cpp` |
| 多角色场景(1 / 8 / 20 / 50 + 地面 + 方向光 | `app/` |
| CPU vs GPU 蒙皮对拍报告 | `test/m4-skin-cmp.json` |
| 扩展性能曲线 | `test/m4-perf-curve.json` |
---
## 任务分解
### T1 · GPU 蒙皮
- 骨骼矩阵改走 GPU:小骨架用 `bgfx::setUniform(u_bones, mtx, boneCount)`uniform 数组,上限 ~128);大骨架 / 多实例用**骨骼矩阵 texture**`bgfx::createTexture2D(RGBA32F)` 每帧 `updateTexture2D`VS 里 `texelFetch`)。
- `vs_pnt_skinned.sc` 从 M2 的演示版转正。
- **完成判据(门禁)**:GPU 蒙皮输出顶点与 M2 的 CPU LBS 结果一致(离屏 transform feedback 或渲到 RT 读回对拍),`‖Δ‖ < ε_vtx`
### T2 · eterpack 加载路径
- `reuse/EterPack`(冻结拷入):`CEterPackManager::RegisterPack` + `Get(mappedFile, "d:/ymir work/.../xxx.gr2", &data)` → LZO 解压 + 解密 → 裸字节喂 `libgr2`
- 需要 `assets/` 打包成 `.eix/.epk``m2dev-client-main/assets/PackMaker.exe``pack.py`Windows 侧一次性做)。
- **完成判据(门禁)**:同一 gr2 经 eterpack 路径 vs 散文件路径,`libgr2` 产出的骨架 / 网格 byte-identical。
### T3 · 多角色场景
- N 个 warrior 实例(各自动画时钟错开),一块带贴图的地面(用一个 zone 静态 gr2 或程序化 quad + terrain 贴图),一个方向光。
- 实例化:bgfx `instanceDataBuffer`(每实例 model 矩阵);蒙皮 texture 每实例一段。
- **完成判据**:50 个角色可交互帧率(真机上 ≥ 20fps 作为下限参考,非硬门禁)。
### T4 · LOD 切换(运行时)
- 按相机距离在 LOD 0–3 间切(用 M2 T6 已验的 LOD 一致性)。
- 切换要平滑:同帧不要让顶点跳(M2 已验位移 < 阈值),或加一帧 cross-fade。
- **完成判据**:镜头拉远/拉近,LOD 切换无肉眼可见 pop。
### T5 · 扩展性能曲线
- 简化 + 满配角色,各 1 / 8 / 20 / 50 个,三台基准机各跑一遍。
- 画帧时间 vs 角色数曲线,标出 CPU 蒙皮 vs GPU 蒙皮两条线。
- 写进 `test/m4-perf-curve.json`
---
## 门禁(go / no-go
- **GPU 蒙皮结果与 CPU 一致**`‖Δ‖ < ε_vtx`)。
- **eterpack 路径与散文件结果一致**byte-identical 骨架 / 网格)。
- 50 角色可交互帧率(参考线,非硬门禁)。
- LOD 运行时切换无 pop。
## 验证
- CPU / GPU 蒙皮对拍(T1)。
- eterpack vs 散文件对拍(T2)。
- 扩展性能曲线覆盖 1 / 8 / 20 / 50 角色 × 两种复杂度 × 三台机(T5)。
## 本步风险
| 风险 | 缓解 |
|---|---|
| GPU 蒙皮骨骼矩阵上传带宽(每帧每实例 60 骨 × 64B) | 用骨骼 texture + `texelFetch`,只 update 变化实例;half-float 视精度 |
| eterpack 解密 key / IV(客户端从服务器拿 `RetrieveHybridCryptPackKeys`) | demo 用离线打包的非加密 pack,或把 key 硬编进 `test/`(自用不公开)|
| 实例化 + 蒙皮 texture 在 GLES3 的上限 | GLES3 保证 `texelFetch` + `RGBA32F` sampledAdreno 老驱动测一下 |
| 50 角色 draw call 爆 | 按材质 / 程序批;满配角色本来就多 draw call,接受较低帧率 |
## DoD 清单
- [ ] GPU 蒙皮输出 == CPU LBS`test/m4-skin-cmp.json`
- [ ] eterpack 路径 == 散文件路径(骨架 / 网格 byte-identical
- [ ] 多角色场景(含地面 + 光)可跑,LOD 运行时切换无 pop
- [ ] `test/m4-perf-curve.json`1/8/20/50 × 简化/满配 × 三机,CPU/GPU 两条线
- [ ] 结论并入 PLAN §10.1 反证清单 + 一页纸结论的"正式移植还缺什么"部分