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
4.4 KiB
4.4 KiB
M4 · 逼近真实负载(可选)
总纲:
../PLAN.md§06。 本文件是 M4 的详细施工文档。可选 —— M3 全绿已经能给出 go/no-go 结论,M4 只是把结论从"骨骼网格能跑"推到"接近真实负载也能跑"。
目标
在 M3 已验证的基础上,加 GPU 蒙皮、eterpack 加载、多角色 + 地面 + 简单光照、LOD 切换, 把性能结论从简化场景推到接近真实的负载。
前置
交付物
| 产物 | 位置 |
|---|---|
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 sampled;Adreno 老驱动测一下 |
| 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 反证清单 + 一页纸结论的"正式移植还缺什么"部分