开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:1963

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 2175|回复: 30

[士郎] Unity 游戏配置表格代码自动生成术

[复制链接]  [移动端链接]
排名
53168
昨日变化
21

5

主题

5

帖子

21

积分

Rank: 9Rank: 9Rank: 9

UID
250663
好友
0
蛮牛币
134
威望
0
注册时间
2017-10-25
在线时间
3 小时
最后登录
2017-11-17
发表于 2017-11-1 09:03:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 卫宫士郎 于 2017-11-1 09:06 编辑

说起游戏配置表,不论是游戏程序还是游戏策划,都是每天都在打交道的、最普通不过的东西。
相信不少游戏程序员,撸过大量这样的代码:

[AppleScript] 纯文本查看 复制代码
class SkillSetting
{
    public int Id;
    public string Name;
    public string Desc;
    public int Arg1;
    public int Arg2;
    public int Arg3;
    // .....
    // .....
}

class SkillSettingManager
{
    // .....
    public void Init ()
    {
        var table = TableReader.Read("jineng.txt")
        for (var line = 0; line <= table.RowsCount; line++)
        {
            Id = table.GetRow(line, "id");
            Name = table.GetRow(line, "name");
            Desc = table.GetRow(line, "desc");
            Arg1 = table.GetRow(line, "arg1");
            Arg2 = table.GetRow(line, "arg2");
            Arg3 = table.GetRow(line, "arg3");
            // ......
        }
    }
}
// ....
// .....
// ......
class BuffSettingManager { .... }
class TaskSettingManager { .... }
class MissionSettingManager { .... }

// .... 接近上百个XXX SettingManager


相信不少游戏策划,都遇到过这样的配置表:

shibazhang.png
好吧。大家都或多或少遇过这些问题

  • 大量的配置表代码需要手工撸,枯燥繁杂
  • 大量的手工配置表代码跟随着大量的BUG
  • 策划配置表跟程序代码经常命名不一
  • 策划新人看不懂配置表的这一列究竟是干嘛的
  • 策划同学想要更方便的工具提升工作体验
  • 配置表加载严重影响游戏启动速度
  • 运营需求对游戏配置表修改热重载,手工代码没有支持
  • 配置表相关联的功能和BUG消磨大量的研发、运营时间


嗯,多么痛的领悟。

接下来抛砖引玉,让我们一起探讨一种游戏配置表的优化方案。

需求
编辑游戏配置表的用户首要就是我们的策划同学了,而策划同学最喜欢最顺手的工具非Excel(或WPS表格)莫属了。 当然了,也见过自己开发编辑器工具的,但我们毕竟不是全职做工具开发,没必要额外的增大工作量。

因此我们可以在Excel表格设计上,动动手脚。策划同学有这样的需求:

  • 配置表的列头带上注释
  • 策划同学可以在任意他们喜欢的地方做注释
  • 策划同学可以在他们的配置表中的添加文档性东西如图表、文字框
  • 有时候同样的表,可以拆分成多张,方便编辑


拿到这样的一份配置表后,程序同学有这样的需求:

  • 希望配置表的代码是可以自动生成的
  • 部分复杂逻辑的可以自定义扩展的
  • 为配置表的列定义类型



方案编辑

针对这些需求,我们就有了这样的这个结果:

kuaijie.png


  • 第一行是列名
  • 第二行是程序用途的类型声明,如int, Dictionary<int, string>
  • 第三行是该列的注释
  • 列名以#开头,则这一列为注释列(忽略该列单元格内容忽略)
  • 行的第一个单元格内容以#开头,则这一行为注释行(所有行单元格内容忽略)
  • 可以加入图表、第二张工作表作为辅助内容


将这样的一张表,保存为SettingSrc/Test.xls文件。

下面我们使用一个名为TableML的执行程序,可以从Releases · mr-kelly/TableML · GitHub下载测试,并包含源码和单元测试。

