Coder Social home page Coder Social logo

focus-creative-games / luban Goto Github PK

View Code? Open in Web Editor NEW
3.0K 40.0 474.0 7.4 MB

luban是一个强大、易用、优雅、稳定的游戏配置解决方案。luban is a powerful, easy-to-use, elegant and stable game configuration solution.

Home Page: https://code-philosophy.com/

License: MIT License

C# 99.99% Batchfile 0.01% Shell 0.01%
excel csv json xml cocos2d-x yaml protobuf flatbuffers game unity

luban's Introduction

Luban

icon

license star

luban是一个强大、易用、优雅、稳定的游戏配置解决方案。它设计目标为满足从小型到超大型游戏项目的简单到复杂的游戏配置工作流需求。

luban可以处理丰富的文件类型,支持主流的语言,可以生成多种导出格式,支持丰富的数据检验功能,具有良好的跨平台能力,并且生成极快。 luban有清晰优雅的生成管线设计,支持良好的模块化和插件化,方便开发者进行二次开发。开发者很容易就能将luban适配到自己的配置格式,定制出满足项目要求的强大的配置工具。

luban标准化了游戏配置开发工作流,可以极大提升策划和程序的工作效率。

核心特性

  • 丰富的源数据格式。支持excel族(csv,xls,xlsx,xlsm)、json、xml、yaml、lua等
  • 丰富的导出格式。 支持生成binary、json、bson、xml、lua、yaml等格式数据
  • 增强的excel格式。可以简洁地配置出像简单列表、子结构、结构列表,以及任意复杂的深层次的嵌套结构
  • 完备的类型系统。不仅能表达常见的规范行列表,由于支持OOP类型继承,能灵活优雅表达行为树、技能、剧情、副本之类复杂GamePlay数据
  • 支持多种的语言。支持生成c#、java、go、cpp、lua、python、typescript 等语言代码
  • 支持主流的消息方案。 protobuf(schema + binary + json)、flatbuffers(schema + json)、msgpack(binary)
  • 强大的数据校验能力。ref引用检查、path资源路径、range范围检查等等
  • 完善的本地化支持
  • 支持所有主流的游戏引擎和平台。支持Unity、Unreal、Cocos2x、Godot、微信小游戏等
  • 良好的跨平台能力。能在Win,Linux,Mac平台良好运行。
  • 支持所有主流的热更新方案。hybridclr、ilruntime、{x,t,s}lua、puerts等
  • 清晰优雅的生成管线,很容易在luban基础上进行二次开发,定制出适合自己项目风格的配置工具。

文档

Excel格式概览

基础数据格式

primitive_type

enum 数据格式

enum

bean数据格式

bean

多态bean数据格式

bean

容器

collection

可空类型

nullable

无主键表

table_list_not_key

多主键表(联合索引)

table_list_union_key

多主键表(独立索引)

table_list_indep_key

单例表

有一些配置全局只有一份,比如 公会模块的开启等级,背包初始大小,背包上限。此时使用单例表来配置这些数据比较合适。

singleton

纵表

大多数表都是横表,即一行一个记录。有些表,比如单例表,如果纵着填,一行一个字段,会比较舒服。A1为##column表示使用纵表模式。 上面的单例表,以纵表模式填如下。

singleton

使用sep读入bean及嵌套bean。

sep_bean

使用sep读取普通容器。

sep_bean

使用sep读取结构容器。

sep_bean

多级标题头

colloumlimit

限定列格式

titlelimit

枚举的列限定格式

titlle_enum

多态bean列限定格式

title_dynamic_bean

map的列限定格式

title_map

多行字段

map

数据标签过滤

tag

其他格式概览

以行为树为例,展示json格式下如何配置行为树配置。xml、lua、yaml等格式请参见 详细文档

{
  "id": 10002,
  "name": "random move",
  "desc": "demo behaviour tree",
  "executor": "SERVER",
  "blackboard_id": "demo",
  "root": {
    "$type": "Sequence",
    "id": 1,
    "node_name": "test",
    "desc": "root",
    "services": [],
    "decorators": [
      {
        "$type": "UeLoop",
        "id": 3,
        "node_name": "",
        "flow_abort_mode": "SELF",
        "num_loops": 0,
        "infinite_loop": true,
        "infinite_loop_timeout_time": -1
      }
    ],
    "children": [
      {
        "$type": "UeWait",
        "id": 30,
        "node_name": "",
        "ignore_restart_self": false,
        "wait_time": 1,
        "random_deviation": 0.5,
        "services": [],
        "decorators": []
      },
      {
        "$type": "MoveToRandomLocation",
        "id": 75,
        "node_name": "",
        "ignore_restart_self": false,
        "origin_position_key": "x5",
        "radius": 30,
        "services": [],
        "decorators": []
      }
    ]
  }
}

