结构定义
CFG文件结构定义系统旨在表达复杂的数据结构和关系网络。系统通过以下核心组件构建:
基础类型(int, float, str, bool, long, text) ↓枚举(enum)定义编译时常量 ↓结构体(struct)聚合基础类型和枚举,支持嵌套 ↓容器类型(list, map)表达集合数据 ↓接口(interface)实现多态行为 ↓数据表(table)存储具体数据,通过主键、唯一键、外键建立关联最终形成一个相互关联的数据网络,支持复杂游戏逻辑的配置。
枚举(enum)
Section titled “枚举(enum)”枚举用于在 schema 文件中定义编译时常量,语法格式:enum 名称 { 值; 值; }
enum ArgCaptureMode { Snapshot; // 快照模式 Dynamic; // 动态模式}等价于:
// 在.cfg中配置tabletable ArgCaptureMode[name] (enum='name') { name:str; comment:str;}
// 在excel中配置数据// Snapshot, 快照模式// Dynamic, 动态模式使用:
captureMode:ArgCaptureMode;// 等价于: captureMode:str ->ArgCaptureMode// 也支持list<ArgCaptureMode>和map<str, ArgCaptureMode>等容器类型| 特性 | Schema Enum | Table Enum |
|---|---|---|
| 数据位置 | .cfg 文件中配置 | Excel 中配置 |
| 成员字段 | 固定 name + comment | 可定制更多字段 |
结构体(struct)
Section titled “结构体(struct)”结构体用于定义复合数据类型,是构建复杂数据结构的基础。
- 定义格式:
struct 结构体名称 { 字段定义 } - 字段定义:
字段名:字段类型; // 注释 - 字段类型:
- 基础类型:
bool,int,float,long,str,text - 聚合类型:
struct,interface - 容器类型:
list<类型>,map<键类型,值类型>
- 基础类型:
外键用于建立表之间的关联关系,支持多种引用方式。
- 单向外键(->):指向表的主键或唯一键
- 格式:
字段类型 ->表名(指向主键) - 格式:
字段类型 ->表名[唯一键](指向唯一键)
- 格式:
- 多向外键(=>):指向表的任意字段,生成反向引用列表
- 格式:
字段类型 =>表名[字段名]
- 格式:
- 独立外键:
->外键名:[字段列表] ->|=> 目标表
详细说明请参考:表键、枚举与数据关联
// 数值范围结构// 用于定义最小值和最大值struct Range { rmin:int; // 最小值 rmax:int; // 最大值}
// 奖励物品结构// 包含掉落概率、物品ID列表和数量范围struct RewardItem { chance:int; // 掉落概率 itemids:list<int> ->item.item (fix=2); // 掉落物品列表,每个物品指向item表 range:Range; // 数量范围(嵌套结构)}
// 时间结构// 使用冒号分隔的小时、分钟、秒配置struct Time (sep=':'){ hour:int; // 小时 minute:int; // 分钟 second:int; // 秒}特性说明:
Range:基础结构体,定义数值范围RewardItem:复杂结构体,包含列表外键和嵌套结构Time:使用(sep=':')属性,支持Excel中以冒号分隔的时间格式
接口(interface)
Section titled “接口(interface)”接口用于定义多态行为,支持多种实现类,常用于游戏逻辑的条件判断和公式计算。
-
enumRef(可选):指向枚举表,该表包含接口所有实现类的信息
- 作用:让策划在Excel中通过下拉菜单选择实现类,无需查看CFG文件
- 要求:枚举表必须包含实现类名称,可包含ID和其他信息
-
defaultImpl(可选):指定默认实现类
- 作用:Excel中可不显式配置接口字段,系统自动使用默认实现
// 任务完成条件接口// 定义多种任务完成条件的实现方式,通过枚举表completeconditiontype选择interface completecondition (enumRef='completeconditiontype') { // 击杀怪物条件 struct KillMonster { monsterid:int ->npc.monster; // 怪物ID,外键指向npc表 count:int; // 需要击杀的数量 }
// 与NPC对话条件 struct TalkNpc { npcid:int ->npc.npcid; // NPC ID,外键指向npc表 }
// 多条件与逻辑 struct ConditionAnd { cond1:task.completecondition; // 条件1,递归引用 cond2:task.completecondition; // 条件2,递归引用 }
// 收集物品条件 struct CollectItem { itemid:int ->item.item; // 物品ID,外键指向item表 count:int; // 需要收集的数量 }}
// 任务经验公式接口// 定义多种经验计算方式,默认使用固定值interface taskexp (enumRef='taskexptype', defaultImpl='ConstValue') { // 基于玩家等级的经验公式 struct ByLevel { levelcoef:float; // 等级系数 value:int; // 基础值 }
// 基于服务器开服天数的经验公式 struct ByServerUpDay { updaycoef1:float; // 天数系数1 updaycoef2:float; // 天数系数2 value:int; // 基础值 }
// 固定经验值 struct ConstValue { value:int; // 固定经验值 }}设计优势:
- 可扩展性:新增任务完成条件只需添加新的struct实现
- 易用性:策划通过下拉菜单选择,无需了解技术细节
- 灵活性:支持递归组合,可构建复杂条件树
数据表(table)
Section titled “数据表(table)”数据表是实际存储配置数据的容器,支持索引、约束和多态字段。
- 主键:表名后的
[]内定义主键字段 - 表属性:主键后的
()内定义表级属性 - 唯一键:
{}内以[字段名]开头的行定义唯一键 - 字段定义:与struct语法相同
详细主键、唯一键说明请参考:主键、枚举、外键
-
enum:指定枚举字段,该表作为枚举表使用
- 作用:Excel中该列由程序员填写,每行都必须有值
- 用途:配合interface的enumRef属性
-
entry:指定入口字段,生成静态访问代码
- 作用:Excel中该列由程序员填写,只有特定行需要值
- 用途:程序代码中通过静态成员直接访问特定行
详细说明请参考:表键、枚举与数据关联
// 任务完成条件类型枚举表// 为completecondition接口提供下拉选项table completeconditiontype[id] (enum='name') { id:int; // 任务完成条件类型ID name:str; // 程序用名称(必须包含completecondition接口的所有实现类名)}
// 任务经验公式类型枚举表// 为taskexp接口提供下拉选项table taskexptype[id] (enum='name') { id:int; // 经验公式类型ID name:str; // 程序用名称(必须包含taskexp接口的所有实现类名)}
// 任务配置表// 存储所有任务数据和完成条件table task[taskid] (entry='entry') { [nexttask]; // 定义唯一键 taskid:int ->task.taskextraexp (nullable); // 任务ID,外键(可空) entry:str; // 入口标识,程序代码直接访问 text:text; // 国际化文本 nexttask:int ->task (nullable); // 下一个任务ID,外键(可空) completecondition:task.completecondition; // 任务完成条件(多态接口) exp:taskexp (mustFill); // 经验奖励公式(多态接口,必须填写) rewardItems:list<RewardItem> (block=1); // 物品奖励列表 time:Time; // 时间配置}表设计说明:
- completeconditiontype:枚举表,定义任务完成条件类型
- taskexptype:枚举表,定义经验公式类型
- task:主任务表,包含复杂的数据结构和关联关系
- 唯一键:
[nexttask]会生成GetByNextTask访问方法 - 多态字段:
completecondition和exp字段支持多种实现
字段可以配置多种属性来控制数据验证和生成行为。
| 属性 | 用途 | 适用类型 | 示例 |
|---|---|---|---|
nullable | 允许字段为空 | 所有类型 | field:int (nullable) |
mustFill | 必须填写,不能为空 | 所有类型 | field:str (mustFill) |
fix=N | 固定长度,占用N倍元素类型的列数 | list, map | items:list<int> (fix=3) |
block=N | 块状映射,横向固定N个元素,纵向可扩展 | list, map | rewards:list<Reward> (block=1) |
pack | 压缩到1列,用逗号或分号分隔 | struct, list, map | pos:Position (pack) |
sep='分隔符' | 自定义分隔符,压缩到1列 | struct, list | time:Time (sep=':') |
详细映射规则请参考:映射到表格
| 构造 | 语法 | 用途 |
|---|---|---|
| 枚举 | enum 名称 { 值; 值; } | 定义编译时常量枚举 |
| 结构体 | struct 名称 { 字段:类型; } | 定义复合数据类型 |
| 接口 | interface 名称 { struct 实现类 { ... } } | 定义多态行为 |
| 数据表 | table 表名[主键] { [唯一键]; 字段:类型; } | 存储配置数据 |
| 外键 | 字段:类型 ->目标表 | 建立表间关联 |
| 多向外键 | 字段:类型 =>目标表[字段] | 建立反向引用 |
| 属性 | 位置 | 用途 |
|---|---|---|
enumRef='表名' | interface | 指定枚举表 |
defaultImpl='类名' | interface | 指定默认实现 |
enum='字段名' | table | 指定枚举字段 |
entry='字段名' | table | 指定入口字段 |
nullable | 字段 | 允许为空 |
mustFill | 字段 | 必须填写 |
fix=N | 映射… | … |
block=N | 映射… | … |
pack | 映射… | … |
sep='分隔符' | 映射… | … |
| 类型分类 | 具体类型 | 描述 |
|---|---|---|
| 基础类型 | bool, int, float, long, str, text | 基本数据类型 |
| 枚举类型 | 枚举名称 | 编译时常量枚举 |
| 容器类型 | list<T>, map<K,V> | 集合数据类型 |
| 聚合类型 | struct, interface | 复合数据类型 |
| 引用 | ->表名,->表名[唯一键], =>表名[字段] | 表间关联 |
- 文件目录结构:详见 文件目录结构
- 表键与关联:详见 表键、枚举与数据关联
- 表格映射:详见 映射到表格