金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks
帧同步是否允许客户端指定命令帧号

(金庆的专栏 2020.10)

帧同步服务器以固定的帧率收集每个客户端的输入命令,每帧打包一个命令帧,打上服务器当前帧号,
然后广播该命令帧到每个客户端,由客户端执行。
如果没有客户端输入命令,则该命令帧可能只有一个帧号。

客户端的输入命令分2种模式:不指定帧号和指定帧号。

客户端不指定帧号的模式下,客户端仅告诉服务器自己的动作,由服务器为该动作打上当前的服务器帧号,然后再广播。
服务器实现较简单,只需要缓存当前帧的所有客户端输入,下一帧时全部打包广播。

指定帧号的模式下,客户端要求该命令在指定帧(服务器帧)才生效。
服务器需要缓存该命令,运行到指定帧号时,才将该命令打包到命令帧并广播所有客户端。

指定帧号在客户端有预测回滚时较为有利,因为客户端知道自己的命令将在确定的帧执行,即对自己的预测总是成功的。
而如果不指定帧号,客户端需要预测自己的命令会在哪个服务器帧到达服务器,而这在网络抖动较大时会预测失败。

指定帧号会造成命令的延时时间较长。而不指定帧号将会立即执行。

如果网络堵塞了一会儿,客户端发送的命令延时了较长时间才到达服务器,
指定的帧号可能小于服务器当前帧号,这时服务器对该命令有2种处理方式.
一种是直接忽略该命令,因为该命令已无法实现。
一种是尽量实现该命令,即在当前帧执行。
考虑到客户端预测,2种都是预测失败,同样需要回滚,但是在当前帧执行可能回滚造成的抖动会小一点。
如起跳命令,一种是已经跳起来了被拉回地面,因为起跳命令被取消了,一种是跳在空中停顿了一下,因为起跳的时间点被延后了。
尽量实现命令应该比丢弃命令更好一点。

如果是在当前服务器帧执行过期帧号的命令,那么这2种模式可以合并成一种,即所有命令都是指定帧号,
只是有的帧号是0,表示让服务器在当前帧执行。

通用的帧同步服务器应该让客户端指定帧号。

指定帧号的命令可以实现严格时间间隔的命令序列,
客户端可以一次性发送整个命令序列,指定每个命令为不同的帧号。
还应该允许客户端指定命令序列的帧间隔,但是首命令是立即执行的。
命令序列的帧号应该是相对于首命令的。
如果命令序列的首命令延后执行,那么整个序列全部将同样延后。

客户端是否需要知道自己的指定帧号命令被延后执行了?这样可以让客户端有更好的表现?
那么成功执行的指定帧号命令是否也应该让客户端知道?
服务器仅仅是将客户端命令原样广播,客户端命令中可以加入命令序号,自行判断命令是否延后了。

是否将一个玩家的提前发送的指定帧命令提前广播给其他玩家?
这样其他玩家不仅对自己预测成功,对该玩家的预测也成功。
但是泄露了自己将要执行的动作会被其他玩家利用。
所以提前量不能太大,指定帧号应该尽量接近服务器帧号。
服务器就不用缓存客户端指令了,直接收到后广播即可。
这样服务器广播的命令帧中有服务器帧号,也有客户端的指定帧号。
服务器也就不用管客户端是否指定帧号了。
指定帧号和解析成为纯客户端逻辑。



posted on 2020-10-08 11:39 金庆 阅读(373) 评论(0)  编辑 收藏 引用 所属分类: 2. 网游开发

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理