KBEngine 文档KBEngine 文档
首页
源码学习
架构
API
资料
指南
GitHub
首页
源码学习
架构
API
资料
指南
GitHub
  • 核心概念

    • API 总览
    • API 分类与核对清单
    • 基本数据类型
    • 关键词释义
  • 客户端

    • client插件
    • KBEngine模块
    • Entity类
    • Bots进程
    • KBEngine模块
    • Entity类
    • PyClientApp类
  • 服务端组件

    • Cellapp进程
    • KBEngine模块
    • Entity类
    • Baseapp进程
    • KBEngine模块
    • Entity类
    • Proxy类
    • Loginapp进程
    • KBEngine模块
    • Dbmgr进程
    • KBEngine模块
    • Interfaces进程
    • KBEngine模块
    • Logger进程
    • KBEngine模块

基本数据类型

KBEngine 的 .def 文件中,属性(<Type>)和方法参数(<Arg>)必须使用系统中已注册的数据类型。

类型总览

类型字节数数值范围Python 对应用途
UINT810 ~ 255int小范围非负整数(枚举、标志位)
UINT1620 ~ 65,535int较小非负整数(计数器、ID)
UINT3240 ~ 4,294,967,295int通用非负整数(最常用)
UINT6480 ~ 18,446,744,073,709,551,615int大整数(时间戳、大ID)
INT81-128 ~ 127int小范围有符号整数
INT162-32,768 ~ 32,767int较小有符号整数
INT324-2,147,483,648 ~ 2,147,483,647int通用整数(推荐默认)
INT648±9,223,372,036,854,775,807int大整数(时间戳、大ID)
FLOAT4±3.4E38(7位精度)float单精度浮点数
DOUBLE8±1.7E308(15位精度)float双精度浮点数
VECTOR212(x, y)tuple二维向量
VECTOR316(x, y, z)tuple三维向量(最常用)
VECTOR420(x, y, z, w)tuple四维向量
STRINGNASCII 字符串str普通字符串
UNICODENUTF-8/UTF-16 字符串str国际化字符串
PYTHONN任意 Python 对象any通用 Python 对象(需可序列化)
PY_DICTNPython 字典dict字典类型
PY_TUPLENPython 元组tuple元组类型
PY_LISTNPython 列表list列表类型
ENTITYCALLN实体调用句柄EntityCall跨实体/跨进程调用
BLOBN二进制数据bytes原始二进制数据

详细说明

整数类型

无符号整数 (UINT)

类型推荐场景避免使用
UINT8枚举值、标志位、百分比(0-100)可扩展的数量
UINT16小型计数器、临时ID可能超过 65K 的数量
UINT32默认无符号整数、实体ID可能超过 40 亿的数量
UINT64数据库自增ID、Unix时间戳一般情况(浪费空间)

有符号整数 (INT)

类型推荐场景避免使用
INT8小范围配置值、属性修正值可能溢出的数值
INT16伤害值、坐标偏移大数值
INT32默认整数类型超过 20 亿的数值
INT64金币数、积分、时间戳一般情况

选型建议:

  • 传递整数时,优先使用 INT32 作为默认选择
  • 确认数值范围不会溢出后再考虑 smaller 类型
  • 金币、积分等累积性数值务必使用 INT64

浮点类型

类型精度推荐场景
FLOAT7位有效数字坐标、3D计算、一般小数
DOUBLE15位有效数字精确计算、金融数值

注意事项:

  • 浮点数不应直接用 == 比较,应使用 abs(a - b) < epsilon
  • 金币等精确数值应使用 INT64 而非 FLOAT/DOUBLE

向量类型

<Properties>
    <position>
        <Type> VECTOR3 </Type>
        <Flags> BASE_AND_CLIENT </Flags>
        <Default> 0,0,0 </Default>
    </position>
</Properties>
类型Python 表示用途
VECTOR2(x, y)2D 坐标、UI 位置
VECTOR3(x, y, z)3D 坐标、位置、方向
VECTOR4(x, y, z, w)四元数、颜色 RGBA

字符串类型

类型编码推荐场景
STRINGASCII纯英文、数字、内部标识
UNICODEUTF-8/UTF-16多语言文本、用户输入

注意事项:

  • 客户端显示的文本应使用 UNICODE
  • 数据库字段长度需配合 <DatabaseLength> 设置

特殊类型

PYTHON - 通用 Python 对象

<Properties>
    <userData>
        <Type> PYTHON </Type>
        <Flags> BASE </Flags>
    </userData>
</Properties>

特点:

  • 可传递任意可 pickle 序列化的 Python 对象
  • 占用字节数不固定,取决于对象大小

限制:

  • 对象必须可序列化(不可包含线程、锁、文件句柄等)
  • 网络传输开销较大
  • 不能用于 CELL 和 CLIENT 间同步

适用场景:

  • 服务端内部临时数据存储
  • 复杂配置对象(非高频传输)

PY_DICT / PY_LIST / PY_TUPLE

这些是 PYTHON 的特化版本,更明确的类型约束:

类型Python 类型推荐场景
PY_DICTdict键值对数据
PY_LISTlist可变列表
PY_TUPLEtuple固定长度序列

