作者bearnone (无)
看板GameDesign
标题[程式] 前、後端物理运算一致性
时间Thu Jan 28 12:37:09 2021
最近尝试使用Box2D做为物理引擎来模拟与制作游戏(想要模仿怪物弹珠)
但遇到了前、後端同步的问题
为了避免前端直接传送封包作弊
希望乱数与物理参数(速度、反作用力等)都是由後端产生
最後由前端直接带入後端产生的参数并驱动Body产生结果
在物理引擎上前、後端皆使用fixed timestamp的方法去运行
状况1:
场面上除了玩家操控的Body外
其他物件都是不会移动的(仅会产生物理碰撞)
玩家的操作会有随机性并产生物理参数让前端使用
一开始有使用CCD但在某些状况下会导致前、後端的位置不一样
後来去看了核心才发现主要原因是CCD所造成的
也因为游戏世界中并没有会高速移动的Body
所以就先将CCD的机制关闭
关闭後似乎就没有再出现运算结果不一致的状况
请问有办法在开启CCD的情况下也保持物理运算结果是一样的吗?
状况2:
承上述的状况1
但游戏世界中增加了一些会自体来回移动的Body并影响玩家的操作结果
请问要如何让前端只使用物理参数下可以达到运算结果一致?
以下提供我想到的解法
把後端在物理运算中每一个tick的结果保存下来传送给前端演示
但这种做法会导致封包流量过大
以一秒钟固定跑60个tick的状况下
每一次动作可能产生5 ~ 6KB的流量
虽然可以让前端完美重现但流量应该会爆炸
而且上面的做法假设碰到状况2就完全无法适用
中间也有参考一些别人的游戏
但有些游戏似乎是让前端去跑结果并且告知後端
请问这样做不会容易发生作弊的状况吗?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 220.134.195.1 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1611808631.A.ABD.html
※ 编辑: bearnone (220.134.195.1 台湾), 01/28/2021 13:05:50
1F:→ dklassic: 最简单的方法就是你自己推算玩家的施力跟方向去算出移 01/28 17:26
2F:→ dklassic: 动路径与碰撞结果吧,而不是真的靠物理模拟去做 01/28 17:26
3F:推 wulouise: 你可以前端先算画面,最後後端再更新,不然一定慢 01/28 18:38
4F:→ wulouise: 大部分网路游戏的前端都有偷算,跟後段比差很多再拉会 01/28 18:39
你说的方法不知道是否是所谓的Client side prediction?
目前碰到的难题是
前端演示的画面显示该路径是会得到奖励的
但实际上跟後端的计算是有误差的(後端的路径并无实际碰到奖励范围)
如果最後前端依据後端(权威性)结果去做画面修正
深怕玩家会来吵糖吃
5F:推 ddavid: 网路游戏常见的延迟造成瞬移就是这种前端预测跟後端实算有 01/29 10:39
6F:→ ddavid: 差异造成的结果,这几乎是必备技术了 01/29 10:40
你提及网路延迟的部分不知道跟我下面理解的是否一样?
大部分即时的游戏都会侦测延迟的状况
并依照延迟的形况去做画面修正
如果只是轻微延迟可能会利用补间的方式去修正
但是当延迟过大的时候则是将画面停滞并且做大幅度的一次性修正
7F:推 LayerZ: 唯一的变数只有玩家的角度与力道,其他所有都是常数 01/29 22:35
8F:→ LayerZ: 不要太依赖物理特性了,物理特性应该是做出来的表现效果 01/29 22:36
9F:→ LayerZ: 去依靠Unity的物理引擎来做出本来该自己做的其实是邪道.. 01/29 22:37
10F:推 LayerZ: 结果跟原文完全没关系抱歉Orz... 01/29 22:47
11F:→ dklassic: 啊我理解错,我在干嘛 XD 01/30 02:24
12F:→ dklassic: 前端先模拟是满正常的作法,这边效能跟作弊是一体两面 01/30 02:24
13F:→ dklassic: 的难题就只能看取舍了 01/30 02:24
是说通常效能跟作弊一定要有所取舍吗?
因为主要感兴趣的部分是後端层面
所以对玩家作弊的部分会比较想要理解怎样处理
14F:推 LayerZ: 认真回一下,基本上是不可能做到前後端同步的,如果做得到 01/31 14:06
15F:→ LayerZ: 就已经突破云端游戏瓶颈了 01/31 14:06
16F:→ LayerZ: 一般有两种做法,一种是控制变数常数,Client端物理表演, 01/31 14:07
17F:→ LayerZ: Server端验算 (目前常见短连线游戏),一种是资料Server端 01/31 14:07
18F:→ LayerZ: 为主,Client仅依照Server端送下来的资讯作出表演,如何用 01/31 14:08
19F:→ LayerZ: 这些资讯让表演逼真是另一个领域了 01/31 14:08
20F:→ LayerZ: (MMO之类) 01/31 14:08
21F:→ LayerZ: 至於你说的作弊,作弊抓的到就好,指要让他正常游玩不会出 01/31 14:09
22F:→ LayerZ: 问题就没关系,至於玩家不管用任何手段作弊,只要server端 01/31 14:10
23F:→ LayerZ: 抓得出来(各种验算) 就能即时处理掉 01/31 14:10
请问你说的变数常数主要是控制哪些部分?(是指物理参数吗?)
目前想到的方法好像是比较偏向你说的方法2
我打算在Client跟Server都用Box2D去创建一个游戏世界(world)
并且让Client跟Server端的world尽可能保持在一致的状态
当玩家进行游戏操作後
Client会将该操作的RPC封包送至後端
後端接收封包後後产生结果(使用物理引擎计算路径并且包含乱数因素)并回传前端作演示
但这样似乎有可能会碰到浮点数精准的问题(?)
另外场面上如果有移动性的Body
似乎也会导致无法单靠物理参数就导出同样的结果
另外想询问如果要防止作弊的方法
有哪些常见的方式吗?
谢谢
※ 编辑: bearnone (220.134.195.1 台湾), 02/01/2021 14:43:51