游戏二进制序列化

游戏二进制序列化
MeteorCat近些年游戏序列化工具不断迭代更新, 比较知名的是 Protobuf|MessagePack 这种序列化,
如果性能要求不高甚至 JSON|XML 这种广泛集成语言也是可以作为游戏数据载体.
但是实际在项目使用当中发现其实 Protobuf 问题也很多, 包括以下问题:
-
项目引入不可预测的复杂性, 有时候版本可能出现冲突( ProtobufV2 和 ProtobufV3 )
-
没办法适应性动态处理数据, 结构变动必须要对
proto文件再编译导入游戏当中 -
而且对于小众语言来说, 可能根本没有具体实现处理
-
有的H5游戏上架平台对于底层数据读写功能要求很严格导致可能无法引入
特别是游戏项目, 很多都不采用外网软件库当中的项目引入而是自己内网重写相关功能,
所以对于游戏数据传输其实推荐更加采用原生二进制读写:
-
基本上是编程语言都支持, 真正跨平台处理, 不需要额外引入别的依赖
-
序列化过程可以自己动态处理, 不需要编译直接热更
这里采用 Java 语言做示例, 讲解怎么二进制在游戏当中怎么构建和传输.
数据结构
网络传输的数据结构一般常规以下几种:
-
byte|int8: 8位, 1字节, 一般用来替代 bool 值做0|1状态等 -
short|int16:16位, 2字节 -
int|int32: 32位, 4字节 -
long|int64: 64位, 8字节 -
float: 32位单精度 -
double: 64位双精度 -
bytes: 二进制, 字符串做二进制处理, 首位int32后面就是结构数据 -
list: 列表数据, 首位int32后面就是结构数据
还有比较少用到的:
-
char: 单字符 -
boolean: 布尔类型
一般原生数值类型不需要做处理, 如下直接填充就行:
1 | public class Main { |
Java默认采用大端网络序列做二进制处理
C# 之类的游戏客户端可以直接通过协议解包获取二进制主体解析, 这些基础类型没什么可以讲解重点是复合类型:
1 | public class Main { |
复合数据类型比较特殊, 因为内部长度并不是确定的, 所以需要提供标识长度给 服务端|客户端 做初始化缓冲区;
而如果想转化成结构类对象可能需要抽象实现自己的序列和反序列化功能:
1 | public class LoginMessage extends Message { |
这种解包方式在游戏项目当中十分常见, 对于项目侵入性低且编写方便.

