数据配置是游戏开发的基础建设之一,估计没人会反对,而且相信大家也在这方面有自己的看家本领与心得。但是能做与做好是两回事,今天就给大家带来一款自己开发且开源的表格处理工具:go-xlsx-exporter
在介绍工具之前,我先说说我了解到的配置的痛点:
- 是否能快速使用
- 是否支持多种数据类型
- 是否方便程序员后续开发使用
- 是否有错误检查功能
- 是否利于持续集成
- 有自定义的空间等
…
以上是我大致列出的一些问题,正是基于以上思考,我在github上溜达了一圈工具后觉得,有必要自己开发一套满足以上所有需求,并且方便后续扩展的导出工具。
下面会简单为大家介绍此工具:
支持类型
数据类型表达式:
(基础类型|void)[[数组分割符]][[?]自定义类型][<规则ID>]
,其中技基础数据必须包含,实例如下如: string,int,int32,void,string[,],string[,]?UserInfo,string?UserInfo,string[,]?UserInfo<1>等… 一般情况,如果没有特殊需求,基本类型即可满足要求。
基本类型以及相关基础类型的数组类型:
- bool
- int
- uint
- int64
- uint64
- float
- double
- string
- 预定义枚举
支持功能
- 支持枚举类型
- 支持自定义类型
- 支持全局定义
- 支持客户端/服务器导出
- 支持注释
- 支持多语言
- 忽略空行/列
- 分表配置支持
- 支持自定义转换类型
- 支持数据正则检查
支持导出
- proto文件导出(type:proto)
- 序列化为protobuf文件导出(type:proto_bytes)
- golang数据结构代码导出(type:golang)
- csharp数据接口代码导出(type:csharp)
- javascript数据接口代码导出(type:js)
- typescript接口代码导出, 用于配合javascript代码(type:dts)
- typescript数据接口代码导出(type:ts)
- 多语言表使用的文字导出为文本文件,用于生成字符集(type:charset)
- 支持多语言数据导出
读取支持
- cocoscreator+ts数据读取
- unity+csharp数据读取
- golang数据读取
快速使用
有能力的同学可以拉源码进行编译或进行修改,其他同学可以直接拉项目的release版本,即可进行使用,目前release编译了mac与windows版本。
1. 按规定格式定义表头
表格分为两种类型,一种为预定义表,一种为数据表(语言表为特殊数据表),一般没有特殊需求可以只要数据表。
预定义表
此表用于定义数据表可使用的枚举类型,以及结构体及全局配置(可不使用后两种类型),表结构如下:
- 枚举类型
enum, 同一枚举类型名一样,类型为空,值为枚举索引值
- 结构体类型
struct, 此项预留
- 常量类型
const, 用于定义游戏中的一些常量值,常量数据也会导出为二进制文件,与数据文件不同的是,导出的数据不是列表数据,仅为一个消息体(类)的数据
数据表:此类型用于定义数据表,前四行(忽略前后端导出配置时为三行)用于字段描述,支持使用定义表中定义的枚举类型,导出的二进制数据类型为“类型名_ARRAY”,并在此类型中定义了Items的数组作为此表数据集合。
表格式如下图,其中第三行为前后端导出设置,可以在配置文件中忽略此行:
- 导出数据
将项目中的表格数据放入data目录下,并修改配置文件conf.yaml,配置文件是yaml格式,其中参数如下:
package: "GameData" # 导出代码的包名(命名空间)
pb_bytes_file_ext: ".bin" # 二进制数据文件后缀名,unity中请使用.bytes, cocoscreator中请使用.bin
comment_symbol: "#" # 定义表格中的注释符
export_type: 1 # 全局导出类型设置,1-导出前后端代码/数据,2-仅导出客户端代码/数据,3-仅导出服务端代码/数据,4-忽略(表格式无需添加前后端导出配置行)
array_split_char: "|" #默认数组分割符号
pause_on_end: false # 运行完毕后是否暂停
strict_mode: true # 是否严格模式,如:int配置为空时,严格模式将会报错,非严格模式默认为0
rules: #数据规则,可在字段类型后加入规则id,在数据导出时进行规则检测,严格模式会中断输出,否则只进行日志提示
-
id: 1 # 规则id,在类型表达式中使用
rule: '\w+?\.png' # 规则正则表达式
desc: '图片' # 描述
disable: false # 是否关闭此规则
-
id: 2
rule: '\d+'
desc: '数字'
disable: false
sheets: # 所有表格数据
-
id: 1 # 表格编号,用于生成时过滤
type: "define" # 表格数据类型,包含: define/table/language
xls_file: 'data/define.xlsx' # xlsx文件路径
sheet: 'define' # xlsx中的表格名
-
id: 2
type: "table"
xls_file: 'data/model.xlsx'
sheet: 'user'
type_name: 'User'
-
id: 2
type: "table"
xls_file: 'data/i18n.xlsx'
sheet: 'location1'
is_lang: true
exports: # 导出任务集合
-
id: 1 # 编号,用于任务过滤
type: "proto" # 任务类型,包含:proto/proto_bytes/golang/csharp或后续支持类型
path: "./gen/code/all_proto.proto" # 生成文件名,或者导出路径(针对多文件输出)
sheets: "" # 导出表id集合,默认为导出所有表,逗号分割表示数组,如:1,2,3,横杠分割表示范围,如:1-7,可混用如:1,2-4,6-7
export_type: 2 # 可单独设置导出类型,覆盖全局设置(忽略导出除外,只认全局配置)
-
id: 2
type: "golang"
path: "./gen/code/data_model.pb.go"
sheets: "1,3-7"
package: "game_data" # 可单独设置包名,覆盖全局设置,但是会被参数设置的包名覆盖
-
id: 3
type: "csharp"
path: "./gen/code/DataModel.cs"
sheets: ""
package: "Cfg"
-
id: 4
type: "proto_bytes"
path: "./gen/data/"
-
id: 5
type: "charset"
path: "./gen/data/lang.txt"
-
id: 6
type: "js,dts" #部分任务可同时进行,避免多次解析表格,多类型导出按","分割,且输出路径必须与类型数量相同
path: "./gen/code/data_mode.js,./gen/code/data_mode.d.ts"
imports: #当使用了自定义类型转换,可在生成代码中加入引用,防止生成代码错误
- "import UserData from './userdata'"
- "import XXX from './xxx'"
-
id: 7
type: "ts"
path: "./gen/code/data_mode.ts"
可以看到,我们只需要简单的配置表 sheets
格然后添加导出任务 exports
,即可运行程序对数据和协议进行导出。
使用数据
目前在cocos中,我使用的是protobufjs与我工具导出的ts文件与bin数据。
使用方法如下:
下载项目中的typescript数据读取文件(DataAccess.ts,[I18N.ts,Lang.ts]语言读取可选),与导出的.bin数据文件和.ts文件放入项目中即可。
- 资源加载配置
DataAccess.dataDir = "data/";
DataAccess.loader = (datafile) => {
let source = ab.get<BufferAsset>(datafile, BufferAsset);
if (source) {
return new Uint8Array(source.buffer());
}
return null;
};
- 加载表格
let userTable = DataAccess.getDataTable<User>(GameData.User_ARRAY);
- 读取数据
userTable.items[index];
userTable.getItem(id);
更多高级功能
- 自定义转换类型
有的项目中有较为复杂字段的配置,需要将字符串解析为相关数据类型,此时就可以用自定义转换类型,使用方法为在数据类型后添加"?类型",导出的代码中就会生成如下接口:
getUP_RATIO(): Ratio {
return this.getConvertData("UP_RATIO", this.UP_RATIO);
}
在这之前,你只需要将DataConverter.convertHandler注册为您的转换函数即可,并且之前转换的数据会进行缓存来提升效率。
- 正则校验
此功能可有效在导出数据时,校验表格数据,减少程序因数据而出现的bug。
使用方法是在配置文件中添加相关的规则,在相应列类型后添加<规则ID>,即可生效。 - 分表功能
当中大型游戏的配置表数据过大或者多人修改同一张表时,此时就可以将一张表分为多个表进行修改,执行在配置文件中配置为同一数据类型即可。 - 导出自定义代码
如果有同学会使用golang的模板文件,可以修改templete目录下的对应的模板文件,从而生成自己风格的代码文件。
更多功能期待大家亲亲自去体验与发现,希望这个工具能帮到大家,为大家开发出更好地游戏尽一份力,希望大家远离996,还能最快最好的做出好游戏。
谢谢大家!!