代码使用预览

这儿只简略展示c#、typescript、go、c++ 语言在开发中的用法,更多语言以及更详细的使用范例和代码见示例项目

  • C# 使用示例
// 一行代码可以加载所有配置。 cfg.Tables 包含所有表的一个实例字段。
var tables = new cfg.Tables(file => return new ByteBuf(File.ReadAllBytes($"{gameConfDir}/{file}.bytes")));
// 访问一个单例表
Console.WriteLine(tables.TbGlobal.Name);
// 访问普通的 key-value 表
Console.WriteLine(tables.TbItem.Get(12).Name);
// 支持 operator []用法
Console.WriteLine(tables.TbMail[1001].Desc);
  • typescript 使用示例
// 一行代码可以加载所有配置。 cfg.Tables 包含所有表的一个实例字段。
let tables = new cfg.Tables(f => JsHelpers.LoadFromFile(gameConfDir, f))
// 访问一个单例表
console.log(tables.TbGlobal.name)
// 访问普通的 key-value 表
console.log(tables.TbItem.get(12).Name)
  • go 使用示例
// 一行代码可以加载所有配置。 cfg.Tables 包含所有表的一个实例字段。
if tables , err := cfg.NewTables(loader) ; err != nil {
 println(err.Error())
 return
}
// 访问一个单例表
println(tables.TbGlobal.Name)
// 访问普通的 key-value 表
println(tables.TbItem.Get(12).Name)
  • c++ 使用示例
    cfg::Tables tables;
    if (!tables.load([](ByteBuf& buf, const std::string& s) { return buf.loadFromFile("../GenerateDatas/bytes/" + s + ".bytes"); }))
    {
        std::cout << "== load fail == " << std::endl;
        return;
    }
    std::cout << tables.TbGlobal->name << std::endl;
    std::cout << tables.TbItem.get(12)->name << std::endl;

license

Luban is licensed under the MIT license

luban's People

Contributors

absences avatar bruce1125 avatar dustinmaple avatar elmerning avatar fistchina avatar kteong1012 avatar madflyfish avatar neko1990 avatar pirunxi avatar shiinarinne avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

luban's Issues

关于数据文件的管理

生成的pb和相应语言代码是要自己在代码库里管理,程序里进行本地文件读取么?可否做成lubanserver 生成数据文件后,数据文件自动同步到etcd之类的配置中心,游戏server启动后自动在本地内存缓存所有配置数据并利用watch机制订阅etcd里得数据变化,实现数据热更。这种比较适合游戏服务端的使用场景。

希望增加一个“是否清空 output_data_dir/output_code_dir”的选项

背景说明

  • 多人开发的情况下,甲 开发 A 功能,乙 开发 B 功能。
  • 有 2 个 git 仓库,分别是 程序代码 和 策划配置。
  • 甲 做 A 功能,修改删除了部分字段,提交 程序代码仓库 和 策划配置仓库。
  • 乙 做 B 功能,本地修改了程序代码,如果此时更新了策划配置仓库,因为本地改动较多暂未更新程序代码仓库。
  • 此时,乙导出策划配置,会发现代码编译错误。
  • 因为本地改动较多,不方便马上更新程序代码仓库。
  • 此时,要么导出策划配置,手动将 A 功能模块相关的改动 discard,保证编译正确。
  • 要么将策划配置仓库 reset 到甲的修改之前(和本地代码保持一致)。
  • 无论哪种,都会对开发过程的行为有一定的限制。

期望

因此,希望鲁班工具可以增加“是否清空 output_dir”的选项,以此来解决上述的问题。
(这样 乙导出策划配置时,只选择导出 B 功能相关的策划配置,由于没有清空 output_dir,A 功能相关的程序代码还保持之前的状态。以此来规避该问题。)

或者,对于这种情况,有其他处理方式的话,也请指教一下。