注意:推荐使用 types.xml 中定义的 FIXED_DICT 和 ARRAY 替代这些类型,性能更好。

ENTITYCALL - 实体调用句柄

<Properties>
    <targetEntity>
        <Type> ENTITYCALL </Type>
        <Flags> BASE </Flags>
    </targetEntity>
</Properties>

用途:存储对另一个实体的引用,用于跨实体调用方法。

# 使用示例
self.targetEntity = otherEntity.base  # 存储 base 的 ENTITYCALL
if self.targetEntity:
    self.targetEntity.someMethod()    # 远程调用

限制:

  • 只能在服务端内部使用,不能同步到客户端
  • 跨进程调用(如 Base → Cell)会产生网络消息

BLOB - 二进制数据

<Properties>
    <thumbnail>
        <Type> BLOB </Type>
        <Flags> BASE </Flags>
    </thumbnail>
</Properties>

用途:图片、压缩数据、加密数据等二进制内容。

Python 对应:bytes

选型指南

传递整数

需要传 int → 用 INT32(默认)
数值可能很大 → 用 INT64
确认是小正整数(0-255)→ 用 UINT8 节省空间

传递字符串

英文/数字 → STRING
多语言/用户输入 → UNICODE

传递结构化数据

固定结构 → 使用 types.xml 定义 FIXED_DICT
动态结构 → PY_DICT(性能较差)
数组类型 → 使用 types.xml 定义 ARRAY

⚠️ .def 文件修改的版本兼容性

核心警告

修改 .def 文件后,新旧服务器混合运行会导致严重问题!

问题根源

KBE 的服务器之间(BaseApp、CellApp、LoginApp 等)没有版本检查机制。

当不同版本的服务器交互时:

新 BaseApp (def v2)   ──RPC──→   老 CellApp (def v1)
                              ↓
                         方法ID (utype) 不匹配
                         参数类型/数量不同
                         序列化/反序列化失败
                         ↓
                         崩溃 / 数据错乱 / 内存越界

具体问题场景

修改类型后果原因
新增属性阅读越界老服务器不知道要读这个字段
删除属性字段错位老服务器继续读,读到了后续字段的数据
修改属性类型反序列化失败int32 变 string,内存布局完全不同
新增方法调用失败utype 冲突或找不到目标方法
修改方法签名参数解析错乱参数数量/类型变了,解码越界
修改 Persistent 标志数据库不一致有的写库,有的不写

客户端 ↔ 服务端

这部分有版本检查:

// loginapp.cpp:1354-1413
void Loginapp::onHello(Channel* pChannel,
                       const string& verInfo,      // 客户端引擎版本
                       const string& scriptVerInfo) // 客户端脚本版本
{
    // 版本不匹配会拒绝连接
    void onVersionNotMatch(Channel* pChannel);
    void onScriptVersionNotMatch(Channel* pChannel);
}

正确的升级流程

升级检查清单

  • [ ] 所有 BaseApp/CellApp 使用相同版本的 .def 文件
  • [ ] 所有服务器上的 Python 脚本已同步
  • [ ] 数据库 schema 已迁移(如涉及 Persistent 属性变更)
  • [ ] 客户端 SDK 已重新生成并更新
  • [ ] 灰度验证:先在测试环境完整验证后再上线生产

❌ 不存在"兼容层"方案

重要澄清:以下方案在 KBEngine 中不可行:

  1. 保留旧方法 + 新方法实现兼容 → 新方法的 utype 在老服务器上找不到
  2. 方法重载实现不同版本参数 → RPC 系统按 utype 查找,不涉及重载

原因:RPC 调用按 utype 查找方法,不是按方法名。新老服务器混合运行时,utype 映射不一致会导致调用失败。

// entity.cpp:922 - 按utype查找方法
MethodDescription* pMethodDescription = pScriptModule->findCellMethodDescription(utype);
if (pMethodDescription == NULL)
{
    ERROR_MSG("can't found method. utype=%d\n", utype);
    return;  // 找不到就报错返回
}

源码位置

类型注册:kbe/src/lib/entitydef/datatypes.cpp:56-79

addDataType("UINT8",   new IntType<uint8>);
addDataType("UINT16",  new IntType<uint16>);
addDataType("UINT32",  new UInt32Type);
addDataType("UINT64",  new UInt64Type);
addDataType("INT8",    new IntType<int8>);
addDataType("INT16",   new IntType<int16>);
addDataType("INT32",   new IntType<int32>);
addDataType("INT64",   new Int64Type);
addDataType("STRING",  new StringType);
addDataType("UNICODE", new UnicodeType);
addDataType("FLOAT",   new FloatType);
addDataType("DOUBLE",  new DoubleType);
addDataType("PYTHON",  new PythonType);
addDataType("PY_DICT", new PyDictType);
addDataType("PY_TUPLE",new PyTupleType);
addDataType("PY_LIST", new PyListType);
addDataType("ENTITYCALL", new EntityCallType);
addDataType("BLOB",    new BlobType);
addDataType("VECTOR2", new Vector2Type);
addDataType("VECTOR3", new Vector3Type);
addDataType("VECTOR4", new Vector4Type);
Prev
API 分类与核对清单
Next
关键词释义