【更新】更新文档

main
walon 2021-12-03 15:30:54 +08:00
parent 8b0f607f4a
commit f740685830
19 changed files with 2 additions and 1952 deletions

View File

@ -30,10 +30,10 @@ luban相较于常规的excel导表工具有以下核心优势
- 通用型生成工具。也可以用于生成协议、数据库之类的代码,甚至可以用作对象缓存服务。
## 文档
- [快速上手](docs/start_up.md)
- [快速上手](https://github.com/focus-creative-games/luban/wiki/start_up)
- [**wiki**](https://github.com/focus-creative-games/luban/wiki) 比较完善有使用疑问请先查看此wiki。
- **示例项目** ([github](https://github.com/focus-creative-games/luban_examples)) ([gitee](https://gitee.com/focus-creative-games/luban_examples))
- [版本变更记录](https://github.com/focus-creative-games/luban/wiki/%E7%89%88%E6%9C%AC%E5%8F%98%E6%9B%B4%E8%AE%B0%E5%BD%95)
- [版本变更记录](https://github.com/focus-creative-games/luban/wiki/changelog)
- 支持与联系
- QQ群: 692890842 Luban开发交流群。有使用方面的疑问请及时加QQ群询问随时有人帮助解决。

View File

@ -1,126 +0,0 @@
* start up
- [下载 dotnet 5](https://dotnet.microsoft.com/download/dotnet/5.0)
- [下载 luban.client&luban.server](https://github.com/focus-creative-games/luban_examples/tree/main/Tools)
- 启动 luban.server
- 创建游戏配置
- root.xml
- 新增一个表定义
- 新增一个excel文件
- 生成
- c# dotnet core
- gen.client 命令行
- c# unity
- c# unity + ILRuntime
- lua unity xlua
- lua unity tolua
- 其他lua
- java
- go
- cpp
- typescript
- python 2.7及3.0
* 进阶
- 游戏配置
- excel 篇
- 标题头定义
- 定义和配置更多基础类型
- 定义枚举
- 定义bean
- 数据格式
- 指定某个或者多个sheet或者文件
- list 或者其他类型
- group 分组导出
- tag
- sep
- multi_rows
- 多级标题头
- 单例表
- 行表与列表
- 可空变量
- datetime
- convert
- 多态bean
- json 篇
- lua
- xml
- 一个同时包含 excel 、 json 配置的项目
- 数据校验
- ref
- path
- 导出格式
- bin 格式
- lua 格式
- 本地化
* gen.client & gen.server 工作模型
![](docs/images/Client_Server.png)
* 定义 + 数据的 抽象模型
* 定义
* 根定义文件
* group
* service
* topmodule
* import
* 子模块定义
* 类型系统
- 基础类型
- 可空类型
- 枚举
- const
- bean
- field
- convert 常量替换
- 多态
* table
* module
* 源数据格式
- excel
- json
- lua
- xml
* 导出数据格式
- bin
- json
- lua
- emmylua anntations
* input 多种数据文件来源
* group 数据分组
* tag
* 资源列表导出
* validator 数据检验
* 本地化
* editor 相关。导出符合luban数据约束的文件。
* ide支持
- emmylua anntations
- luban.client 命令行介绍
- luban.client 命令行参数
- job cfg 命令行参数
* 各个语言和引擎及平台下的项目搭建
- c# + dotnet core
- c# + unity
- c# + unity + ILRuntime
- 其他 c# 平台
- lua + unity + tolua
- lua + unity + xlua
- lua + unity + slua
- lua + unreal + unlua
- lua + cocos2dx
- 其他使用 lua 的 平台
- c++ + unreal
- c++ + 其他平台
- go
- java
- python 2.7
- python 3.0
- typescript + 微信小游戏
- typescript + 其他平台
* luban 开发
- git clone 项目
- luban 构建与发布
- 普通构建
- docker
- 代码结构介绍
- 自定义 job

View File

@ -1,409 +0,0 @@
[//]: # "Author: bug"
[//]: # "Date: 2020-11-01 15:40:11"
## bool 类型
用 true 或 false 表示 bool 值,只需要小写后是这两个值即可,比如 true,True,True 都是合法的值。excel 会自动将输入的值大写化。
|##| id | x|
|-|-|-|
|##type|int| bool|
|| 1| true|
||2| false |
## float 类型
|##| id | x|
|-|-|-|
|##type|int| float|
|| 1| 1.2|
||2| 4.895 |
## byte,short,int,long,string
与 float 相似,不再赘述
## string 类型
填法与 float相似但又特殊性。当string类型数据出现在**连续单元格**比如多列bean占了多个单元格或者用**sep分割**的数据中时,由于工具无法区别空白到底算空白字符串还是应该跳过,所以在连续多字段模式下,强制用""来表示空白字符串。
下面示例中s1是string单独占一个列可以用空白单元格表示空白字符串。 cs1和cs2要么是连续单元格模式要么是sep分割产生的连续数据模式表达空白字符串必须用""。
可能会有疑问,如何恰好想表达 ""是怎么办呢? 如果真遇到这种需求,再寻找解决方案吧。
|##| id | x|
|-|-|-|
|##type|int| string|
|| 1| aaabbb|
||2| |
||3| ""|
## text 类型
该类型数据包含两个字段, key和text 其中 key 可以重复出现但要求text完全相同否则报错。这么设计是为了防止意外写重了key。**注意不允许key为空而text不为空**
如果想填空的本地化字符串, key和text完全留空即可工具会特殊对待不会加入 key集合。
text的key和text字段都是string类型因此在连续单元格或者sep产生的连续数据流模式中同样要遵循用""来表达空白字符串的规则。
|##| id | x&sep=|
|-|-|-|
|##type|int| text|
|| 1| /demo/key1#aaaa|
||2| /demo/key2#bbbb|
||3| | |
## datetime 类型
- 时间是常用的数据类型。Luban 特地提供了支持。
有两种形式,一种以纯字符串的方式填写。
- 以纯字符串方式填写
填写格式为 以下 4 种。
- yyyy-mm-dd hh:mm:ss 如 1999-08-08 01:30:29
- yyyy-mm-dd hh:mm 如 2000-08-07 07:40
- yyyy-mm-dd hh 如 2001-09-05 07
- yyyy-mm-dd 如 2003-04-05
- 以 excel内置的时间格式填写
|##| id | x|
|-|-|-|
|##type|int| datetime|
|| 1|1999-09-09 01:02:03|
||2| 1999-09-09 01:02|
||3| 1999-09-09 01 |
||4| 1999-09-09|
## 可空变量
- 有时候会有一种变量,我们希望它 功能生效时填一个有效值,功能不生效里,用一个值来表示。 例如 int 类型,常常拿 0 或者-1 作无效值常量。 但有时候0 或-1 也是有效值时,这种做法就不生效了。或者说 项目组内 有时候拿 0有时候拿-1 作无效值标记,很不统一。我们借鉴 sql 及 c#,引入 可空值概念,用 null 表达空值。
|##| id | x| color |
|-|-|-| - |
|##type|int| int?|QualityColor?|
|| 1| 1| A |
||2| null|B|
||3| 2|null|
## 列表类型 list,int
|##| id | x|
|-|-|-|
|##type|int| list,int|
|| 1| 12,33,44|
||2| 10,20,30,40|
## 向量类型 vector2,vector3,vector4
vector3 有三个字段 float x, float y, float z, 适合用于表示坐标之类的数据。
|##| id | x2|x3|x4|
|-|-|-| -| -|
|##type|int| vector2|vector3|vector4|
|| 1| 1,2|11,22,33|12,33,44,55|
||2| 2,3|22,44,55|6.5,4.7,8.9|
## 枚举类型
- 道具有品质,白绿蓝紫橙。 虽然可以直接填 1-5 这几个数据,但不直观,而且对程序非常不友好。
- 有一种更优雅的方式是定义枚举。
- [枚举定义](images/adv/def_09.png)
``` xml
<enum name = "EQuality">
<var name = "WHITE" alias = "白" value = "1">
<var name = "GREEN" alias = "绿" value = "2">
<var name = "BLUE" alias = "蓝" value = "3">
<var name = "PURPLE" alias = "紫" value = "4">
<var name = "ORANGE" alias = "橙" value = "5">
</enum>
```
- 之前用 bean 来定义结构,我们引入的新的 tag “enum” 来定义 枚举。
- enum 的 name 属性表示 枚举名。
- 如果生成 c#代码的话,会生成 cfg.item.Equality 类。
- `<var name=”xxx” alias=”xx” value=”xx”/>` 为检举项。
- 其中 name 为必填项,不可为空,也不能重复。
- alias 是可选项,枚举项别名。
- value 是枚举值,主要给程序使用。
- [完整用法](images/adv/def_10.png)
``` xml
<module name = "item">
<enum name = "EQuality">
<var name = "WHITE" alias = "白" value = "1">
<var name = "GREEN" alias = "绿" value = "2">
<var name = "BLUE" alias = "蓝" value = "3">
<var name = "PURPLE" alias = "紫" value = "4">
<var name = "ORANGE" alias = "橙" value = "5">
</enum>
<bean name = "Item">
<var name = "quality" type = "EQuality">
</bean>
</module>
```
- excel 表中,想表达一个枚举值,既可以用检举项 name,也可以用枚举项的 alias但不能是相应的整数值。
- 注意!如果想引用其他模块定义的 enum 或者 bean, type 里必须指定全名。
比如 type=”mall.TradeInfo” 。
|##| id | color |
|-|-| - |
|##type|int| QualityColor?|
|| 1| GREEN |
||2| RED|
||3| 白|
## bean 类型
- 有时候希望一个字段是复合类型。
- 比如,我们想用一个字段 level_range 来表示道具可以使用的等级范围,它包含两个字段,最小等级和最大等级。
- 此时,可以通过定义 bean 来解决。
[定义](images/adv/def_12.png)
``` xml
<bean name="IntRange">
<var name="min" type="int">
<var name="max" type="int">
</bean>
<bean name="Item">
<var name="level_range" type="IntRange">
</bean>
```
- 之前的字段都在一个单元格内填写,现在这个字段是 bean 类型,有两个值,该怎么填写呢?
如果也像 list,int 那样把两个数写在一个单元格里(如下图),会发现工具报错了: “10,20” 不是合法的整数值。
![如图](images/adv/def_13.png)
- 填写这些占据多个单元格的数据有两种办法:
1. 合并标题头
让 level_range 标题头占据两列,这样就能在两个单元格里分别填写最小最大等级了。
![如图](images/adv/def_14.png)
2. 使用 sep 分割单元格
字段定义中指定 sep 属性,用某些字符分割单元格,这样就能识别为两个整数了。
[定义](images/adv/def_15.png)
``` xml
<bean name="IntRange">
<var name="min" type="int">
<var name="max" type="int">
</bean>
<bean name="Item">
<var name="level_range" type="IntRange" sep="|">
</bean>
```
如果想用 分号; 或者 竖号 | 分割,只要 sep=”;” 或者 sep=”|“ 即可。
![如图](images/adv/def_16.png)
## list,bean 类型
- 有些时候,我们需要一个 结构列表字段。
比如说 道具不同等级会增加不同的血量。我们定义一个 ItemLevelAttr 结构。
[定义](images/adv/def_17.png)
``` xml
<module name="item">
<bean name="ItemLevelAttr">
<var name="level", type="int">
<var name="desc", type="string">
<var name="attr", type="float">
</bean>
<bean name="Item">
<var name="level_attrs" type="list,ItemLevelAttr" />
</bean>
</module>
```
配置:
![如图](images/adv/def_18.png)
- 对于多个值构成的字段,填写方式为 在标题头(level_attrs)对应的列范围内,按顺序填值。不需要跟策划的标题头名有对应关系。空白单元格会被忽略。也就是如下填法也是可以的:
![如图](images/adv/def_19.png)
- 这种填法的缺点是占据在太多的列。如果想如下填,该怎么办呢?
![如图](images/adv/def_20.png)
- 有两种办法。
1. bean ItemLevelAttr 增加属性 sep=”,”
[定义](images/adv/def_21.png)
``` xml
<bean name="ItemLevelAttr" sep=",">
<var name="level" type="int"/>
<var name="desc" type="string"/>
<var name="attr" type="float"/>
</bean>
```
如果不想用逗号”,” ,想用;来分割单元格内的数据,只要将 sep=”;” 即可。
2. 字段 level_attrs 增加属性 sep=”,”,即
[定义](images/adv/def_22.png)
``` xml
<bean name="ItemLevelAttr" sep=",">
<var name="level" type="int"/>
<var name="desc" type="string"/>
<var name="attr" type="float"/>
</bean>
<bean name="Item">
<var name="level_attrs" type="list,ItemLevelAttr" sep=",">
</bean>
```
如果想所有数据都在一个单元格内填写,又该怎么办呢?
![如图](images/adv/def_23.png)
想用 | 来分割不同 ItemLevelAttr ,用 , 来分割每个记录的数据。只需要 字段 level_attrs 的 sep=”,|” 即可。
[定义](images/adv/def_24.png)
``` xml
<bean name="ItemLevelAttr" sep=",">
<var name="level" type="int"/>
<var name="desc" type="string"/>
<var name="attr" type="float"/>
</bean>
<bean name="Item">
<var name="level_attrs" type="list,ItemLevelAttr" sep=",|">
</bean>
```
## 多态 bean
- 多态 bean 的 Luban 类型系统的核心,没有它就不可能比较方便简洁地表达游戏内的复杂数据。
- 常见的结构都是固定,但有时候会有需求,某个字段有多种类型,每种类型之间可能有一些公共字段,但它们也有一部分不一样的字段。简单的做法是强行用一个结构包含所有字段,这在类型种类较少时还勉强能工作,但类型很多,字段个数变化极大时,最终的复合结构体过于庞大笨拙,故而难以在实际采用。
- Luban 引入了 OOP 中类型继承的概念,即多态 bean。方便表达那些复杂配置需求。
- 假设 item 有一个形状 Shape 类型的字段。Shape 有两种 Circle 和 Rectangle.
Cicle 有 2 个字段 int id; float radius;
Rectangle 有 3 个字段 int id; float width; float height;
[定义](images/adv/def_25.png)
``` xml
<bean name="Shape">
<var name="id" type="int">
<bean name="Circle">
<var name="radius" type="float">
</bean>
<bean name="Rectangle">
<var name="width" type="float"/>
<var name="height" type="float"/>
</bean>
</bean>
<bean name="Item">
<var name="shape" type="Shape"/>
</bean>
```
配置:
![如图](images/adv/def_26.png)
- 注意到,多态 bean 与普通 bean 填写区别在于,多态 bean 需要一个类型名。这也好理解,如果没有类型名,如何知道使用哪个 bean 呢。
- 有时间策划不太习惯填写英文,或者说类型名有时候会调整,不希望调整类型名后配置也跟着改变,因为,多态 bean 支持别名的概念。
[定义](images/adv/def_27.png)
``` xml
<bean name="Shape">
<var name="id" type="int"/>
<bean name="Circle" alias="圆">
<var name="radius" type="float"/>
</bean>
<bean name="Rectangle" alias="长方形">
<var name="width" type="float"/>
<var name="height" type="float"/>
</bean>
</bean>
```
- 配置
![如图](images/adv/def_28.png)
- 使用类型名和别名来标识多态都是支持的,可以混合使用。
## multi_rows 多行 记录
- 使用数据表经常会遇到某个字段是列表类型的情形。有时候列表的 bean 的字段特别多,比如多达 10 个字段,列表包含了好几个 bean。如果此时配置成一行会导致 excel 列过多,策划编辑维护不方便直观。 Luban 支持这个列表 多行配置。
- [定义](images/adv/def_29.png)
``` xml
<bean name="MultiLineType">
<var name="x1" type="int"/>
<var name="x2" type="int"/>
<var name="x3" type="int"/>
<var name="x4" type="int"/>
<var name="x5" type="int"/>
<var name="x6" type="int"/>
<var name="x7" type="int"/>
</bean>
<bean name="Item">
...
<var name="lines" type="list,MultiLineType" multi_rows="1"/>
</bean>
```
- 和 普通 非多行记录的区别在于 lines 字段多了一个 multi_rows=”1” 字段,表示这个字段要多行配置。
- ![如图](images/adv/def_30.png)
## 多级标题头
- 经常会有字段占了多列,比如 Shape, 如果按顺序填写,有个问题在于,字段很多时,容易对应错误,不方便定位。
- 假设 有个 show_info 字段,包含 如下字段 string name; string desc; string tip;
- [定义](images/adv/def_31.png)
``` xml
<bean name="ShowInfo">
<var name="name" type="string" />
<var name="desc" type="string" />
<var name="tip" type="string" />
</bean>
<bean name="Item">
...
<var name="show_info" type="ShowInfo"/>
</bean>
```
- 配置
![如图](images/adv/def_32.png)
- 有几处改动
1. 我们新插入了一行标题头,第 2 行变成了两行。同时 A2,A3 单元格合并,表示标题头占了 2 行。
2. show_info 下一行,填上 子字段名 (顺序不重要)
- 我们称之为多级标题头,通过多级标题头的方式,可以精确定位深层次字段的列。方便策划填。
## 单例表
- 不是所有数据都是 类似 map 这样的多记录结构。有些配置只有一份,比如 开启装备系统的最小角色等级。 这些数据 所在的表,也只有一个记录。称之为 单例表。
- 我们创建一个单例表,来存放这些数据。
- [定义](images/adv/def_33.png)
``` xml
<bean name="GlobalConfig">
<var name="unlock_equip_sys_level" type="int"/>
<var name="unlock_mall_sys_level" type="int"/>
</bean>
<table name="TbGlobalConfig" value="GlobalConfig" mode="one" input="item/全局参数表.xlsx"/>
```
- 配置
![如图](images/adv/def_34.png)
## 横表与纵表
- 之前介绍的表都是 面向行,沿着行方向填写数据。有时候我们希望 以列为方向填写。
- 比如 上面的单例表。 如果改成一行一个字段,看起来会更清楚。 我们引入纵表支持。
- 定义不变,但 excel 的填法有区别,数据如下:
- ![如图](images/adv/def_35.png)
## 默认值
该特性只对excel格式文件有效。当单元格为空时该字段使用默认值。
```xml
<bean name="DemoDefault">
<var name="id" type="int"/>
<var name="x" type="int" default="10">
</bean>
<table name="TbDemoDefault" value="DemoDefault" input="default.xlsx"/>
```
![default](images/adv/def_50.png)
## convert 常量替换
游戏里经常会出现一些常用的类似枚举的值,比如说 升级丹的 id,在很多地方都要填,如果直接它的道具 id,既不直观,也容易出错。 Luban 支持常量替换。对于需要常量替换的字段,添加 convert=”枚举类”。 如果填写的值是 枚举名或者别名,则替换为 相应的整数。否则 按照整数解析。
定义
``` xml
<enum name="EFunctionItemId">
<var name="SHENG_JI_DAN" alias="升级丹" value="11220304"/>
<var name="JIN_JIE_DAN" alias="进阶丹" value="11220506"/>
</enum>
<bean name="Item">
<var name="cost_item_on_use" type="int" convert="EFunctionItemId"/>
</bean>
```
配置:
![如图](images/adv/def_41.png)

View File

@ -1,126 +0,0 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-01 16:26:41)
# json 数据源
## json数据格式
大多数数据格式填法符合直觉,有几个数据类型的格式比较特殊:
- set类型。填法为 [v1,v2,...]
- map类型。由于json只支持string类型的key因此map格式填法为 [[k1,v1],[k2,v2]...]
- 多态bean类型。需要 \_\_type\_\_ 属性来指定具体类型名。
- text类型填法为 {"key":key, "text":text}
不同数据结构在json中格式示例如下
```xml
<bean name="DemoType2" >
<var name="x4" type="int"/>
<var name="x1" type="bool"/>
<var name="x5" type="long"/>
<var name="x6" type="float"/>
<var name="x7" type="double"/>
<var name="x10" type="string"/>
<var name="t1" type="text"/>
<var name="x12" type="DemoType1"/>
<var name="x13" type="DemoEnum"/>
<var name="x14" type="DemoDynamic"/>
<var name="v2" type="vector2"/>
<var name="v3" type="vector3"/>
<var name="v4" type="vector4"/>
<var name="t1" type="datetime"/>
<var name="k1" type="array,int"/>
<var name="k2" type="list,int"/>
<var name="k8" type="map,int,int"/>
<var name="k9" type="list,DemoE2"/>
<var name="k15" type="array,DemoDynamic" />
</bean>
```
示例json文件内容如下
```json
{
"x1":true,
"x2":3,
"x3":128,
"x4":1,
"x5":11223344,
"x6":1.2,
"x7":1.23432,
"x10":"hq",
"t1": {"key":"/key/xx1","text":"apple"},
"x12": { "x1":10},
"x13":"B",
"x14":{"__type__": "DemoD2", "x1":1, "x2":2},
"v2":{"x":1, "y":2},
"v3":{"x":1.1, "y":2.2, "z":3.4},
"v4":{"x":10.1, "y":11.2, "z":12.3, "w":13.4},
"t1":"1970-01-01 00:00:00",
"k1":[1,2],
"k2":[2,3],
"k7":[2,3],
"k8":[[2,2],[4,10]],
"k9":[{"y1":1, "y2":true},{"y1":2, "y2":false}],
"k15":[{"__type__": "DemoD2", "x1":1, "x2":2}]
}
```
## 以复合json文件形式组织
整个表以一个或者多个json文件的形式组织。在table的input属性中手动指定json数据源有以下几种格式
- xxx.json把xxx.json当作一个记录读入。
- *@xxx.json把xxx.json当作记录列表读入。
- field@xxx.json把 xxx.json中的field字段当作一个记录读入。field可以是深层次字段比如 a.b.c。
- *field@xxx.json把xxx.json中的field字段当作记录列表读入。field可以是深层次字段。
比较有趣的是与xlsx数据源相似支持将多个表放到同一个json中不过实践中极少这么做。
如下列示例:
- TbCompositeJsonTable1 从 composite_tables.json的table1字段中读入记录列表从composite_tables2.json中读入记录列表从one_record.json中读入一个记录
- TbCompositeJsonTable2 从 composite_tables.json的table2字段中读入记录列表
- TbCompositeJsonTable3 从 composite_tables.json的table3字段中读入一个记录
```xml
<bean name="CompositeJsonTable1">
<var name="id" type="int"/>
<var name="x" type="string"/>
</bean>
<bean name="CompositeJsonTable2">
<var name="id" type="int"/>
<var name="y" type="int"/>
</bean>
<bean name="CompositeJsonTable3">
<var name="a" type="int"/>
<var name="b" type="int"/>
</bean>
<table name="TbCompositeJsonTable1" value="CompositeJsonTable1" input="*table1@composite_tables.json,*@composite_tables2.json,one_record.json"/>
<table name="TbCompositeJsonTable2" value="CompositeJsonTable2" input="*table2@composite_tables.json"/>
<table name="TbCompositeJsonTable3" value="CompositeJsonTable3" mode="one" input="table3@composite_tables.json"/>
```
## 以目录树形式组织
典型用法是以目录为数据源会遍历整棵目录树目录树下每个json文件为一个记录读入。
如下递归遍历test/json_datas整个目录树**按文件名排序后**依次将每个json数据当作一个记录读入。
```xml
<table name="TbDataFromJson" value="DemoType2" input="test/json_datas"/>
```
## 数据tag
与excel格式类似json格式支持记录tag用 \_\_tag\_\_ 属性来指明tag示例如下
```json
{
"__tag__":"dev",
"x":1,
"y":2
}
```

View File

@ -1,91 +0,0 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-01 16:26:41)
# Lua 数据源
## json数据格式
大多数数据格式符合直觉,有几个特殊点:
* 数据前有一个return这是因为 lua 数据是当作 lua 文件加载的,每个加载后的结果当作一个记录读入。
* set 的格式为 {v1, v2, ...}
* 与json不同lua 的table的key支持任意格式所以lua的map可以直接 {[key1] = value1, [key2] = value2, ,,,}
* text类型填法为 {key = key, text = text}
定义
```xml
<bean name="DemoType2" >
<var name="x4" type="int"/>
<var name="x1" type="bool"/>
<var name="x5" type="long"/>
<var name="x6" type="float"/>
<var name="x7" type="double"/>
<var name="x10" type="string"/>
<var name="t1" type="text"/>
<var name="x12" type="DemoType1"/>
<var name="x13" type="DemoEnum"/>
<var name="x14" type="DemoDynamic"/>
<var name="v2" type="vector2"/>
<var name="v3" type="vector3"/>
<var name="v4" type="vector4"/>
<var name="t1" type="datetime"/>
<var name="k1" type="array,int"/>
<var name="k2" type="list,int"/>
<var name="k8" type="map,int,int"/>
<var name="k9" type="list,DemoE2"/>
<var name="k15" type="array,DemoDynamic" />
</bean>
```
示例数据
```lua
return
{
x1 = false,
x2 = 2,
x3 = 128,
x4 = 1122,
x5 = 112233445566,
x6 = 1.3,
x7 = 1122,
x10 = "yf",
t1 = {key="/key/ab1", text="apple"},
x12 = {x1=1},
x13 = "D",
x14 = { __type__="DemoD2", x1 = 1, x2=3},
v2 = {x= 1,y = 2},
v3 = {x=0.1, y= 0.2,z=0.3},
v4 = {x=1,y=2,z=3.5,w=4},
t1 = "1970-01-01 00:00:00",
k1 = {1,2},
k2 = {2,3},
k8 = {[2]=10,[3]=12},
k9 = { {y1=1,y2=true}, {y1=10,y2=false} },
k15 = { { __type__="DemoD2", x1 = 1, x2=3} },
}
```
## 以复合lua文件形式组织
整个表在一个或者多个lua文件中组织。用法与json数据源相似参见 [json数据源](./data_json.md)
## 以目录树形式组织
典型用法是以目录为数据源会遍历整棵目录树目录树下每个lua文件为一个记录读入。如下示例递归遍历test/lua_datas整个目录树**按文件名排序后**依次将每个lua数据当作一个记录读入。
```xml
<table name="TbDataFromLua" value="DemoType2" input="test/lua_datas"/>
```
## 数据tag
与excel格式类似也支持记录tag用 \_\_tag\_\_ 属性来指明tag示例如下
```lua
return {
__tag__ = "dev",
x = 1,
y = 2,
}
```

View File

@ -1,64 +0,0 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-01 16:26:41)
### json 数据源
```xml
<bean name="DemoType2" >
<var name="x4" type="int" convert="DemoEnum"/>
<var name="x1" type="bool"/>
<var name="x5" type="long" convert="DemoEnum"/>
<var name="x6" type="float"/>
<var name="x7" type="double"/>
<var name="x10" type="string"/>
<var name="x12" type="DemoType1"/>
<var name="x13" type="DemoEnum"/>
<var name="x14" type="DemoDynamic" sep=","/>多态数据结构
<var name="v2" type="vector2"/>
<var name="v3" type="vector3"/>
<var name="v4" type="vector4"/>
<var name="t1" type="datetime"/>
<var name="k1" type="array,int"/> 使用;来分隔
<var name="k2" type="list,int"/>
<var name="k8" type="map,int,int"/>
<var name="k9" type="list,DemoE2" sep="," index="y1"/>
<var name="k15" type="array,DemoDynamic" sep=","/>
</bean>
<table name="TbDataFromXml" value="DemoType2" input="test/xml_datas"/>
```
递归遍历test/xml_datas整个目录树**按文件名排序后**依次将每个xml数据当作一个记录读入。其中1.xml文件内容如下
```xml
<data>
<x1>true</x1>
<x2>4</x2>
<x3>128</x3>
<x4>1</x4>
<x5>112233445566</x5>
<x6>1.3</x6>
<x7>1112232.43123</x7>
<x10>yf</x10>
<x12> <x1>1</x1> </x12>
<x13>C</x13>
<x14 __type__="DemoD2"> <x1>1</x1> <x2>2</x2> </x14>
<v2>1,2</v2>
<v3>1.2,2.3,3.4</v3>
<v4>1.2,2.2,3.2,4.3</v4>
<t1>1970-01-01 00:00:00</t1>
<k1> <item>1</item> <item>2</item> </k1>
<k2> <item>1</item> <item>2</item> </k2>
<k8>
<item> <key>2</key><value>10</value></item>
<item> <key>3</key><value>30</value></item>
</k8>
<k9>
<item> <y1>1</y1> <y2>true</y2> </item>
<item> <y1>2</y1> <y2>false</y2> </item>
</k9>
<k15>
<item __type__="DemoD2"> <x1>1</x1> <x2>2</x2> </item>
</k15>
</data>
```

View File

@ -1,94 +0,0 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-01 16:26:41)
# yaml 数据源
## 以复合数据形式组织
整个表在一个或者多个yaml文件中组织。用法与json数据源相似参见 [json数据源](./data_json.md)
## 以目录树形式组织
```xml
<bean name="DemoType2" >
<var name="x4" type="int" convert="DemoEnum"/>
<var name="x1" type="bool"/>
<var name="x5" type="long" convert="DemoEnum"/>
<var name="x6" type="float"/>
<var name="x7" type="double"/>
<var name="x10" type="string"/>
<var name="x12" type="DemoType1"/>
<var name="x13" type="DemoEnum"/>
<var name="x14" type="DemoDynamic" sep=","/>多态数据结构
<var name="v2" type="vector2"/>
<var name="v3" type="vector3"/>
<var name="v4" type="vector4"/>
<var name="t1" type="datetime"/>
<var name="k1" type="array,int"/> 使用;来分隔
<var name="k2" type="list,int"/>
<var name="k8" type="map,int,int"/>
<var name="k9" type="list,DemoE2" sep="," index="y1"/>
<var name="k15" type="array,DemoDynamic" sep=","/>
</bean>
<table name="TbDataFromYaml" value="DemoType2" input="test/yaml_datas"/>
```
递归遍历test/yaml_datas整个目录树**按文件名排序后**依次将每个yaml数据当作一个记录读入。其中1.yml文件内容如下
```yaml
---
x1: true
x2: 3
x3: 128
x4: 40
x5: 11223344
x6: 1.2
x7: 1.23432
x10: hq
x12:
x1: 10
x13: B
x14:
__type__: DemoD2
x1: 1
x2: 2
s1:
key: "/key32"
text: aabbcc22
v2:
x: 1
y: 2
v3:
x: 1.1
y: 2.2
z: 3.4
v4:
x: 10.1
y: 11.2
z: 12.3
w: 13.4
t1: '1970-01-01 00:00:00'
k1:
- 1
- 2
k2:
- 2
- 3
k8:
- - 2
- 2
- - 4
- 10
k9:
- y1: 1
y2: true
- y1: 2
y2: false
k15:
- __type__: DemoD2
x1: 1
x2: 2
```

View File

@ -1,20 +0,0 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-23 00:21:21)
# 服务端布署
## Docker 镜像布署
- 镜像会自动更新至最新版
- 在有 docker 的环境下,执行下面的指令
``` bash
docker pull hugebug4ever/luban:latest
docker run --name luban-server -d -p 8899:8899 hugebug4ever/luban:latest
```
## Windows 下命令行布署
- 下载 [release](https://github.com/focus-creative-games/luban/releases) 版本
- 解压 Luban.Server.zip
- 执行下面的命令即可
```
Luban.Server.exe
```

View File

@ -1,26 +0,0 @@
[//]: # "Author: bug"
[//]: # "Date: 2020-11-15 23:59:21"
===============================================================================
## 为什么要使用"客户端/服务器"模式
- 最初的想法是服务端闭源,因为代码生成部分花了很多心思,也方便加密之类的操作
- 为了方便与社区开发者交流开源后,还保留了这一模式,因为觉得
- 这一模式,也能作为 ddc 的基础 (distributed data cache)
- 配置文件需要反复生成与测试
- 文件数量上升后,配置生成不可避免地变慢
- 再快的技术,也挡不住大量数据的处理
## 如果用客户端生成,再通过服务器端分享缓存,不是更快么
- 是的。
- 但服务器模式还有方便更新的优势,就像网页访问,不需要每个客户端升级浏览器。
- 通知每个使用者要更新本地目录这件事,在实践中也产生过很多麻烦。
- 如果有效率提升,更佳的 feature (比如统计?), 在服务端实施更方便。
- c-s 本身是个流行的设计,虽然万物皆可客户端 ^_^。
- 考虑至此,就没有继续深究这个问题。
## 为什么 excel 的配置不像别的工具,用文件头描述数据?
- 数据描述除了 excel 还可以为 json 等其它数据源。用 xml 可以更统一。
- 数据类型可以描述地更详细,毕竟 excel 的表达只是强在数据。
- 数据关系可以更好地表达,比在 excel 中用一些技巧实现更舒服。

View File

@ -1,199 +0,0 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-10-18 15:35:26)
## 特性说明
--------------------
### 支持的数据类型
* 基础内置类型
- bool,byte,short,fshort,int,fint,long,flong,float,double,string,text,bytes
- vector2, vector3,vector4
- datetime
* 可空类型
- bool?,byte?,short?,fshort?,int?,fint?,long?,flong?,float?,double?
- vector2?,vector3?,vector4?
- datetime?
* 自定义枚举 enum
* 自定义常量 const
* 自定义结构 bean
- 可以定义所有类型的字段
- 支持无限制的结构继承,对于表达中大型项目的复杂数据(技能,buff,ai 等等) 极其有用。 (比如基类Shape, 子类 Circle,Rectangle
```mermaid
graph TD;
A-->B;
A-->C;
B-->D;
B-->E;
```
* 支持容器类型 array。 value 可以为内置类型,也可以为自定义类型
* 支持容器类型 list。 value 可以为内置类型,也可以为自定义类型
* 支持容器类型 set。 value 只能为内置类型或者enum类型不支持 bean 类型
* 支持容器类型 map。 key 只能为内置类型或者enum类型不支持 bean 类型。 value 可以为内置类型,也可以为自定义类型
### 多数据源支持
* 支持excel族。 csv 及 xls,xlsx等格式
* 支持从指定excel里的某个单元薄读入。
* 支持json。 每个json文件当作一个记录读入
* 支持lua。 每个lua文件当作一个记录读入
* 支持xml。 每个xml文件当作一个记录读入
* 支持目录。 递归目录下的所有文件每个文件当作一个记录读入。允许不同类型的文件混合比如目录下可以同时有json,lua,xml,excel之类的格式。
* 允许指定多个数据源,可以使用以上所有的组合。
* 扩展新的数据源也非常容易 (像支持lua,json,xml数据源只用了200行左右代码)
### 多种数据表模式
* one 格式,即单例表模式
* map 格式即普通key-value表模式。 任何符合set 的value要求的类型都可以做key
* bmap 格式,即双主键模式。 任何符合 set 的value要求的类型都可以作 key1和key
### 分组导出
在大多数项目中,导出给前后端的数据并非完全相同。有些表可能仅仅前端或者后端需要,有些字段也可能仅仅前端或者后端需要。 luban同时支持两种级别的分组
#### 表级别分组
定义方式为在table中定义group属性如果未定义 group,则默认导出给所有分组如果定义group则只导出给指定分组可以多个以逗号","分隔。
例如: TbDemoGroup_C表只给客户端使用, TbDemoGroup_S只能服务器使用, TbDemoGroup_E只给editor使用。
定义如下:
![group_table](docs/images/examples/group_02.png)
#### 字段级别分组
定义方式为给var指定group属性未指定则默认导出给所有分组。可以为多个以逗号","分隔。相比于大多数导表工具只支持**表顶级字段**的分组导出luban支持任意bean字段粒度级别的分组导出。
例如, TbDemoGroup表中 id,x1,x4 字段前后端都需要; x3 只有后端需要;x2 字段只有前端需要。x5是bean类型它导出给前后端但它的子字段也可以被分组过滤 x5.y1, x2.y4前后端都会导出x5.x3只导出给后端,x5.x2只导出给前端。
定义如下:
![group_var](docs/images/examples/group_01.png)
### 生成极快
* 大项目几十M配置数据也能1秒导出
* 生成工具使用客户端/服务器架构
* 服务器使用多线程加速生成,数十倍提高生成速度
* 服务器使用缓存直接返回未改动的代码或者数据的生成结果
* 支持增量生成
### 增强的 excel 格式
* 支持填写任意复杂的数据(比如 常见的 list,bean 这种类型)
* 支持 sep 在单个单元格内填写多个数据
* 支持 多行数据。即 对于 list,bean 类型的字段,可以多行填写
* 支持多级标题头,对填写 层次很深的数据时非常有用
* 支持导出标记。比如 是、否、test 等等,用于标记某行数据是否导出
* 支持用 true,false表示 bool 值,语义更清晰。
* 支持枚举 alias 别名,填写枚举类型不再需要写数字了
* 支持可空变量。可以用null表达空。 某些场合下语义更清晰。
* 支持 datetime 数据类型. 时间格式标准为以下几种最终被转化为utc时间方便程序处理
- yyyy-MM-dd HH:mm:ss
- yyyy-MM-dd HH:mm
- yyyy-MM-dd HH
- yyyy-MM-dd
### 代码编辑器支持
* 根据配置表定义生成相应的json文件的 load 及 save 代码(c#或者c++)方便编辑器加载和导出。每个记录对应一个json文件。
* 支持 unity 下用c# 开发编辑器
* 支持 unreal 下用c++ 开发的编辑器
### 多数据源
支持表数据来自excel文件来自excel某个单元薄来自json、xml、yaml文件来自目录下所有文件。以及以上几种的组合。
#### 来自某个excel文件
```xml
<table name="TbItem" value="Item" input="item/item1.xlsx">
```
#### 来自某个excel单元薄
```xml
<table name="TbItem" value="Item" input="table1@item/item1.xlsx">
```
####
#### 一个数据表来自两个excel文件
通过 excel文件1,excel文件2... 的方式指定数据表的数据来自多个文件,不同文件以逗号","分隔。当数据源为excel文件并且没有用@来指定某个单元表时该excel文件的中的所有单元表都会被读入。例如TbItem表的数据来自item目录下的item1.xlsx和item2.xlsx。
```xml
<table name="TbItem" value="Item" input="item/item1.xlsx,item/item2.xlsx">
```
#### 两个数据表来自同一个excel文件的不同单元表
通过 <单元表名>@excel文件的方式指定数据来自excel文件的某个单元表可以指定多个单元表通过逗号","分隔。示例中TbItem占了table1、table3两个单元表TbEquip占了table2、table4两个单元表。同一个数据表占据的单元表不必连续。示例中故意让TbItem和TbEquip占了不相邻的两个单元表。
```xml
<table name="TbItem" value="Item" input="table1@examples.xlsx,table3@examples.xlsx">
<table name="TbEquip" value="Equip" input="table2@examples.xlsx,table4@examples.xlsx">
```
#### 一个数据表的数据来自**目录**下的所有文件
当以目录为数据源时,会遍历整个目录树中所有文件,除了文件名以 ",.~"字符逗号或点号或波浪号开头的文件外读入每个文件中的数据。如果是excel族的数据会从每个文件中读取多个记录如果是xml、lua、json族的数据每个文件当作一个记录读入。 可以有指定多个目录同时为数据源,以逗号","分隔。
```xml
<table name="TbSkill" value="Skill" input="skill_datas">
```
### 支持多种导出数据格式
* **导出格式与源数据解耦**。无论源数据是 excel、lua、xml、json 或者它们的混合, 最终都被以统一的格式导出,极大简化了生成代码的复杂性。
* 导出binary。 内置binary格式加载最快占空间最少。
* 导出json 格式
* 导出 lua 格式
* 非常容易扩展其他输出格式(一般来说不到300行代码)
### 本地化支持
* 支持**本地化时间**。 配置中的 datetime会根据指定的timezone及localtime转化为正确的utc时间方便程序处理
* 支持**静态本地化**。 配置中的text类型在导出时已经转化为正确的本地化后的字符串
* 支持**动态本地化**。 配置中的text类型能运行时全部切换为某种本地化后的字符串
### 代码编辑器支持
* 支持 emmylua anntations。生成的lua包含符合emmylua 格式anntations信息。配合emmylua有强大的配置代码提示能力。
### 强大的数据校验能力
* 完整的数据内建约束检查
* ref 检查。检查表引用合法性。
* path 检查。检查资源引用合法性,对于防止策划填错极其有用,不再需要运行时才发现资源配置错误了。
* range 检查。检查数值范围。
* 扩展的自定义检查。使用自定义代码进行高级检查。提交配置前就能完成本地检查,避免运行时才发现错误,极大减少迭代成本。
### 资源导出支持
* 支持 res 资源标记。可以一键导出配置中引用的所有资源列表(icon,ui,assetbundle等等)
### 优秀的代码生成
- 良好模块化。比如对于c#语言生成cfg.item.Item,cfg.equip.EquipInfo这样的类
- 内存性能优化。支持c#值类型以及lua的紧凑格式保存数据节约内存。
- 支持为ref的字段生成resolve后的字段定义及加载后设置。读取所引用的字段不用再查表了。
- 支持对 list 类型数据 生成 index, 方便按列表和索引方式访问的需求。
### 良好的数据组织
- 数据模块化。允许策划按模块目录自由组织数据。
- 数据多源化。允许策划按需求选择最合适的源数据类型。
### 支持的语言 (覆盖主流的语言)
* 支持 c# (所有 .net framework 2 及以上, .net core平台)
* 支持 java (java 1.6 及以上)
* 支持 c++ ( c++ 11 及以上)
* 支持 go
* 支持 lua (5.1 及以上)
* 支持 typescript
* **新增其他语言支持非常容易**
### 支持的服务器引擎(满足语言版本的情况下)
* 纯 c# 的所有引擎
* 纯 java 的所有引擎
* 纯 go 的所有引擎
* 纯 c++ 的所有引擎
* 纯 lua 的所有引擎
* 纯 js或typescript的所有引擎
### 支持的客户端引擎(满足语言版本的情况下)
* unity + c#
* unity + tolua
* unity + xlua
* unity + ILRuntime
* cocosx-lua
* cocosx-js
* unreal + 纯 c++
* unreal + unlua
* unreal + puerts (typescript)
* 支持微信小程序和小游戏 sdk
* 支持 lua 的其他任何引擎
* 支持 js 或 typescript的 其他任何引擎
### 强大的扩展能力
* 支持插件形式,扩展其他生成极其方便

View File

@ -1,22 +0,0 @@
# 欢迎使用 Luban
## 介绍
Luban 是一个强大的生成与缓存工具。最初只用于对象生成对象可以是常规代码、配置数据、类似protobuf的消息代码也可以是游戏资源如assetbundle。
在大型项目中由于配置或资源数据庞大生成对象可能会花费相当多的时间。比如一个典型的MMORPG项目后期全量生成配置即使用了多线程加速所需时间
也在10秒的级别。因此使用client/server模式配合缓存机制来大幅加速生成过程。
Luban 最初是为了解决传统excel导出工具功能过于薄弱无法很好解决MMORPG游戏复杂配置需求的痛点问题。 自2015年以来经历过 MMORPG、卡牌、SLG 等多个上线项目的考验,
实际项目过程中不断迭代和优化,理解逐渐深入,最终由一个增强型的配置工具成为一个 **相对完备的游戏配置数据解决方案**。
## 文档
* [目录](docs/catalog.md)
## 支持和联系
QQ 群 : 692890842
QQ 群名 : Luban 开发交流群
邮箱 : taojingjian#gmail.com

View File

@ -1,157 +0,0 @@
## 本地化
支持多种本地化机制,分别处理不同的场合,它们可以同时使用。
### 静态文本值本地化
对于需要本地化的文本值,在配置导出时既已完成本地化的转化,适用于不同地区打不同包或者不同配置的情形。通过以下几个方面来实现静态文本值本地化:
- 使用 text 类型标识需要本地化的字符串。 text类型由两个字段构成, key和value。
- 使用本地化映射表提供text到其他语言的映射
- 未完成本地化的text单独输出到一个文件方便得知哪些文本值未完成本地化映射
#### 需要本地化的示例表
<table border="1">
<tr align="center">
<td>##</td>
<td>id</td>
<td colspan="2">name</td>
<td>desc</td>
<td>count</td>
</tr>
<tr align="center">
<td>##type</td>
<td>int</td>
<td colspan="2">text</td>
<td>string</td>
<td>int</td>
</tr>
<tr align="center">
<td/>
<td>1</td>
<td>/demo/key1</td><td>苹果</td>
<td>这是一个苹果</td>
<td>100</td>
</tr>
<tr align="center">
<td/>
<td>2</td>
<td>/demo/key2</td><td>香蕉</td>
<td>这是香蕉</td>
<td>100</td>
</tr>
<tr align="center">
<td/>
<td>3</td>
<td>/demo/key3</td><td>西瓜</td>
<td>这是西瓜</td>
<td>100</td>
</tr>
</table>
#### 文本值映射文件
| ## | key | origin_text | text_tw | text_en |
| - | - | - | - | - |
|##type|string|string|string|string|
|##|本地化key| 原始值 | 繁体值 | 英文 |
||/demo/key1|苹果|苹果|apple|
||/demo/key2|香蕉|香蕉|banana|
### Luban.Client 命令
有三个参数跟静态文本值本地化相关
- input_l10n_text_files 本地化映射文件
- l10n_text_field_name 映射的目标字段名。因为有可能多个语言都在同一个映射表内(如text_tw和text_en)
- output_l10n_not_translated_text_file 未完成文本值本地化映射的text
以下为一个示例脚本
```bat
%GEN_CLIENT% -h %LUBAN_SERVER_IP% -j cfg --^
-d %DEFINE_FILE%^
--input_data_dir %CONF_ROOT%\Datas ^
--output_code_dir Gen ^
--output_data_dir config_data ^
--gen_types data_json ^
-s all ^
--input_l10n_text_files l10n/cn/TextTable_CN.xlsx ^
--l10n_text_field_name text_en ^
--output_l10n_not_translated_text_file NotLocalized_CN.txt
```
### 示例输出结果
导出json文件内容为
```json
[
{
"id": 1,
"text": {
"key": "/demo/key1",
"text": "apple"
},
"desc": "这是一个苹果",
"count": 100
},
{
"id": 2,
"text": {
"key": "/demo/key2",
"text": "banana"
},
"desc": "这是香蕉",
"count":100
},
{
"id": 3,
"text": {
"key": "/demo/key3",
"text": "西瓜"
},
"desc":"这是西瓜",
"count": 100
}
]
```
示例中 /demo/key3 在本地化映射表中未提供因为output_l10n_not_translated_text_file 指定的未映射本地化文本值列表内容为。
```text
/demo/key3|这是西瓜
```
### 文本值动态本地化
运行时动态切换text类型字段到目标语言程序不需要根据id去本地化映射表里查询简化了使用。注意目前只有bean中text类型字段才支持像list,text之类的暂未支持。通过以下几个方面支持文本值动态本地化
- 标识字段为text类型
- 提供 (string key, string origin_value) => (string target_value) 的本地化映射函数
- 运行时调用 cfg.Tables.TranslateText函数一键切换配置中所有text类型值到目标语言
本地化映射函数实现比较简单,核心在于如何制作文本值本地化映射配置?使用者既可以使用自定义本地化映射表,可以使用普通的 luban配置表来提供 文本值映射配置,如下图:
|##| key | origin_text | text_tw | text_en |
|-| - | - | - | - |
|##type| string| string| string| string|
|##|本地化key| 原始值 | 繁体值 | 英文 |
||/demo/key1|苹果|苹果|apple|
||/demo/key2|香蕉|香蕉|banana|
假设想切换到en配置表的表名为 l10n.TbTextMapper示例c#版本地化映射函数如下:
```c#
string TextMapper(string key, string originText)
{
return tables.TbTextMapper.GetOrDefault(key)?.TextEn ?? originText;
}
```
### 多分支 数据
支持 main + patches的数据模式。在主版本数据基础上提供一个补丁数据合并处理后生成最终目标数据。适合制作海外有细节配置不同的多地区配置不需要
复制出主版本数据,接着在上面修改出最终数据。极大优化了制作本地化配置的工作流。
### 时间本地化
datetime类型数据在指定了本地化时区后会根据目标时区生成相应时刻的UTC时间方便程序使用.
通过Luban.Client的参数来指定时区
-t,--l10n_timezone <timezone>
该时区为linux下的时区名例如: -t "Asia/Shanghai" 指定目标时区为 亚洲上海(也即北京时间)

View File

@ -1,239 +0,0 @@
## 部属
Luban工具有两种部属方式。
### 方法1 Luban.Client与Luban.Server独立部属云生成模式
#### 部属 luban-server
- 基于 docker (强烈推荐以这种方式在服务器上部属luban-server因为可以充分利用缓存机制大幅缩短生成时间)
docker run -d --rm --name luban-server -p 8899:8899 focuscreativegames/luban-server:latest
- 基于 .net 6 runtime (可跨平台,不需要重新编译)
- 自行安装 .net 6 runtime.
- 从[示例项目](https://github.com/focus-creative-games/luban_examples/tree/main/Tools/Luban.Server)拷贝 Luban.Server**可跨平台即使在linux、mac平台也不需要重新编译**
- 在Luban.Server目录下运行 dotnet Luban.Server.dll (提示Win平台可以直接运行 Luban.Server.exe)
#### 安装 luban-client
- 基于 docker (只推荐与jenkins之类devops工具配合使用因为docker容器启动会增加一定的延迟)
docker run --rm -v $PWD/.cache.meta:/bin/.cache.meta focuscreativegames/luban-client <参数>
提醒! .cache.meta这个文件用于保存本地生成或者提交到远程的文件md5缓存**强烈推荐** 添加-v $PWD/.cache.meta:/bin/.cache.meta 映射不然每次重新计算所有涉及文件的md5,这可能在项目后期会造成多达几秒的延迟。
- 基于 .net 6 runtime 推荐win平台使用可跨平台不需要重新编译
- 自行安装 .net 6 runtime.
- 从[示例项目](https://github.com/focus-creative-games/luban_examples/tree/main/Tools/Luban.Client)拷贝 Luban.Client**可跨平台即使在linux、mac平台也不需要重新编译**
### 方法2 Client与Server一体模式
Client与Server在同个进程内运行不需要单独部属Luban.Server。
将运行脚本中%LUBAN_CLIENT%变量由 Luban.Client/Luban.Client 改为 Luban.ClientServer/Luban.ClientServer同时**删除 -h (--host ) 选项及其参数**。
Luban.ClientServer是Luban.Client的功能超集可以完全替代Luban.Client。
-----
## 使用
### luban-server 使用介绍
命令行使用
dotnet Luban.Server.dll [-p <port>] [-l <log level>]
参数介绍:
-p, --port <port> 可选参数。 监听端口 <port>默认为8899。
-l, --loglevel <log level> 可选参数。 日志级别。默认为INFO。 有效值有: TRACE,DEBUG,INFO,WARN,ERROR,FATAL,OFF
-t, --template_search_path 可选参数。模板的额外搜索路径。优先从此路径再从Templates目录搜索模板文件。
--disable_cache 可选参数。禁用生成中间过程的缓存,但保留了源文件缓存。在模板调试时比较有用。
--i10n:default_timezone <timezone> 可选参数。 datetime时间所在的时区。如果未设置则会尝试用"Asia/Shangehai"和"China Standard Time"。
关于时区win下可使用命令"tzutil /l" 查看本机时区列表。 也可查阅MS文档[default-time-zones列表](https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones?view=windows-11)
## luban-client 使用介绍
命令行使用
dotnet Luban.Client.dll [-h <host>] [-p <port>] [-l <log level>] [-c <cache meta file>] [-w <watch dirs>] [-h ] -j cfg -- <job options>
参数介绍:
-h,--host <host> 可选参数。 luban-server的地址。默认为 127.0.0.1
-p,--port <port> 可选参数。 luban-server的端口。默认为 8899
-j,--job <job> 必选参数。 生成类型。目前支持的生成类型有: cfg,proto,db。 生成配置请取cfg。
-l,--loglevel <log level> 可选参数。 日志级别。默认为INFO。有效值有: TRACE,DEBUG,INFO,WARN,ERROR,FATAL,OFF
-c,--cachemetafile <meta file> 可选参数。 meta缓存文件名。 默认为 .cache.meta
-w,--watch <dir1;dir2...> 可选参数。 监测目录或者目录列表,以逗号';'分隔。当开启此选项后,生成结束后不会退出程序,而是进入自动生成模式。监听到目标目录发生变化后,自动重新运行生成。省去改动后手动运行生成脚本的麻烦。
--generateonly 可选参数。 仅生成。不从服务器下载生成结果。可以用于检查服务器是否能成功生成。
-h,--help 可选参数。显示帮助信息
-- <job options> 必选参数。 从此参数起,便是 不同job的特有选项
----
cfg的<job options>介绍:
-d,--define_file <root file> 必选参数。 根定义文件名。
--input_data_dir <input data dir> 必选参数。 配置数据文件根目录。
--input_convert_dir <dir> 可选参数。 执行json、lua、xlsx之类数据格式转换时提供的数据源覆盖table中默认的input参数。
-c,--output_code_dir <output code dir> 可选参数。 生成代码文件的目录。
-s,--service 必选参数。生成分组目标。一般来说会定义client,server,editor等好几个目标不同目标的生成内容不同。
--gen_types <type1,type2,,,> 必选参数。生成任务类型。既可以是生成代码也可以是生成数据或者其他。目前支持的有 code_cs_bin,code_cs_json,code_cs_unity_json,code_lua_bin,code_java_bin,code_go_bin,code_go_json,code_cpp_bin,code_python27_json,code_python3_jsoncode_typescript_bin,code_typescript_json,code_rust_json,code_protobuf,data_bin,data_lua,data_json,data_json_monolithic,data_template,data_protobuf,convert_json,convert_lua,convert_xlsx
--output_data_dir <output data dir> 可选参数。 导出的数据文件的目录。只生成代码时可不指定。
--output_compact_json 可选参数。默认导出的json格式为对齐后的优雅格式使用此参数后导出紧凑的不带空格和换行的格式。
--validate_root_dir <path validate root dir>. 可选参数。 配置path检查的根目录。
--export_exclude_tags <tag1,tag2> 可选参数。 导出时排除包含这些tag的数据
--template_name <template name> 可选参数。数据模板的名称不包含后缀当gen_types包含 data_template时必须指定。
--data_file_extension <output data file extension> 可选参数。 导出数据文件的后缀。默认按照生成类型自动选择。
--naming_convention:module <convention> 可选参数。生成代码中模板名的命名约定,可用值为 language_recommend,none,camelCase,PascalCase,under_scores。 默认为language_recommend即选择与相应语言推荐的命名约定风格。 此选项目前未生效。
--naming_convention:bean_member <convention> 可选参数。生成代码中bean类型字段名的命名约定可用值为 language_recommend,none,camelCase,PascalCase,under_scores。 默认为language_recommend。
--naming_convention:enum_member <convention> 可选参数。生成代码中enum类型名的命名约定可用值为 language_recommend,none,camelCase,PascalCase,under_scores。 默认为language_recommend。此选项目前未生效。
--access_bean_member <access mode> 可选参数。 bean属性的访问方式。可用值为language_recommend,variable,getter_setter,property。默认为 language_recommend。此字段目前未生效。
--l10n:timezone <timezone> 可选参数。 指定所在时区。影响datetime类型转换为utc时间。 默认为中国北京时间。
--l10n:input_text_files <file1,file2..> 可选参数。 本地化的文本映射表。可以有多个。
--l10n:text_field_name <field name> 可选参数。 文本映射表中目标映射列的列名默认为text
--l10n:output_not_translated_text_file <file> 可选参数。 未被本地化映射的text key和value的输出文件。不提供该参数则不生成
--l10n:patch <patch name> 可选参数。当前需要生成的分支名称。
--l10n:patch_input_data_dir <patch data root dir> 可选参数。分支数据的根目录。
--typescript:bright_require_path <path> 可选参数。生成typescript代码引用的bright模块的路径
--typescript:bright_package_name <packet> 可选参数。生成typescript代码以包形式引用bright库的路径
--typescript:use_puerts_bytebuf 可选参数。生成typescript代码中使用puerts中导入的c# Bytebuf类。
--cs:use_unity_vector 可选参数。生成c#代码中使用UnityEngine.Vector{2,3,4}作为Vector数据类型。
## 示例
假设
luban.server 运行在本机端口为8899
luban.client的位置在 d:\tools\Luban.Client
配置定义在 d:\raw_config\defines
配置定义的根定义文件为 d:\raw_config\defines\__root__.xml
配置数据在 d:\raw_configs\datas
client项目为unity项目位置在 d:\client
你期望client生成的代码在 d:\client\Assets\Gen 目录
你期望client生成的数据在 d:\client\Assets\StreamingAssets\GameData 目录
你们服务器项目为 dotnet c#项目位置在d:\server
你期望server生成的代码在 d:\server\src\Gen
你期望server生成的数据在 d:\server\GameData
案例1
你要为客户端生成代码和数据。
你期望使用bin格式的导出数据类型
你为客户端选择的service分组为 client
当前在开发期,你期望导出数据中包含测试数据
则win下命令为
dotnet d:\tools\Luban.Client\Luban.Client.dll ^
-h 127.0.0.1 ^
-p 8899 ^
-j cfg ^
-- ^
--define_file d:\raw_config\defines\__root__.xml ^
--input_data_dir d:\raw_configs\datas ^
--output_code_dir d:\client\Assets\Gen ^
--output_data_dir d:\client\Assets\StreamingAssets\GameData ^
--gen_types code_cs_bin,data_bin ^
--service client
linux bash命令同理。
案例2
你要为客户端生成代码和数据。
你期望使用json格式导出数据类型。
你不期望导出数据中包含dev和test标签的数据
则win下命令为:
dotnet d:\tools\Luban.Client\Luban.Client.dll ^
-h 127.0.0.1 ^
-p 8899 ^
-j cfg ^
-- ^
--define_file d:\raw_config\defines\__root__.xml ^
--input_data_dir d:\raw_configs\datas ^
--output_code_dir d:\client\Assets\Gen ^
--output_data_dir d:\client\Assets\StreamingAssets\GameData ^
--gen_types code_cs_unity_json,data_json ^
--service client ^
--export_exclude_tags dev,test
案例3
你要为服务器生成代码和数据。
你期望使用json导出数据格式。
你期望包含测试数据。
你为服务器选择的service为server
则 win下命令为
dotnet d:\tools\Luban.Client\Luban.Client.dll ^
-h 127.0.0.1 ^
-p 8899 ^
-j cfg ^
-- ^
--define_file d:\raw_config\defines\__root__.xml ^
--input_data_dir d:\raw_configs\datas ^
--output_code_dir d:\server\src\Gen ^
--output_data_dir d:\server\GameData ^
--gen_types code_cs_json,data_json ^
--service server
案例4
luban-server 被你部属在 192.168.1.10这台机器上端口为1111。其他的如案例3。
则 win下的生成命令为
dotnet d:\tools\Luban.Client\Luban.Client.dll ^
-h 192.168.1.10 ^
-p 1111 ^
-j cfg ^
-- ^
--define_file d:\raw_config\defines\__root__.xml ^
--input_data_dir d:\raw_configs\datas ^
--output_code_dir d:\server\src\Gen ^
--output_data_dir d:\server\GameData ^
--gen_types code_cs_json,data_json ^
--service server
案例5
你要为服务器生成代码和数据。同时让luban.client执行生成后不退出进入监控状态只要配置定义或者数据有变化就自动生成代码和数据。
你期望使用json导出数据格式。
你期望包含测试数据。
你为服务器选择的service为server
则 win下命令为
dotnet d:\tools\Luban.Client\Luban.Client.dll ^
-h 127.0.0.1 ^
-p 8899 ^
-j cfg ^
-w d:\raw_config\defines;d:\raw_configs\datas
-- ^
--define_file d:\raw_config\defines\__root__.xml ^
--input_data_dir d:\raw_configs\datas ^
--output_code_dir d:\server\src\Gen ^
--output_data_dir d:\server\GameData ^
--gen_types code_cs_json,data_json ^
--service server

View File

@ -1,2 +0,0 @@
# TODO 待补充

View File

@ -1,92 +0,0 @@
# 模板
支持代码模板和数据模板,可以灵活定制生成的代码和数据。
## 代码模板
使用scriban模板文件定制导出数据格式。例如生成cs语言bin数据格式的cfg.Tables类的模板如下。
```
using Bright.Serialization;
{{
name = x.name
namespace = x.namespace
tables = x.tables
}}
namespace {{namespace}}
{
public sealed class {{name}}
{
{{~for table in tables ~}}
{{~if table.comment != '' ~}}
/// <summary>
/// {{table.comment}}
/// </summary>
{{~end~}}
public {{table.full_name}} {{table.name}} {get; }
{{~end~}}
public {{name}}(System.Func<string, ByteBuf> loader)
{
var tables = new System.Collections.Generic.Dictionary<string, object>();
{{~for table in tables ~}}
{{table.name}} = new {{table.full_name}}(loader("{{table.output_data_file}}"));
tables.Add("{{table.full_name}}", {{table.name}});
{{~end~}}
{{~for table in tables ~}}
{{table.name}}.Resolve(tables);
{{~end~}}
}
public void TranslateText(System.Func<string, string, string> translator)
{
{{~for table in tables ~}}
{{table.name}}.TranslateText(translator);
{{~end~}}
}
}
}
```
### 数据模板
使用scriban模板文件定制导出数据格式。例如自定义的lua数据模板如下
```
// {{table.name}}
{{for d in datas}}
// {{d.impl_type.full_name}}
{{~i = 0~}}
{{~for f in d.fields~}}
{{~if f ~}}
// {{d.impl_type.hierarchy_export_fields[i].name}} = {{f.value}}
{{~end~}}
{{~i = i + 1~}}
{{~end~}}
{{end}}
```
输出数据
```
// TbItem
// item.Item
// id = 1
// name = 钻石
// major_type = 1
// minor_type = 101
// max_pile_num = 9999999
// quality = 0
// icon = /Game/UI/UIText/UI_TestIcon_3.UI_TestIcon_3
// item.Item
// id = 2
// name = 金币
// major_type = 1
// minor_type = 102
// max_pile_num = 9999999
// quality = 0
// icon = /Game/UI/UIText/UI_TestIcon_1.UI_TestIcon_1
```

View File

@ -1,14 +0,0 @@
## road map 1
* 补充单元测试
* 新增静态本地化支持
* 新增动态本地化支持
* 新增生成用于unreal编辑器的 加载及保存json配置的cpp代码
* 新增生成用于unity 编辑器的 加载及保存json配置的c#代码
## road map 2
* 新增 unity 内嵌编辑器
* 新增 unreal 内嵌编辑器

View File

@ -1,26 +0,0 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-10-20 20:22:07)
## Python 示例
```Python
```
## TS 示例
``` typescript
```
## C# 示例
``` csharp
```
## C++ 示例
``` c_cpp
```
## Java 示例
``` java
```
## Go 示例
``` go
```

View File

@ -1,106 +0,0 @@
# 安装与执行
## 安装
1. [dotnet sdk 6.0](https://dotnet.microsoft.com/download/dotnet/6.0)
1. 下载luban_examples项目
下载项目 [luban_examples](https://github.com/focus-creative-games/luban_examples)。
项目中包含测试配置、最新的luban_client&luban_server工作以及大量的示例项目。为方便起见后续提及到的文件默认都指这个项目中的文件。
## 创建游戏配置
1. 从示例项目拷贝[MiniDesignerConfigsTemplate](https://github.com/focus-creative-games/luban_examples/tree/main/MiniDesignerConfigsTemplate) 到一个合适的目录,假设为 **MyConfigs**
2. 添加物品表 excel 文件
在 MyConfigs/Datas 目录下创建一个 “物品表.xlsx” 文件。
![如图](images/install/install_03.png)
文件内容如下
|##|id|name|desc|count|
|-|-|-|-|-|
|##type|int|string|string|int|
|##|id|名字|描述|个数|
||1001|item1| desc1| 10|
||1002|item2| desc2| 10|
||1003|item3| desc3| 10|
||1004|item4| desc4| 10|
- 第 1 行是 主字段行,包含表字段定义。单元格 A1 必须是 ##。表示这是一个有效数据表。
- 第 2 行是类型行第1个单元格必须为 ##type。
- 第 3 行是注释行。 以##开头。 可以有0-N个注释行而且可以出现在任何位置
- 第 4 行起是数据行。
3. 在 Datas 目录下的__tables__.xlsx添加表声明。如下图
|##|full_name|value_type|define_from_excel|input|index|mode|group|comment|patch_input|tags|output|
|-|-|-|-|-|-|-|-|-|-|-|-|
||demo.TbItem|Item|true|物品表.xlsx||||||||
4. 至此,物品表的创建工作大功告成!
## 生成代码和数据以及在程序中使用
假设是Unity项目使用json导出格式。 示例参考项目为 [Csharp_Unity_Json](https://github.com/focus-creative-games/luban_examples/tree/main/Projects/Csharp_Unity_json)。其他语言或者导出类型的组合,请参考 [luban_examples](https://github.com/focus-creative-games/luban_examples)
1. 项目准备。
拷贝示例项目中 Assets\LubanLib 目录到你的Unity项目中可以自由组织位置此时尝试编译项目理论上应该能成功编译。
2. 运行生成命令可以参考示例项目的gen_code_json.bat
```bat
dotnet <Luban.ClientServer.dll>
-j cfg ^
-- ^
--define_file <__root__.xml > ^
--input_data_dir <配置数据根目录(Datas)的路径> ^
--output_code_dir <生成的代码文件的路径> ^
--output_data_dir <导出的数据文件的路径> ^
--service all ^
--gen_types "code_cs_json,data_json"
```
其中
- <Luban.ClientServer.dll> 指向 Tools/Luban.ClientServer/Luban.ClientServer.dll
- --define_file 参数为 <MyConfigs>/Defines/\_\_root\_\_.xml 的路径
- --input_data_dir 参数为 <MyConfigs>/Datas 的路径
- --output_code_dir 参数为生成的代码文件存放的路径。 建议建议指向 unity的 Assets 目录下的某级子目录
- --output_data_dir 参数为生成的数据文件的存放路径。
详细的命令文档请看 [luban_command_tools](./luban_command_tools.md)。
如果一切正常,会产生一系列日志,最终一行是 == succ == 。
类似这样
![生成结果](images/install/install_07.png)
如果一切顺利。生成的代码文件会在 output_code_dir 参数指定的 目录中,生成的配置数据会在 output_data_dir 参数指定的目录中。把 output_code_dir 加入到 项目中,编译。此时应该能编译成功。
3. 加载配置
只需一行代码既可完成所有配置表的加载工具
```c#
var tables = new cfg.Tables(file => JSON.Parse(File.ReadAllText(gameConfDir + "/" + file + ".json")));
```
4. 使用加载后的配置表
cfg.Tables 里包含所有配置表的一个实例字段。加载完 cfg.Tables 后,只需要用 tables.<表名> 就能获得那个表实例接着可以做各种操作。例如我们要获取id = 10000 的那个道具。代码如下
```c#
cfg.item.Item itemInfo = tables.TbItem.Get(10000);
Console.WriteLine("id:{0} name:{1} desc:{2}", itemInfo.Id, itemInfo.Name, itemInfo.Desc);
```
可能你会注意到item.xml 里定义 Item 时,字段名 id,name,desc的首字母被大写了。这是因为工具会根据输出的语言自动作相应代码风格的字段名转换也即 boo_bar 会被转换为 BooBar 这样的名字。这也是为什么推荐 配置字段定义时统一使用 xx_yy_zz 的风格。
5. 至此完成 配置加载与使用!

View File

@ -1,137 +0,0 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-08 18:03:58)
## 特性
### 完备的类型系统
* 基础内置类型
- bool,byte,short,fshort,int,fint,long,flong,float,double,string,text,bytes
- vector2, vector3,vector4
- datetime
* 可空类型
- bool?,byte?,short?,fshort?,int?,fint?,long?,flong?,float?,double?
- vector2?,vector3?,vector4?
- datetime?
- <枚举>?
- < bean>?
- <多态bean>?
* 自定义枚举 enum 及相应可空类型
* 自定义常量 const
* 自定义结构 bean
* 多态bean
支持定义无限层次的OOP类型继承体系(比如父类Shape子类Circle,Rectangle),在表达复杂配置时极为简洁,对程序和策划都比较友好。
* 支持容器类型 array。 value 可以为内置类型,也可以为自定义类型
* 支持容器类型 list。 value 可以为内置类型,也可以为自定义类型
* 支持容器类型 set。 value 只能为内置类型或者enum类型不支持 bean 类型
* 支持容器类型 map。 key 只能为内置类型或者enum类型不支持 bean 类型。 value 可以为内置类型,也可以为自定义类型
### 支持增强的excel格式
* 用 true,false表示 bool变量。
* 用枚举名及别名表示枚举常量。比如用 白绿红之类表示品质而不是1,2,3这样的magic number
* 支持整数的常量替换。比如说 升级丹道具id 为 1122所有填升级丹id的地方可以填 升级丹 来表示。减少填写错误
* 支持可空变量. 用 null 表示空数据.
* 支持 datetime 数据类型. 时间格式标准为以下几种最终被转化为utc时间方便程序处理
- yyyy-MM-dd HH:mm:ss
- yyyy-MM-dd HH:mm
- yyyy-MM-dd HH
- yyyy-MM-dd
* 支持用sep拆分单元格。在一个单元格里填写多个数据。
* 支持多行数据。例如,章节配置里有一个复杂小节列表字段。支持多行填写这个列表数据。
* 支持多级标题头,方便对应一些比较深的数据。比如 a.b.c 这种。
* 支持多态别名,可以方便填写多态数据。比如说 Circle,5 或者 Rectangle,3,4
* **支持在excel里比较简洁填写出任意复杂的配置**。
- 支持结构列表。 比如 list,Equip (包含 int id, string name, float attr) 这样一个复杂结构列表数据,可以填成 1,abasfa,0.5|2,xxxyy;0.9。
- 支持多态结构。 比如 cfg.Shape 是一个多态类型,包含 Cirecle(float radius)和Rectagnle(float width, float size)。 可以填成 圆,5 或者 长方形,3,5。
- 支持无限层次的复杂结构的组合
- 比如 list,Convex(int id, Vector3[] vertexs) 是一个多边形列表, Convext自身包含一个顶点列表可以配置成 1_1.2,2.3,3.4_3.1,3.2,3.3|2_2.2,2.3.3.3 。
- 比如 list,Shape 是一个形状列表。 可以这样配置 Circle,10;Rectange,5,6;Circle,4
### 多种原始文件格式支持
一个复杂项目中,总有一部分数据(10-20%)不适合excel编辑比如技能、AI、副本等等这些数据一般通过专用编辑器来编辑和导出。遇到的问题是这种配置数据是无法与excel数据统一处理的造成游戏内有多种配置数据加载方案程序需要花费很多时间去处理这些数据的加载问题。另外这些复杂数据无法使用数据检验和分组导出以及本地化等等excel导表工具的机制。Luban能够处理excel族、xml、json、lua、目录等多种数据源统一导出数据和生成代码所有数据源都能使用数据检验、分组导出等等机制程序彻底从复杂配置处理中解脱出来。
* 支持excel族文件。 csv 及 xls,xlsx等格式
* 支持从指定excel里的某个单元薄读入。
* 支持json。 每个json文件当作一个记录读入
* 支持lua。 每个lua文件当作一个记录读入
* 支持xml。 每个xml文件当作一个记录读入
* 支持目录。 递归目录下的所有文件每个文件当作一个记录读入。允许不同类型的文件混合比如目录下可以同时有json,lua,xml,excel之类的格式。
* 每个表允许指定多个数据源,可以使用以上所有的组合。
- 多对一。比如可以在一个excel里用不同页签配置不同的表。比如 装备升级表和进阶表都在 装备表.xlsx中
- 一对多。比如任务表可以来 任务1.xlsx任务2.xlsx 等等多个表。
- 多对多。还可以是以上组合,不过实际中很少见)
### 多种导出数据格式支持
**导出格式与原始数据解耦**。无论源数据是 excel、lua、xml、json 或者它们的混合, 最终都被以**统一的格式**导出,极大简化了生成代码的复杂性。 目前支持以下几种导出格式:
* binary格式。与pb格式类似。所占空间最小加载最快。
* json 格式。
* lua 格式。
* 扩展其他格式也很容易。像前几种数据格式导出只用200行代码
### 支持表与字段级别分组
支持自定义分组类型。既支持按分组选择性导出一部分表,也支持选择性导出表中的一部分字段。比如为前后端分别导出他们所用的数据。
### 支持数据标签
支持 是、否、test 三种标签。可以为每行数据加标签。比如标签为"否"表示这行数据不被导出。 如果为 "test",则只在测试导出情况下才导出。比如内部开发时会配置一些测试数据,但对外发布时不希望导出它们的情形。
### 强大的数据校验能力
* 完整的数据内建约束检查
* ref 检查。检查表引用合法性。比如 Monster表中的dropId必须是合法的 TbDrop表的key.
* path 检查。检查资源引用合法性。比如 Monster表的icon必须是合法的图标资源。对于防止策划填错极其有用不再需要运行时才发现资源配置错误了。
* range 检查。检查数值范围。
* 扩展的自定义检查。使用自定义代码进行高级检查。提交配置前就能完成本地检查,避免运行时才发现错误,极大减少迭代成本。
### 多种数据表模式
* one 格式,即单例表模式
* map 格式即普通key-value表模式。 任何符合set 的value要求的类型都可以做key
### 本地化支持
* 支持**本地化时间**。 配置中的 datetime会根据指定的timezone及localtime转化为正确的utc时间方便程序处理
* 支持**静态本地化**。 配置中的text类型在导出时已经转化为正确的本地化后的字符串
* 支持**动态本地化**。 配置中的text类型能运行时全部切换为某种本地化后的字符串
### 代码编辑器支持
支持 emmylua anntations。生成的lua包含符合emmylua 格式anntations信息。配合emmylua有良好的配置代码提示能力。
### 资源导出支持
支持 res 资源标记。可以一键导出配置中引用的所有资源列表(icon,ui,assetbundle等等)
### 代码模块化
生成模块化的代码。比如
- c# cfg.item.ItemInfo
- c++ cfg::item::ItemInfo
- lua item.ItemInfo
- go item_ItemInfo
### 生成极快,大型项目也能秒级导出
使用 client/server模式利用服务器强大的硬件(大内存+多线程)同时配合缓存机制如果数据和定义未修改直接返回之前生成过的结果即使到项目中后期数据规模比较大也能1秒传统在10秒以上左右生成所有数据并且完成数据校验。考虑策划和程序经常使用生成工具积少成多也能节省大量研发时间。
### 数据模块化
策划可以方便地按需求自己组织数据目录和结构,不影响逻辑表。
### 支持主流的游戏开发语言
- c++ (11+)
- c# (.net framework 2+. dotnet core 2+)
- java (1.6+)
- go (1.10+)
- lua (5.1+)
- js 和 typescript (3.0+)
- python (2.7+ 及 3.0+)
### 支持主流引擎和平台
- unity + c#
- unity + tolua,xlua
- unity + ILRuntime
- unreal + c++
- unreal + unlua
- unreal + sluaunreal
- unreal + puerts
- cocos2d-x + lua
- cocos2d-x + js
- 微信小程序平台
- 其他家基于js的小程序平台
- 其他所有支持lua的引擎和平台
- 其他所有支持js的引擎和平台