目前的一个思路是将策划配置和程序代码放到同个 git 仓库,程序代码和策划配置总是对应的。
这种思路的问题:策划配置会合程序代码在同个仓库,没有那么独立,无法限制策划不小心提交不必要的改动。即便在同个仓库,程序代码和策划配置仍旧可能不匹配。当然整体来说是个可接受的方案。想看看还有没有其他思路。

Luban后面会考虑支持oneOf吗?

Lunban已经很好很强大了,策划的需求总是多种多样的,所以鲁班有打算支持类似protoBuff的oneof这种数据格式吗?
同一个字段里放入不同格式的复杂类型,这个很有帮助求求了~

可以支持xlsm格式吗?

因为配置表格里面有做宏功能的比较多,试了下好像不支持xlsm格式,后续会支持吗?

期望能增加abtest功能

例如A表,有两套数据,分别放在不同SHEET里结构相同,接口调用时支持全局的FALLBACK规则或者单表的FALLBACK规则 进行ABTEST

空列表读取错误

按照文档中的介绍,如果bean中的List字段想配置为空列表,需要使用}占位,我这样做了之后,还是会有报错。我的定义和数据如下:
image

image

报错是:
缺少数据
MyBean.testBean => {TestBean}.b

我debug了一下,发现是读取TestBean的时候,读取到字段l时,ExcelStreamDataCreator.ReadList方法中,在循环读取元素之前,调用了一次TrySep,这次调用中,将}读取出去了,然后把2作为列表的元素了,所以在读取字段b的时候,就没有数据了。

生成文件不是覆盖追加

luban 生成文件 会先删除文件夹里的所有文件,如果有非luban 需要生成的文件在文件夹 会被删除,希望改成 覆盖追加的形式!

lua 多主键表(独立索引)生成代码问题

image
image
我想配置一个配置表的Id,Domain两个为独立的键,生成对应独立的map映射表,在lua的表示中,只生成上图这种list的格式,这种多主键表(独立索引)配置方式,在lua貌似不生效

请问是否支持按字段过滤表格导出?

你好,请问一下luban是否支持设置单个字段过滤导出?

  1. 比如说一个怪物表我们配置了资源路径,这个字段后端不需要,是否能导出的时候过滤掉
  2. 比如说怪物表我们有一个后端的AI配置项,前端不需要,是否能导出的时候过滤掉

感谢

容器嵌套容器里如果出现两个list, 数据解析会有问题

这样的一个结构
{ILA57(_W~A%RCYKYH52JBI
数据导出的时候, 如果 arr_1 和 arr_2 里的字段是一个字段一个格子的话, 会出现配置在 arr_2 的数据, 导出的时候解析到 arr_1 里

演示个极端的例子, arr_1 和 arr_2 稍微调整一下
_( KOK 8W39JHULPBCP)QIM
6GBJS)D~CI_ S)H`$E0S)3L

导出的数据就会有问题
H~5)YXK$))55ZSFS(Q`}86Y

目前要保证数据导出没问题, 只能在 bean 里定义 sep 才能规避
JNY 3ADGDG0 1HDD(SA}$M
RV28WIZ7HQZZZMZ96KMU6

值类型生成的代码错误

定义如下
<bean name="PeopleAge" valueType="1" >

生成的代码
namespace cfg
{
public partial struct PeopleAge
...
public PeopleAge GetOrDefault(string key) => _dataMap.TryGetValue(key, out var v) ? v : null;

值类型没有null

修改Unity的CS代码模板不生效

问题

修改路径Luban.ClientServer\Templates\config\cs_unity_json\下的table.tpl文件后,使用LuaClientServer.exe重新生成的CS代码仍然是旧模板的代码。

尝试

  1. 删除.cache.meta缓存重试,仍然出现相同的问题。

  2. 尝试使用自定义模板搜索路径,无法识别参数。
    image

