《 开源多端快速导表工具 | 社区征文 》

数据配置是游戏开发的基础建设之一,估计没人会反对,而且相信大家也在这方面有自己的看家本领与心得。但是能做与做好是两回事,今天就给大家带来一款自己开发且开源的表格处理工具:go-xlsx-exporter

在介绍工具之前,我先说说我了解到的配置的痛点:

  1. 是否能快速使用
  2. 是否支持多种数据类型
  3. 是否方便程序员后续开发使用
  4. 是否有错误检查功能
  5. 是否利于持续集成
  6. 有自定义的空间等

以上是我大致列出的一些问题,正是基于以上思考,我在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. 按规定格式定义表头

表格分为两种类型,一种为预定义表,一种为数据表(语言表为特殊数据表),一般没有特殊需求可以只要数据表。

预定义表
此表用于定义数据表可使用的枚举类型,以及结构体及全局配置(可不使用后两种类型),表结构如下:

image

  • 枚举类型

enum, 同一枚举类型名一样,类型为空,值为枚举索引值

image

  • 结构体类型

struct, 此项预留

image

  • 常量类型

const, 用于定义游戏中的一些常量值,常量数据也会导出为二进制文件,与数据文件不同的是,导出的数据不是列表数据,仅为一个消息体(类)的数据

数据表:此类型用于定义数据表,前四行(忽略前后端导出配置时为三行)用于字段描述,支持使用定义表中定义的枚举类型,导出的二进制数据类型为“类型名_ARRAY”,并在此类型中定义了Items的数组作为此表数据集合。
表格式如下图,其中第三行为前后端导出设置,可以在配置文件中忽略此行:
image

  1. 导出数据
    将项目中的表格数据放入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文件放入项目中即可。

  1. 资源加载配置
 DataAccess.dataDir = "data/";
  DataAccess.loader = (datafile) => {
       let source = ab.get<BufferAsset>(datafile, BufferAsset);
       if (source) {
            return new Uint8Array(source.buffer());
       }
       return null;
   };
  1. 加载表格
let userTable = DataAccess.getDataTable<User>(GameData.User_ARRAY);
  1. 读取数据
userTable.items[index];
userTable.getItem(id);

更多高级功能

  1. 自定义转换类型

有的项目中有较为复杂字段的配置,需要将字符串解析为相关数据类型,此时就可以用自定义转换类型,使用方法为在数据类型后添加"?类型",导出的代码中就会生成如下接口:

 getUP_RATIO(): Ratio {
      return this.getConvertData("UP_RATIO", this.UP_RATIO);
 }

在这之前,你只需要将DataConverter.convertHandler注册为您的转换函数即可,并且之前转换的数据会进行缓存来提升效率。

  1. 正则校验
    此功能可有效在导出数据时,校验表格数据,减少程序因数据而出现的bug。
    使用方法是在配置文件中添加相关的规则,在相应列类型后添加<规则ID>,即可生效。
  2. 分表功能
    当中大型游戏的配置表数据过大或者多人修改同一张表时,此时就可以将一张表分为多个表进行修改,执行在配置文件中配置为同一数据类型即可。
  3. 导出自定义代码
    如果有同学会使用golang的模板文件,可以修改templete目录下的对应的模板文件,从而生成自己风格的代码文件。

更多功能期待大家亲亲自去体验与发现,希望这个工具能帮到大家,为大家开发出更好地游戏尽一份力,希望大家远离996,还能最快最好的做出好游戏。

谢谢大家!!

11赞

好东西!!

新增消息协议配置与导出功能

不知道怎么用

不能导出lua格式。

支持倒是简单。我只是没想好意义大不。。我主要是用unity和cocos,如果是unity+lua,现在也是支持的 :grinning:cocos直接可以用ts+bin

下载后直接运行exe就能看测试了。其他可以看文档

你弄的是源码哦。那个是golang的事情了

“希望大家远离996,还能最快最好的做出好游戏。”
说出你的故事

exe 执行就闪退了,目前不知道怎么玩

通过命令行,进入exe目录,然后命令行执行。而且可能不是闪退。是执行完毕了

我没有。不然也没闲心做开源啦

可以用了,但是导出ts||js失败了
文件夹空的image
image

demo不应该失败才对。有在命令行运行,然后看看日志。会有相关提示的。还有最近我会发一个新版本上去,修改了导出的一些bug

额。你去下一个新版本吧。你这个版本有点儿奇怪。像是老版本的,下1.2.1试试

新版本我编译成exe,可以导出脚本文件了

怎么用呢?

加了一个

看文档哈。这个只是预定义表。定义枚举之类的。需要配合项目里的reader下面的typescript文件使用,对了typescript的文档我还没写。
用DataAccess获取相关表就行了。对了需要喂一下读取表资源的那个函数


initial调用下,然后用getDataTable拿表

需要更新下DataAccess.ts改了些东西

感觉有点费劲,程序会用了,但是策划会用吗,你确定用这个策划不会打你吗