TableML.exe --Src SettingSrc --To Setting --CodeFile Code.cs

在SettingSrc目录下执行这个配置表编译命令,会把所有的Excel文件,编译成Tab分隔的表格纯文本(TSV),并生成一个代码文件Code.cs。
编译后的TSV文件Test.tml纯文本内容,实质就是剥离了注释的Excel表格。

Excel表编译结果:

kuaijie2.png

同时命令生成代码:

[AppleScript] 纯文本查看 复制代码
/// <summary>
/// Auto Generate for Tab File: "Test.bytes"
/// Singleton class for less memory use
/// </summary>
public partial class TestSetting : TableRowFieldParser
{
        /// <summary>
        /// ID Column/编号/主键
        /// </summary>
        public string Id { get; private set;}

        /// <summary>
        /// Name/名字
        /// </summary>
        public I18N Value { get; private set;}

        // .............
}
public class TestSettings 
{
     IEnumerator GetAll()
     {
          // ...
     }
}




至此,程序同学,把策划同学的游戏配置表编译优化成纯文本格式,生成的Code.cs文件也导入Unity工程,使用TestSettings.GetAll来获取所有的配置表内容了。

多语言

kuaijie3.png



标注列的类型为I18N


既然表的第二行支持类型说明,那自然而然,我们可以标记某一列是可以需要进行翻译的。比如,把这一列标记成I18N,我们通过脚本,把所有带有I18N列中的字符串进行收集,自动生成一个翻译表;而生成的代码中对应I18N这个类,则对翻译表进行处理,来实现字符串的多语言翻译。 细节不多叙述。
而在游戏做多语言版本的过程中,光字符串翻译是不够的,我们有些时候,不同的版本还有不同的游戏数值。鉴于我们的表编译机制,我们可以加入一些类似预编译指令的机制来处理:

kuaijie4.png


拆表


在很多时候,策划同学喜欢将一个表的东西,分成多个文件来写。比如有游戏的道具比较多,一般会分成SettingSrc/Item/Weapon.xls,SettingSrc/Item/Equipd.xls, SettingSrc/Item/Common.xls等多张表格,尽管他们是不同的文件,但是它们的列头都是一样的,这样让编辑起来更加的容易,而且多人编辑时,不容易做成冲突。

在程序代码中,它们也会被一个统一的ItemSettingsManager类读取成统一的配置类型。

我们可以应用之前的“#”符号,来对他们的文件名修改一下:SettingSrc/Item/#Weapon.xls,SettingSrc/Item/#Equipd.xls, SettingSrc/Item/#Common.xls,这样,来骗过编译程序,再执行刚才的编译命令:

TableML --Src SettingSrc --To Setting --CodeFile Code.cs

这样就会让代码生成器,忽略#号后面的字符串,把它们统一合并成ItemSettings类。

[AppleScript] 纯文本查看 复制代码
public class ItemSettings
{
    // 把三个表一起进行加载
    public static readonly string[] TabFilePaths = {
       "Item/#Weapon.xls", "Item/#Equipd.xls", "Item/#Common.xls"
   };
   // ...
}


至于还有一些细节功能的,如自定义类型、自定义解析、自定义代码模板(让C++、Lua都支持)等扩展代码能力的功能,这里不多作解释。
具体的细节可以参考命令的源码中的单元测试:
GitHub: TableML,

这是一个提供给Unity游戏开发的开源配置表代码生成工具,
一些逻辑细节和教程也可以参考这里的文章。

常见问题


在TableML尝试应用的过程中,曾经遇到过不少疑问:

考虑其它格式让策划同学编辑?如Lua、JSON?

考虑到策划同学和其他同学的使用体验和习惯,Excel表格是他们最顺手、功能强大的工具。

既然编译,为什么不直接编译成序列化的字节?

选择编译成纯文本格式,更多出于工程考虑的,一考虑文本格式能对版本管理(如SVN)更友好,二考虑开发调试也更容易。性能方面,在我经历的项目上,对这种Tab分隔的表格文本解析,比序列化还要快。