  3. 尝试使用 --disable_cache 参数失败,因为该参数仅对Server.exe生效。

其他

Bat脚本如下

set WORKSPACE=.

set GEN_CLIENT="%WORKSPACE%/Luban.ClientServer/Luban.ClientServer"
set CONF_ROOT="%WORKSPACE%/DesignerConfigs"

%GEN_CLIENT% -j cfg --^
 -d %CONF_ROOT%/Defines/__root__.xml ^
 --input_data_dir %CONF_ROOT%\Datas ^
 --output_code_dir ../UnityProject/Assets/Script/Data/Excel/Gen ^
 --output_data_dir ../UnityProject/Assets/StreamingAssets/ExcelData/Json ^
 --gen_types code_cs_unity_json,data_json ^
 -s all ^
 --template_search_path ./Luban.ClientServer/Templates/config/cs_unity_json

pause

工具版本为这个commit提交的版本

[feature request] 通过某个列的值限定另一多态列的子类型

例如某一物品表,有字段 id, itemType, itemValue, ... ,itemValue是多态字段,可以根据itemType确定itemValue的具体类型,按现在的做法需要策划在表中新加一列标明类型,或者在itemValue前面附上类型 如 ListOfInt:1,2,3 这两种写法都需要策划了解并填入正确的多态类型名。
希望在表格schema中可以配置一个映射表,设置不同的ItemType对应的ItemValue类型,而不需要策划在每行数据中填入。

导出表数据时如何额外生成一个存储常量值的C#类

表格结构:

----------------------------------------------------------------------
##var	id	desc	attr_name	default_val
##type	int	string	string	float
##	id	属性名	字段名	默认值
----------------------------------------------------------------------
	1	生命值	hp	0
	2		hp_base	0
	3		hp_add	0
	4		hp_rate	0
----------------------------------------------------------------------

我想在导表的时候额外生成一个C#类,存储字段名内容作为字符串常量,像这样:

public class GameAttrName()
{
public const string hp = "hp",
public const string hp_base = "hp_base",
public const string hp_add = "hp_add",
public const string hp_rate = "hp_rate",
}

请问要怎么做?

是否可以在业务表中定义 __tables__.xlsx 中的内容

工具很好用,但是交由其他习惯在一个配置表中定义所有结构和内容的小伙伴来说,表示多表配置有点复杂,而且在版本管理工具环境下,tables.xlsx 文件容易冲突。
请问是否有方法不定义 三个 tables,enum,bean.xlsx 表,在业务表中就把配置内容搞定呀~

非常感谢。

关于在 __table__.xlsx 中,input 项定义多个页签,如何只导出某一些页签的内容

作者您好:

在实际业务中,可能存在一个excel中的多个sheet中的数据结构可能一样,所以表全名和类名会一样
按照文档,我们可以在 table.xlsx 的 input 项以逗号分隔的形式将这些页签联合起来
此时的 group 项只能管理该项定义的所有页签

但是在某些情况下,如果我不想导出一部分页签的内容,又不能在excel中删除它,该如何定义呢?

image

输出lua文本符号问题

文本末尾是']'结尾时,必须至少用一个等号[=[ ]=]来括住文本。
语法错误

local str = [[我是文本[我自己是有括号结尾]]]

正确

local str = [=[我是文本[我自己是有括号结尾]]=]

忽略空白值引用不会生成代码

新版本luban,忽略空白值的引用不会再生成代码
比如example中,ai.xml里的BehaviorTree,其中的blackboard_id因为加了ref,生成的代码里会自动生成一个BlackboardId_Ref。但是如果我把他改成可以忽略空白值的引用,生成的代码里就不会再生成BlackboardId_Ref了。
QQ图片20231025162007

调试了下模版,发现如果用field.ctype.tags['ref']拿到的引用名称是ai.TbBlackboard?,名称里是带着问号的。
看了下源码,在源码TypeTemplateExtension.cs里的GetRefTable接口是这样的,估计GetTag("ref")的返回值带着问号,作为table名去GetCfgTable就失败了,不知道是不是一个BUG

QQ图片20231025162051

能否为生成类型添加克隆函数

我想将配置类直接作为运行时的类使用. 比如说我配置一个行为树节点,我希望这个节点有自己的运行时数据.但是如果配置两个相同节点就会导致运行时数据共用.

修改命名空间大小写后Unity代码生成失败

example默认命名空间为 'item', 我将其改成 'Item', 日志显示生成成功, 实际上生成失败了.
删除代码生成目录下的 'item' 文件夹后, 生成成功.

  • 预期1: 提示失败
  • 预期2: 不提示失败, 并成功生成

image

ref和path标签貌似没有起作用

我是这样定义的/<var name="NormalBodyId" type="int" ref="role.TbBodyPart",但是在把NormalBodyId设置了一个TbBodyPart表中不存在的值时,在导出.bin文件的时候并没有警告

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.