跳转到内容

元数据

元数据配置是配表系统的重要组成部分,通过在表定义中添加特定的元数据标记,可以控制数据的存储格式、编辑器行为、国际化工具支持等高级功能。

在表的元数据中配置 columnMode,主要用于简化模块参数表的配置过程。

  • 模块化参数配置
  • 动态列定义
  • 批量字段管理

在表的元数据中配置 extraSplit,用于控制生成Lua文件时是否将数据分割为多个文件。

  • 默认值: 0(不分割)
  • 分割规则: 当配置为N时,数据项每N行分割为一个文件

假设数据表有250行数据,配置 extraSplit=100,则生成的文件分布如下:

  • 原文件:100行
  • 文件1:100行
  • 文件2:50行
  • 问题背景: Lua单个文件不能超过65526个常量
  • 解决方案: 通过文件分割避免编译错误
  • 影响文件: assets.lua(资源系统自动生成的文件)
  • 优势: 减少热更新时的下载文件大小
  • 示例:
    • 物品表有10000个条目
    • 热更新时通常只修改少量数据
    • 分割为5个文件后,可能只需更新其中一个文件
    • 显著降低网络传输量

在表上设置 json 元数据,表示该表的数据将以独立的JSON文件形式存储。

  • 支持使用 cfgeditor 编辑器进行可视化编辑
  • 每个数据项对应一个独立的JSON文件
table effect[id] (json) {
id:int;
text:str;
logic:EffectLogic;
}

在表上设置 title 元数据,指定用于显示标题的字段名称。

cfgeditor 编辑器中显示ID时,自动附带指定的标题字段内容。

table effectclass[name] (enum='name', title='text') {
name:str;
text:str;
}

在表上设置 description 元数据,指定用于显示描述的字段名称。

  • 支持多字段组合,使用逗号分隔
  • 格式:field1,field2,field3

cfgeditor 编辑器的简略视图中展示指定的描述字段内容。


在外键字段上设置 refTitle 元数据,指定用于显示外键引用的字段名称。

  • 主要在字段上设置(因为字段包含外键引用)
  • 指定目标结构的字段名称

cfgeditor 编辑器中展示链接时,链接线显示为指定字段对应的值。

  • 默认显示为 refXxx 格式

在表上设置 lang 元数据,用于国际化方案2。

生成Excel文件时:

  • 第一列:主键
  • 第二列:额外添加指定列
  • 目的:辅助翻译人员进行本地化工作

在表上设置 (root) 元数据标记,表示该表中的所有记录类似 GC 的根节点,天然被视为”被引用”。

标记为 (root) 的表会被未引用记录检测(-gen verify)跳过,适用于比如以下场景:

  • 等级表:以等级当 key 的表,程序通过玩家等级动态查找
  • 地块表:以地块坐标当 key 的表,程序通过坐标位置动态访问
  • 随机表:用来随机选择记录的表,程序从中随机抽取
table LevelReward[level] (root) {
level: int;
reward: int ->Item;
}

CFG文件语法定义(ANTLR4格式)

以下为CFG文件的语法定义,采用ANTLR4格式,熟悉BNF语法的开发者可以参考:

Cfg.g4
grammar Cfg;
// ======================================================
// Parser Rules (语法规则) - 自顶向下组织
// ======================================================
// 1. Root Rule
schema
: 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 使用,不要加 -> skip
COMMENT
: '//' ~[\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+
;
  • 现在的默认值number为0,str为空字符串,bool是false,容器为空
要不要在metadata里加入defaultValue配置?
不加! 定死的默认值更容易理解。