【muzzik】3D物理帧同步

之前做商业小游戏的物理帧同步时,发现使用wasm的物理引擎始终不会同步,但是改为纯 js 的逻辑就同步了,然后花了点时间研究的成果

Demo 信息

小破服务器加载大概10秒左右,请耐心等待

预览地址:http://139.224.226.7:8080/

所有人在同一房间内,可以自行用多台设备对比查看,房间 2 分钟重置一次防止追帧时间过长

  • 物理引擎:PhysX
  • 开发框架:MKFramework
  • 帧同步:包含逻辑/渲染帧管理器,延迟追帧,重连追帧,(未实现预测)
  • 服务器:纯 Nodejs 开发,包含简易的房间管理,完整的帧同步逻辑

  • 支持平台:Web
  • 支持物理引擎:PhysX,Bullet

源码

  • 帧同步框架(服务器/客户端):之后会发布在 MK 官网的项目列表

  • 物理帧同步源码:之后会发布到商店,可以搜索 3D物理帧同步 查看

同步原理简述

同步依靠Wasm和JS的浮点运算一致性。是否可以同步取决于平台是否符合 ES6 规范,严格来说默认是必须符合的,所以不同步的设备占少数,具体比例未知可自行测试。针对少数不同步的设备解决方案如下

针对少数不同步的处理

客户端将每帧的物理节点坐标及旋转信息生成一个 md5 传递到服务器,如果服务器检测到设备A的 md5 与设备B的 md5 不一致时暂停 A 设备的物理模拟,并通知 B 开始派发坐标,旋转信息到服务器,服务器再转发给设备 A

这样做会导致 A 的延迟增加,但是可以保持一致性,而且 A 属于少数不需要担心服务器资源被占用

仅提供理论,Demo 未包含此逻辑

关于多平台

对于 Android 平台而言,由于物理引擎是C++代码实现的,所以在多设备间仍然可能存在不同步的情况,具体查看 gpt 说明:https://chatgpt.com/share/696ca09c-d53c-8004-93df-b2ab3956e307

按照 gpt 的解释,不同步率也是占据少数,我自己也用一部老手机 魅族MX5(android5.1)和电脑的夜神模拟器(Andorid9.0)测试的情况是同步的。但是原生端目前不支持重置物理引擎(应该可以改C++代码实现),这是物理同步必要的条件。

针对不同步的情况,这里也提出一个想法,检测到不同步后(md5),记录最新的刚体信息,重置多台设备的物理引擎,重新赋值坐标、旋转、速度等… 不过这些都需要后续验证

2赞

没考虑过rapier吗, 用第三方物理也方便写纯逻辑给服务端跑验证。

rapier需要写引擎适配代码和组件,目前这个只需要使用内置物理引擎就可以,另外验证不需要服务器跑物理引擎