元数据
元数据配置是配表系统的重要组成部分,通过在表定义中添加特定的元数据标记,可以控制数据的存储格式、编辑器行为、国际化工具支持等高级功能。
columnMode - 列模式配置
Section titled “columnMode - 列模式配置”在表的元数据中配置 columnMode,主要用于简化模块参数表的配置过程。
- 模块化参数配置
- 动态列定义
- 批量字段管理
extraSplit - 文件分割配置
Section titled “extraSplit - 文件分割配置”在表的元数据中配置 extraSplit,用于控制生成Lua文件时是否将数据分割为多个文件。
- 默认值: 0(不分割)
- 分割规则: 当配置为N时,数据项每N行分割为一个文件
假设数据表有250行数据,配置 extraSplit=100,则生成的文件分布如下:
- 原文件:100行
- 文件1:100行
- 文件2:50行
1. 解决技术限制
Section titled “1. 解决技术限制”- 问题背景: Lua单个文件不能超过65526个常量
- 解决方案: 通过文件分割避免编译错误
- 影响文件:
assets.lua(资源系统自动生成的文件)
2. 优化热更新
Section titled “2. 优化热更新”- 优势: 减少热更新时的下载文件大小
- 示例:
- 物品表有10000个条目
- 热更新时通常只修改少量数据
- 分割为5个文件后,可能只需更新其中一个文件
- 显著降低网络传输量
json - JSON存储格式
Section titled “json - JSON存储格式”在表上设置 json 元数据,表示该表的数据将以独立的JSON文件形式存储。
- 支持使用
cfgeditor编辑器进行可视化编辑 - 每个数据项对应一个独立的JSON文件
table effect[id] (json) { id:int; text:str; logic:EffectLogic;}title - 标题字段配置
Section titled “title - 标题字段配置”在表上设置 title 元数据,指定用于显示标题的字段名称。
在 cfgeditor 编辑器中显示ID时,自动附带指定的标题字段内容。
table effectclass[name] (enum='name', title='text') { name:str; text:str;}description - 描述字段配置
Section titled “description - 描述字段配置”在表上设置 description 元数据,指定用于显示描述的字段名称。
- 支持多字段组合,使用逗号分隔
- 格式:
field1,field2,field3
在 cfgeditor 编辑器的简略视图中展示指定的描述字段内容。
refTitle - 外键标题配置
Section titled “refTitle - 外键标题配置”在外键字段上设置 refTitle 元数据,指定用于显示外键引用的字段名称。
- 主要在字段上设置(因为字段包含外键引用)
- 指定目标结构的字段名称
在 cfgeditor 编辑器中展示链接时,链接线显示为指定字段对应的值。
- 默认显示为
refXxx格式
lang - 国际化支持
Section titled “lang - 国际化支持”在表上设置 lang 元数据,用于国际化方案2。
生成Excel文件时:
- 第一列:主键
- 第二列:额外添加指定列
- 目的:辅助翻译人员进行本地化工作
root - 根表标记
Section titled “root - 根表标记”在表上设置 (root) 元数据标记,表示该表中的所有记录类似 GC 的根节点,天然被视为”被引用”。
标记为 (root) 的表会被未引用记录检测(-gen verify)跳过,适用于比如以下场景:
- 等级表:以等级当 key 的表,程序通过玩家等级动态查找
- 地块表:以地块坐标当 key 的表,程序通过坐标位置动态访问
- 随机表:用来随机选择记录的表,程序从中随机抽取
table LevelReward[level] (root) { level: int; reward: int ->Item;}- 配置验证完整说明 - 了解未引用记录检测和验证流程
CFG文件格式规范
Section titled “CFG文件格式规范”CFG文件语法定义(ANTLR4格式)
以下为CFG文件的语法定义,采用ANTLR4格式,熟悉BNF语法的开发者可以参考:
grammar Cfg;
// ======================================================// Parser Rules (语法规则) - 自顶向下组织// ======================================================
// 1. Root Ruleschema : schema_ele* suffix_comment* EOF ;
schema_ele : struct_decl | interface_decl | table_decl | enum_decl ;
// 2. High-level Structures (Struct, Interface, Table)struct_decl : leading_comment* STRUCT ns_ident metadata LC_COMMENT (field_decl | foreign_decl)* suffix_comment* RC ;
interface_decl : leading_comment* INTERFACE ns_ident metadata LC_COMMENT struct_decl+ suffix_comment* RC ;
table_decl : leading_comment* TABLE ns_ident key metadata LC_COMMENT (field_decl | foreign_decl | key_decl)+ suffix_comment* RC ;
enum_decl : leading_comment* ENUM ns_ident metadata LC_COMMENT enum_value* suffix_comment* RC ;
// 3. Members & Fields (字段与定义)field_decl : leading_comment* identifier COLON type_ ref? metadata SEMI_COMMENT ;
foreign_decl : leading_comment* REF identifier COLON key ref metadata SEMI_COMMENT ;
key_decl : leading_comment* key SEMI_COMMENT ;
enum_value : leading_comment* identifier SEMI_COMMENT ;
// 4. Types System (类型系统)type_ : TLIST '<' type_ele '>' # TypeList | TMAP '<' type_ele ',' type_ele '>' # TypeMap | type_ele # TypeBasic ;
type_ele : TBASE | ns_ident ;
// 5. References & Keys (引用与键)ref : (REF | LISTREF) ns_ident key? ;
key : '[' identifier (',' identifier)* ']' ;
// 6. Metadata & Attributes (元数据与属性)metadata : ( LP ident_with_opt_single_value ( COMMA ident_with_opt_single_value )* RP )? ;
ident_with_opt_single_value : identifier (EQ single_value)? | minus_ident ;
minus_ident : MINUS identifier ;
single_value : INTEGER_CONSTANT | HEX_INTEGER_CONSTANT | FLOAT_CONSTANT | STRING_CONSTANT | BOOL_CONSTANT ;
// 7. Common Utilities (通用工具)ns_ident : identifier ( DOT identifier )* ;
identifier : IDENT | STRUCT | INTERFACE | TABLE | ENUM | TLIST | TMAP | TBASE ;
// 命名标签规则,用于区分声明前注释和后缀注释leading_comment : COMMENT ;
suffix_comment : COMMENT ;
// ======================================================// Lexer Rules (词法规则) - 优先级非常重要// ======================================================
// 1. Keywords (关键字) - 必须放在 IDENT 之前STRUCT : 'struct';INTERFACE : 'interface';TABLE : 'table';ENUM : 'enum';TLIST : 'list';TMAP : 'map';
// 基础类型关键字TBASE : 'bool' | 'int' | 'long' | 'float' | 'str' | 'text' ;
// 2. Operators & Symbols (运算符与符号)REF : '->';LISTREF : '=>';EQ : '=';LP : '(';RP : ')';LB : '[';RB : ']';RC : '}';DOT : '.';COMMA : ',';COLON : ':';PLUS : '+';MINUS : '-';
// { 和 ; 及其可选的同行注释(必须与符号在同一行)LC_COMMENT : '{' [ \t]* ('//' ~[\r\n]*)? ;SEMI_COMMENT: ';' [ \t]* ('//' ~[\r\n]*)? ;
// 3. Boolean Literals (布尔字面量)BOOL_CONSTANT : 'true' | 'false' ;
// 4. Numeric Literals (数字字面量)// 将 Fragment 放在使用它们的规则附近或文件底部FLOAT_CONSTANT : (PLUS|MINUS)? FLOATLIT ;
HEX_INTEGER_CONSTANT : [-+]? '0' [xX] HEXADECIMAL_DIGIT+ ;
INTEGER_CONSTANT : [-+]? DECIMAL_DIGIT+ ;
// 5. String Literals (字符串字面量)STRING_CONSTANT : '\'' SCHAR_SEQUENCE? '\'' ;
// 6. Identifiers (标识符) - 放在关键字之后,避免关键字被识别为变量名IDENT : [a-zA-Z_] [a-zA-Z0-9_]* ;
// 7. Comments & Whitespace (注释与空白)// 如果你需要把注释保留在语法树中给 Parser 使用,不要加 -> skipCOMMENT : '//' ~[\r\n]* ;
WS : [ \t\r\n] -> skip ;
// ======================================================// Fragments (词法片段) - 辅助 Lexer 规则// ======================================================
fragment FLOATLIT : ( DECIMALS DOT DECIMALS? EXPONENT? | DECIMALS EXPONENT | DOT DECIMALS EXPONENT? ) ;
fragment DECIMALS : DECIMAL_DIGIT+ ;
fragment EXPONENT : ('e' | 'E') (PLUS|MINUS)? DECIMALS ;
fragment DECIMAL_DIGIT : [0-9] ;
fragment HEXADECIMAL_DIGIT : [0-9a-fA-F] ;
fragment SCHAR_SEQUENCE : SCHAR+ ;
fragment SCHAR : ~['\\\r\n] | ESCAPE_SEQUENCE ;
fragment ESCAPE_SEQUENCE : SIMPLE_ESCAPE_SEQUENCE | HEXADECIMAL_ESCAPE_SEQUENCE | UNICODE_ESCAPE_SEQUENCE ;
fragment SIMPLE_ESCAPE_SEQUENCE : '\\' ['"?bfnrtv\\/] ;
fragment HEXADECIMAL_ESCAPE_SEQUENCE : '\\x' HEXADECIMAL_DIGIT+ ;
fragment UNICODE_ESCAPE_SEQUENCE : '\\u' HEXADECIMAL_DIGIT+ ;不要default设置
Section titled “不要default设置”- 现在的默认值number为0,str为空字符串,bool是false,容器为空
要不要在metadata里加入defaultValue配置?不加! 定死的默认值更容易理解。