Easel全新定制物理引擎增量回滚功能让开发大型多人游戏成为可能2026年5月1日阅读时长9分钟。raysplaceinspaceEasel创作者。我们期望Easel强大到足以制作出让玩家沉浸数小时的游戏。像《Among Us》这类热门多人游戏玩家能在整个宇宙飞船中四处走动、完成任务并躲避冒名顶替者。可惜的是到目前为止这种规模的游戏对于Easel而言还难以实现。因为现有的物理引擎若要支持Easel的预测性多人游戏架构就必须对整个世界进行快照和回滚而每帧都这样做的工作量太大。在此之前你只能把游戏世界设计得“小一些”。但“现在不同了”Easel全新的“定制物理引擎”仅对世界中“发生变化的部分”进行快照和回滚。那艘巨大的宇宙飞船或许由数千个物体组成像墙壁、控制面板、通风口等。然而每帧中实际发生变化的物体数量少得惊人玩家在世界中走动和互动时每帧可能只有不到30个物体发生变化。智能的实现方式能让屏幕外的物体处于休眠状态。每帧只需对数千个物体中的30个进行快照比之前减少了30 - 50倍这使使用Easel开发大型世界的多人游戏突然变得可行了放手去做吧幕后原理Easel的新物理引擎是为Easel量身定制的所以它支持Easel的所有功能且表现更出色下面介绍一下它的一些独特特性。休眠机制做一件事最快的方法就是根本不做。当一个物体处于休眠状态时在它再次唤醒之前无需进行任何快照、回滚或物理计算。和其他引擎等待物体静止几秒后才进入休眠不同Easel会在物体速度降为零当然是在一个小的误差范围内时立即让其进入休眠状态。这里有个棘手的情况是“重力”它持续的作用力可能会让整个世界都保持活跃。Easel会跟踪每个物体上的力和反作用力判断它们是否平衡。无论物体速度是否为零只要堆叠中的一个物体受力不平衡整个堆叠就未达到平衡状态因此整个堆叠都会保持活跃。空间索引和许多其他物理引擎一样Easel的“宽相位检测”使用了边界体积层次结构Bounding Volume HierarchyBVH来快速查找潜在的碰撞。Easel的BVH算法经过优化可最大程度减少不必要的快照和回滚仅在树结构发生变化时进行增量重新平衡。这就如同你在朋友来访前才打扫房间一样Easel的BVH同样“高效”。另一个技巧是Easel的BVH还会跟踪每个碰撞体的 [类别](/docs/learn/physics/categories)这能显著加快常见的游戏查询速度。例如机器人经常需要定位最近的玩家如果玩家在地图的另一端它就不得不遍历世界中的每个碰撞体来找到最近的玩家。有了类似金属探测器的功能在众多 Category:Haystack 碰撞体中找到最近的 Category:Needle 碰撞体就快多了。移动机制在物理引擎中让角色移动看似简单实则相当复杂。常见的方法是在移动时增加速度物理模拟完成后再减去这个速度但当角色在移动过程中撞到障碍物时问题就出现了。即使物理引擎正确地将速度归零但之后减去之前增加的移动速度时又会重新引入物理引擎刚刚消除的反弹让角色感觉非常容易反弹。有些游戏通过“阻尼”消除所有速度来解决这个问题这样虽然消除了反弹但也消除了击退效果减少了游戏的趣味性。撞到墙时没有反弹这没问题但被火球击中时没有击退效果就感觉不太对了。其他游戏则通过基于射线检测创建“运动学角色控制器”来解决。在物理引擎术语中“运动学”与静态或动态相对意味着角色不受力和碰撞的影响。换句话说物理引擎未能产生预期的结果因此完全被绕过了。“物理引擎你就干好你的活啊。物理计算好好做。别这样算了我自己来吧。”Easel物理引擎的求解器直接内置了无反弹移动功能。只需使用 [ForcefulStep](/docs/reference/physics#forcefulstep) 并设置新的 restitution 0 参数Easel的新物理引擎就能确保移动不会产生反弹。它是如何工作的呢诀窍在于Easel处理移动的方式与处理位置重叠的方式类似。你是否玩过这样的游戏角色卡在墙里物理引擎试图将你“弹出”结果把你送到地图的另一端这是常见的物理引擎故障。《超级马里奥64》的速通玩家就利用这样的故障让马里奥背朝下滑上楼梯。哎哟现代物理引擎通过单独解决“位置校正”问题来避免这个问题。将角色从墙中弹出的力会立即应用到位置上而不改变速度这意味着“弹出速度不会持续到下一帧”。Easel中的 ForcefulStep 作为位置校正的一部分实现这就是它不会导致反弹的原因除非你希望它反弹。我们一举两得实际上由于多种原因情况要复杂一些。Easel首先同时求解弹出 移动和速度然后存储弹出速度接着移除弹出 移动约束并再次求解存储稳定后的速度。此时物体还没有移动所以我们现在可以使用正确的速度来扫描下一次碰撞的时间。到移动的时候我们使用弹出速度但在帧结束时只应用稳定后的速度这样反弹就消失了。换句话说Easel提前收集所需的所有数据而不进行更改这样在真正移动时就能做出正确的操作。连续碰撞检测我们喜欢看到两个火球在半空中相撞的场景。要检测两个快速移动的物体之间的碰撞需要进行连续碰撞检测因为如果我们每帧只检查一次碰撞可能会错过两个火球重叠的精确时刻。和其他物理引擎一样Easel通过扫描和形状投射来进行连续碰撞检测但在这个过程中我们发现Easel与其他物理引擎有一些不同之处这可能会让一些“游戏开发者”感兴趣**Rapier** 物理引擎在火球在帧开始时接触镜子的情况下可能会产生错误的结果。在Easel中碰撞会先得到解决使火球反弹并改变方向“然后” 再查找两个火球的碰撞时间。而在Rapier中它会先使用原始速度查找碰撞时间这意味着在这种情况下它会以错误的方向扫描火球。这种差异是因为Rapier过早进行位置积分在知道碰撞时间之前就确定了子步长。Easel提前存储了足够的信息能够在知道碰撞时间后再进行位置积分从而避免了这个问题。**Box2D 2.4** 使用正确的速度进行扫描但采用了先进行完整的常规物理模拟然后回溯的方法这就是为什么在连续碰撞检测之前所有碰撞都已经解决。有趣的是新的 **Box2D 3.0** 根本不支持动态对动态的连续碰撞检测这意味着那两个火球就像夜空中的两艘船一样会错过彼此。也许这是Box2D未来的发展方向除此之外他们似乎通过使用推测性接触实现了避免子步长的理想状态。**Photon Quantum** 是一款专业的多人回滚网络代码引擎它根本不支持连续碰撞检测理由是其物理引擎是无状态的实现起来成本太高。看来我们物理状态的增量快照和回滚功能让Easel能够高效地支持这一特性。物体可自行移动之前的物理引擎有一个不便的边缘情况即带有 velocity 或 turnRate 但没有碰撞体的物体根本不会移动。可以说这是合理的。如果没有质量来保持动量就不会有运动但我们不仅仅是在制作一个“物理” 引擎而是在制作一个“游戏” 引擎。有时候物体只是将精灵组合在一起的一种方式物理特性并不重要。现在如果你给一个物体设置 velocity 或 turnRate即使它没有碰撞体也会自行移动。附上一个 TextSprite你就可以让一个简单的广告牌在屏幕上向上漂浮滚动到遥远的星系。旁注光子没有质量但它们仍然有速度事实上现在每秒有 10^17 个光子正撞击你的眼睛所以也许有些物理引擎需要回归现实。致谢Easel的物理引擎基于 [Parry](https://parry.rs) 的碰撞检测算法构建Parry是Dimforge开发的优秀开源库为 [Rapier](https://rapier.rs) 物理引擎提供支持。开发一个物理引擎是一项艰巨的任务。为了让它简洁、高效并与Easel的多人游戏架构良好配合我们做了许多细微的决策。现在不仅物理引擎Easel的所有部分都只对发生变化的部分进行快照和回滚这意味着你可以创建更大的游戏世界。是时候大胆设想了标签[更新](/blog/tags/updates)[上一篇文章 子相机与火花效果2026年4月更新](/blog/2026-apr-update)幕后原理休眠机制空间索引移动机制连续碰撞检测物体可自行移动致谢政策[服务条款](/terms)[隐私政策](/privacy)[行为准则](/conduct)Easel[博客](/blog)[媒体资料包](/press)[联系我们](/contact)[](https://discord.gg/EJfzutBSz8 加入Easel的Discord社区)[](https://www.reddit.com/r/MadeWithEasel 在Reddit上关注Easel)[](https://x.com/madewitheasel 在Twitter上关注Easel)[](https://www.facebook.com/MadeWithEasel 在Facebook上关注Easel)[](https://www.tiktok.com/madewitheasel 在TikTok上关注Easel)[](https://youtube.com/MadeWithEasel 在YouTube上关注Easel)