请选择 进入手机版 | 继续访问电脑版
设为首页收藏本站

ESFKAMI

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz

ESFX

ESF: Xenoverse

ESF123

ESF1.2.3

EVM2.1

EVM2.1

ECXSSJ

ECX: TeamSSJ

ECX2.2

ECX RC2

ECX2.3

ECX RC3

查看: 2239|回复: 0

[HLSDK]Delta详解

[复制链接]

212

主题

217

帖子

1229

积分

ESFKAMI

Rank: 8Rank: 8

积分
1229
发表于 2017-7-27 14:01:37 | 显示全部楼层 |阅读模式
by Akatsuki


服务端和客户端总是需要互相交换数据,来做到实时的游戏体验。

很久之前,我们的网速都不是很快,甚至带宽只有 1Mbps (128KB/s)这样的速度,作为当时一个网络实时对战游戏,每时每刻都要传递数据,为了完成各种各样复杂的效果,要传递的数据量自然也就多了。

为了减少需要发送的数据大小,引擎的程序员开发出了 Delta 模块。

它能把需要传递的数据的大小压缩到极致,大大减少了网络传输的数据量,使得当时网速很慢的电脑也能流畅地玩游戏!

如果你看过我的前两篇文章,你一定对 clientdata_t、entity_state_t 有些了解(如果你还没看过,我建议你去看看),查看结构体你会发现里面的成员大多数是 int、float (4字节变量)为了节约网络带宽占用,引擎还会对这些变量进一步处理,才能发给客户端。

这里就是 Delta 模块发挥的时候了,打开 valve/delta.lst 或者 esf/delta.lst 这个文件,能看到这样的代码:

  1. clientdata_t none                    
  2. {
  3.     DEFINE_DELTA( flTimeStepSound, DT_INTEGER, 10, 1.0 ),
  4.    
  5.     // ...
  6.     DEFINE_DELTA( m_flNextAttack, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),

  7.     // ...
  8.    
  9.     DEFINE_DELTA( m_iId, DT_INTEGER, 5, 1.0 ),
  10.    
  11.     // ...
  12. }
复制代码
首先你看到了眼熟的 clientdata_t 这个结构体名字,接着还有它的成员们。

我们可以看到 DEFINE_DELTA ( .. ) 里有一些参数,我们逐个来分析它们。

为了方便讲解,我们从 DEFINE_DELTA( m_iId, DT_INTEGER, 5, 1.0 ) 这行开始。

第一个参数 m_iId 毫无疑问表示 clientdata_t 里的 m_iId 这个成员变量。

第二个参数 DT_INTEGER 表示这个成员变量是 整数型。

第三个参数 5 表示这个变量最多占用多少个“位”(如果你不知道“位”是什么,我建议你搜索“位和字节”来复习一下基础)下文简称占位参数。

第四个参数 1.0 对于整数型成员变量来说,它总是 1.0 不需要改变

重点来啦!注意第三个参数,这里是 Delta 模块压缩数据的精髓!我们知道一个 int 型变量要占用 4字节 也就是 32位,它能存下一个超级大的数值,

但我们的变量可能不需要存这么大的数值,比如我的 m_iId 的值最大就 31,连 1字节 都不够,只需要 5位!

Delta模块会在发送数据前,根据这个配置文件来精简变量数据(压缩),把要发送的数据压缩到最小!

比如上面的 m_iId 这个变量,经过 Delta压缩,只剩下 5位,这远远小于一个 int(32位)!Delta 根据配置文件来压缩每个成员变量的大小,到最后,引擎要发送的数据将会变得非常小!

这里还要解释一下传递小数(FLOAT)时是如何计算位数的,上面提到了一个 1.0 的参数,实际上它是一个倍数,Delta模块在处理小数时,会把小数乘上这个倍数,得到一个整数,

比如我的 m_flNextAttack 里的数值是 12.55 乘 1000.0 变成 12550 这样一个整数,而这个整数至少需要 13位 才能存得下,所以占位参数至少要写 13 才能发送 12.55 这个小数给客户端。然后客户端再除以 1000.0 就得到了这个小数。

你一定注意到还有个 DT_SIGNED ,它表示这个变量允许保存负数,它会额外占用 1位 数据,所以写占位参数时,要考虑到它。

你可以在 delta.lst 里为每个成员变量配置大小,这是非常必要的。当你决定要传递一个新的数据时,请一定要记得配置 delta.lst 不然你的客户端可能会接收到一个错误的数值。



Delta模块还有十分强大的差异管理功能,服务端不会每一帧都发送完全相同的数据给客户端,这很没必要。Delta会过滤掉没有改变的数据,只发送有变化的部分数据给客户端,进一步减少了数据发送量!

相信你一定已经被Delta的强大吸引,但是经过Delta压缩的数据,还会经过更高级的数据压缩算法压缩才发送给客户端。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|ESFKAMI    

GMT+8, 2018-11-19 18:13 , Processed in 0.260196 second(s), 21 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表