我更喜欢自己撸,没必要代码自动生成?

从程序习惯的角度来说,这种想法无可厚非,毕竟多年的开发习惯如此,而且自由度更高,写起这些代码来自然是舒畅的 。 但是从工业角度来想,人工写出的代码维护Bug成本,比自动生成代码维护成本要高。并且,为自动生成的代码添加功能(比如,运行时动态重载),只需要在生成代码的代码中稍微修改,就全局生效。

Excel文件怎么进行版本比较?

在我看来这是一个非常关键的问题。这也是为什么Excel表被编译成TSV纯文本的一个重要原因。另外除了Excel表,TableML命令中还支持TSV翻译到TSV,就是直接把Excel文件另存为TSV格式的配置表文件,再进行编译。

另外,Beyond Compare 4支持Excel文件的直接比较;TortoiseSVN中双击Excel文件,也会打开Excel文件显示差异的地方(但较蹩脚)。


我项目的配置表都是自动生成的,程序策划没意见、也挺智能的?


恭喜你们项目的质量棒棒的,也希望一同分享您的方案!独乐乐不如众乐乐!


所以呢


说这么多,技术角度来说,自动化的配置表编辑和加载,没有什么技术含量,更多的是一种思想,但是我相信这对项目管理、规范化是起到积极的作用的,减少重复劳动的时间,增加生产力。做游戏项目,消耗时间的,往往不是高深难解的问题,而是一些简单问题的重复轮回。
藉著本文抛砖引玉,也希望大家各抒己见,提出一些让策划、程序皆大欢喜的方法和技巧,让更多更好的方案通过思想的交流碰撞出来,“节约更多时间,去陪恋人、家人和朋友 :) ”




知乎
陈小霖



回复

使用道具 举报

排名
274
昨日变化
1

28

主题

766

帖子

3401

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
6108
好友
15
蛮牛币
3258
威望
0
注册时间
2013-10-22
在线时间
971 小时
最后登录
2017-11-19

社区QQ达人七夕浪漫情人

QQ
发表于 2017-11-1 09:12:40 | 显示全部楼层
不错哦

回复

使用道具 举报

3偶尔光临
189/300
排名
10359
昨日变化
177

0

主题

54

帖子

189

积分

Rank: 3Rank: 3Rank: 3

UID
228538
好友
2
蛮牛币
194
威望
0
注册时间
2017-6-24
在线时间
63 小时
最后登录
2017-11-19
发表于 2017-11-1 09:32:45 | 显示全部楼层
感谢分享

回复

使用道具 举报

6蛮牛粉丝
1491/1500
排名
1421
昨日变化

1

主题

457

帖子

1491

积分

Rank: 6Rank: 6Rank: 6

UID
56496
好友
0
蛮牛币
4354
威望
0
注册时间
2014-11-19
在线时间
329 小时
最后登录
2017-11-17
发表于 2017-11-1 09:37:14 | 显示全部楼层
规范化。。。我先哭一会儿,没有策划怎么办

回复 支持 反对

使用道具 举报

5熟悉之中
539/1000
排名
5080
昨日变化
1

1

主题

147

帖子

539

积分

Rank: 5Rank: 5

UID
192151
好友
0
蛮牛币
251
威望
0
注册时间
2016-12-14
在线时间
177 小时
最后登录
2017-11-16
发表于 2017-11-1 10:16:26 | 显示全部楼层
好东西 嘿嘿

回复

使用道具 举报

5熟悉之中
960/1000
排名
3787
昨日变化
2

0

主题

479

帖子

960

积分

Rank: 5Rank: 5

UID
156480
好友
0
蛮牛币
1572
威望
0
注册时间
2016-7-12
在线时间
177 小时
最后登录
2017-11-13
发表于 2017-11-1 10:24:59 | 显示全部楼层
66666666666666666666

回复 支持 反对

使用道具 举报

