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

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

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

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

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

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

clientdata_t none
{
DEFINE_DELTA( flTimeStepSound, DT_INTEGER, , 1.0 ), // ...
DEFINE_DELTA( m_flNextAttack, DT_FLOAT | DT_SIGNED, , 1000.0 ), // ... DEFINE_DELTA( m_iId, DT_INTEGER, , 1.0 ), // ...
}

首先你看到了眼熟的 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压缩的数据,还会经过更高级的数据压缩算法压缩才发送给客户端。。。

我总觉得我忘了什么事情,等我想起来再补充吧!

【HLSDK系列】Delta 详解的更多相关文章

  1. PHP输出缓存ob系列函数详解

    PHP输出缓存ob系列函数详解 ob,输出缓冲区,是output buffering的简称,而不是output cache.ob用对了,是能对速度有一定的帮助,但是盲目的加上ob函数,只会增加CPU额 ...

  2. 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程

    反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑)   背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...

  3. SignalR新手系列教程详解总结(转)

    SignalR新手系列教程详解总结 GlobalHost.ConnectionManager.GetHubContext<TodoListHub>() .Clients.Clients(l ...

  4. 猫哥网络编程系列:详解 BAT 面试题

    从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...

  5. 【WebApi系列】详解WebApi如何传递参数

    WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...

  6. css3系列之详解perspective

    perspective 简单来说,就是设置这个属性后,那么,就可以模拟出像我们人看电脑上的显示的元素一样.比如说, perspective:800px   意思就是,我在离屏幕800px 的地方观看这 ...

  7. 【tomcat系列】详解tomcat架构(上篇)

    java中,常用的web服务器一般由tomcat,weblogic,jetty,undertwo等,但从用户使用广泛度来说,tomcat用户量相对比较大一些,当然这也基于它开源和免费的特点. 从软件架 ...

  8. Java并发包源码学习系列:详解Condition条件队列、signal和await

    目录 Condition接口 AQS条件变量的支持之ConditionObject内部类 回顾AQS中的Node void await() 添加到条件队列 Node addConditionWaite ...

  9. pssh系列命令详解

    安装 pssh提供OpenSSH和相关工具的并行版本.包括pssh,pscp,prsync,pnuke和pslurp.该项目包括psshlib,可以在自定义应用程序中使用.pssh是python写的可 ...

  10. css3系列之详解border-image

     border-image border-image呢,是给 边框加上背景图片的.没错,就是平常那一小小条的边框,也能加图片. 参数: border-image-source border-image ...

随机推荐

  1. angular中的$q服务实例

    用于理解$q服务 参考:http://www.zouyesheng.com/angular.html#toc39 广义回调管理 和其它框架一样, ng 提供了广义的异步回调管理的机制. $http 服 ...

  2. ADO.NET操作MySQL数据库

    前言 ADO.NET包括5大对象,分别是Connection.Command.DataReader.DataSet.DataAdapter,使用ADO.NET访问数据库有两个步骤:建立数据库连接.读取 ...

  3. Spring学习(一)-----Spring 模块详解

    官方下载链接:http://repo.spring.io/release/org/springframework/spring/ Spring 模块详解: Core 模块 spring-beans-3 ...

  4. Linux TCP/IP调优参数 /proc/sys/net/目录

    所有的TCP/IP调优参数都位于/proc/sys/net/目录. 例如, 下面是最重要的一些调优参数,后面是它们的含义: /proc/sys/net/core/rmem_default " ...

  5. 韦大仙--LoadRunner压力测试:详细操作流程

    一. 录制脚本 1.安装完毕后,创建脚本: 点击OK之后,会弹出网址,之后创建Action,每进一个页面添加一个Action,录制结束后,终止录制. 二. 修改脚本 1.脚本参数化 将登录的用户名密码 ...

  6. idea 临时文件

    idea可以直接创建一个 scratch file (mac os快捷键 cmd+shift+n) 在里面可以自由的编辑文档, 配合vim使用很方便, 我使用的频率还比较高. 大概是这样的. 这个临时 ...

  7. 启动sshd时,报“Could not load host key”错

    原文发表于cu:2016-05-24 现象:启动sshd服务时,虽看似服务启动成功,但客户端并不能连接上sshd服务器端.如下: [root@aefe8007a17d ~]# /usr/sbin/ss ...

  8. html js 全选 反选 全不选源代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  9. LeetCode 148——排序链表

    1. 题目 2. 解答 2.1 快速排序 可参考 快速排序和归并排序 中的第一种快速排序思想,与在数组中排序有两点不同. 第一,我们需要取最后一个元素作为主元,在数组中可以直接访问到最后一个元素,但在 ...

  10. Java fluent风格(转载)

    转载:java Fluent风格 一.我们先写一个通常的,即不使用fluent风格 1.实体类 package com.xbq.demo.stu; /** * @ClassName: Student ...