7日久生情
2003/5000
排名
17661
昨日变化
6

2

主题

1675

帖子

2003

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
185807
好友
0
蛮牛币
2610
威望
0
注册时间
2016-11-22
在线时间
302 小时
最后登录
2017-11-15
发表于 2017-11-1 10:32:27 | 显示全部楼层
赞,不错不错,学习了,谢谢分享

回复 支持 反对

使用道具 举报

排名
4086
昨日变化

9

主题

115

帖子

625

积分

Rank: 9Rank: 9Rank: 9

UID
117397
好友
2
蛮牛币
1246
威望
0
注册时间
2015-8-10
在线时间
135 小时
最后登录
2017-11-14

专栏作家

发表于 2017-11-1 11:17:03 | 显示全部楼层

回复

使用道具 举报

排名
22318
昨日变化
3

19

主题

47

帖子

89

积分

Rank: 2Rank: 2

UID
251769
好友
0
蛮牛币
142
威望
0
注册时间
2017-10-31
在线时间
9 小时
最后登录
2017-11-10
发表于 2017-11-1 11:50:49 | 显示全部楼层
不错不错,谢谢分享,先收了
[发帖际遇]: nicaiwocaini 乐于助人,奖励 1 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

2初来乍到
139/150
排名
16542
昨日变化
5

0

主题

84

帖子

139

积分

Rank: 2Rank: 2

UID
158334
好友
0
蛮牛币
181
威望
0
注册时间
2016-7-22
在线时间
27 小时
最后登录
2017-11-3
发表于 2017-11-1 12:02:49 | 显示全部楼层
感谢楼主分享

回复

使用道具 举报

4四处流浪
397/500
排名
5411
昨日变化
1

0

主题

86

帖子

397

积分

Rank: 4

UID
226471
好友
0
蛮牛币
604
威望
0
注册时间
2017-6-12
在线时间
111 小时
最后登录
2017-11-18
发表于 2017-11-1 13:29:48 | 显示全部楼层
感谢楼主分享!!!

回复

使用道具 举报

3偶尔光临
200/300
排名
10359
昨日变化
4

0

主题

47

帖子

200

积分

Rank: 3Rank: 3Rank: 3

UID
156414
好友
1
蛮牛币
307
威望
0
注册时间
2016-7-11
在线时间
81 小时
最后登录
2017-11-18
发表于 2017-11-1 14:04:51 | 显示全部楼层
感谢分享

回复

使用道具 举报

4四处流浪
392/500
排名
4546
昨日变化

0

主题

49

帖子

392

积分

Rank: 4

UID
218402
好友
2
蛮牛币
608
威望
0
注册时间
2017-4-19
在线时间
97 小时
最后登录
2017-11-14
QQ
发表于 2017-11-1 20:20:39 | 显示全部楼层
这就666666了
[发帖际遇]: Gilbert 在论坛发帖时没有注意,被小偷偷去了 2 蛮牛币. 幸运榜 / 衰神榜

回复

使用道具 举报

3偶尔光临
185/300
排名
10211
昨日变化
2

2

主题

49

帖子

185

积分

Rank: 3Rank: 3Rank: 3

UID
215897
好友
1
蛮牛币
113
威望
0
注册时间
2017-4-1
在线时间
60 小时
最后登录
2017-11-9
发表于 2017-11-2 08:07:54 | 显示全部楼层
楼主我爱你

回复

使用道具 举报

3偶尔光临
291/300
排名
12929
昨日变化
252

8

主题

205

帖子

291

积分

Rank: 3Rank: 3Rank: 3

UID
249218
好友
2
蛮牛币
935
威望
0
注册时间
2017-10-17
在线时间
28 小时
最后登录
2017-11-19
发表于 2017-11-2 08:31:40 | 显示全部楼层
dddddddddddddddssssssssssssssss
[发帖际遇]: robinApp 在论坛发帖时没有注意,被小偷偷去了 2 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表