游戏开发论坛

 找回密码
 立即注册
搜索
查看: 28394|回复: 35

[分享] [技术交流] 如何建好数据表

  [复制链接]

98

主题

784

帖子

4495

积分

版主

Rank: 7Rank: 7Rank: 7

积分
4495
发表于 2013-5-30 00:38:12 | 显示全部楼层 |阅读模式
  最近对外交流比较频繁,接触了很多朋友的项目,发现在他们的项目中,数据表的建立都有比较大的问题,大多表现为:

  1,数据列众多:随机挑张表打开一看,我的天,横向没有100列也得有5、60列,做个页游甚至手游,至于吗?但是他们却能详细的分析出每一条打算干嘛?这点我觉得至少他们都是做过项目的老团队,分析出这些数据的作用应该不难,但是却让我看到了一些问题——策划与程序的沟通缺乏,甚至有些团队的表结构是由程序建立的,而程序员本身对游戏即将做成什么样也是一知半解。

  2,表连表频繁:一个任务表,某几列挂向NPC表,为的是谁给的任务,任务交给谁,还有任务过程中要接触谁(比如杀什么怪);除此之外,还要挂向道具表,任务奖品、任务掉落等;这还不够,他还要挂向一些其他表,比如buff表,技能表。我的天,这你让策划怎么去填这个表,天地良心,一个公司机器配置最差的基本都是策划,而他们却要用这种机器打开高配机器开了都吃力的这么多的表,仅仅只是为了填一个表。

  我相信大家经历的项目中,以上两大问题,多多少少都会遇到过一些吧,从我的经验来看,在一个游戏设计师设计表的时候(我认为数据表结构应该由策划提供),需要注意以下这些,才能建立出比较适合的表来:

1,合理利用计算公式、巧妙运用数据类型,该去掉的去掉,该合并的合并。

  么是合理利用计算公式?我见过很多混账表,其中甚至包括了玩家升级经验表,这往往发生于那些认为策划应该被细分为系统、数值等工种的团队。事实上在经验值的数值设计上,是最开放的,在你设计整个游戏系统的时候你想要的经验值提升曲线如何?无非越高等级需要越多经验,这我们都知道,那么经验增长速度的环比如何?无非也就是越到后面提升越慢的和越到后面提升越明显的,2个都接近于公式y=power(a,b),区别在于前者的b要大于1而尽可能小于1.5,后者只要大胆的大于等于2就好了,这至于去填一个表吗?不值得!这就是所谓的该去掉的去掉,某列数据可以用公式计算,或者通过其他数据演算获得,那么就去掉它,表的每一列数据都应该是独特的,是计算机无法通过一种固定逻辑产生来的,因此才需要人为去填写。

  什么事巧妙运用数据类型?我见过一些技能表,在不断地开发过程中无限膨胀:今天策划想出来了某某技能不能对建筑物使用(dota类),由于表是程序建立的,程序说了,加一列“可否对建筑有效”,布尔型;明天策划又想到了,一些技能还不能对元素类别的怪物使用,于是程序又说了……逐渐逐渐的,表列越来越多了。你可以说策划初期为什么没有想好有哪些目标类别,那这样一早建立好表,不就不用去改了吗?事实上有经验的项目经理都知道,这是不现实的,因为人每天都在思考,新的主意如果够好,应该被利用。那么像这样一个动态性的问题,事实上我们可以把它变成一个位运算的做法。每一个角色数据中有一项免疫类别(ImmuneType),而技能本身有一项效果类别(effectType),我们指定元素类为0位、建筑为1位、魔法为2位、诅咒为3位、钢铁为4位,这些都是我现在脑袋一拍说的,明天策划说了我又有技能不能对昆虫类用,没关系,昆虫为5位,用一个int64来记录该项我觉得足够了,但使用string就有些亏了,我不信有策划能想出64个特性来。而实际工作中,策划只要为元素建筑物单位的免疫类型配置为3(1左移0或1左移1,这句话不能用语文的方式理解,而要用程序的方式),钢铁元素建筑19就可以;而我们有一个火球技能为元素魔法那么他的效果类别就是5,刀砍技能没有符合以上的特效他就是0。而在程序处理过程中,判断技能是否对目标有效的函数也比多条if好些很多,直接return (skill.effectType | guy.ImmuneType)>0; 就可以返回是否免疫了,如果是true就是免疫。如此一来原本可能扩展为64列的数据在1列中就概括完成了,事实上除了位运算外还有挺多其他的细节技巧可以运用,不妨开动自己的脑筋利用学到的知识好好想想,实际问题用实际的解决方法对付。

2,加权值好过百分比。

  在WoW流行了这么多年后的今天,受尽了WOW熏陶的很多策划,他们往往也看过不少WoW的数据库,因此他们对于掉落的理解仅仅限于XX的掉落率为yy%,然后设计掉落表的时候,简单的要求了我填写掉落百分比。好吧,这就引发了一个问题,你填写的百分比是干什么的呢?比如哥布林5%几率掉落斧头,12%几率掉落桔子?这个还好说,因为综合没有超过100%,如果哥布林还有80%的几率会掉落哥布林卡牌,这时候程序该怎么办呢?for循环遍历他所有会掉的东西,然后达到掉落概率就掉?策划会说可能会掉太多,那么while不掉do random next?策划又说填写的越前面的掉率越高不符合想法,当然是事也是如此。程序听完毛了,那好吧,你在增加一个不掉落率,然后保证掉落率总和+不掉落率=100%。事实上这是一个极为愚蠢的做法,但很典型,的确它能解决眼下的问题,当时当策划明天认为哥布林还会掉落头盔的时候就麻烦了,必须去修改已经填好的所有内容的概率。因此在这里我推荐大家还是采用加权的做法,至于掉落系统,各个游戏不太一样真不好说,但是加权的做法是针对每一系掉落的,比如我有一个怪,他一定会掉落列表中的某个东西,只是概率不同,这样一个系统,我只需要为每个掉落配一个加权:巧克力20,咖啡11,橘子122,饼干7,那么按照之前系统设计来看,他掉落巧克力的概率就是20/(20+11+122+7)=12.5%,当加入新的掉落香蕉40的时候,巧克力的掉率自然就降低到了10%,而不需要策划手动去更改。

3,利用Tag机制,让执行者有更多的预判断而不至于陷入死循环。

  现实开发中,我们经常会遇到填表的时候表连表,这是不可避免的,即使设计的再好的表,他也会至少挂向别的一个表,此时我们会遇到一些问题——我设计了软泥怪,它会掉落公主的靴子和猪头怪的獠牙,可是道具表还没有填,我也不知道这俩道具最后id会是多少。可是道具表里面某些道具使用后才能产生软泥怪……这样一来,事实上陷入了一个很常见的僵局,表A没完成弄不了表B,而没有表B,表A也高不了……

  这里我推荐大家一个做法就是Tag机制,对于每一个需要表表连接的地方,都采用一个tag模式而非直接id模式。什么是tag模式?简单的来说,还是上面这个软泥掉落道具的例子,我们可以为每个道具设定一个tag,这个tag是Array<String>的,也就是说他有多个字符串tag,策划可以为公主的靴子配置tag为"dropbyslim","soldbygoblin",而为猪头怪的獠牙配置tag为"dropbyslim","food003","chocolate"等,由于软泥怪的掉落套组中包含了"dropbyslim"这个标签,因此这两个道具都会成为他的掉落品,因为他们都含有这样的tag。

  Tag机制的可以说是缺陷的地方在于,如果你直接将tag概念引入到最后的游戏的逻辑程序里面,这会产生效率问题,因此最好还是在数据表变成程序可读的数据表的过程中,由转换表的程序来实现一个遍历转换,将他们变成id式连接。我们公司使用的工具中,我已经加入了这个逻辑,大家不妨推荐程序这么做,这样会很好的避免策划将时间浪费在改表上。

  以上是一些我在建立数据表时候的Little Trick,我觉得可以share给大家一起讨论下,看看优缺点,或者和你们现在的方式结合是否能产生更好的做法。但如果你只是一个新手,想学习如何建好表,想知道从哪儿学起,我的建议是,学着去修改单机游戏的存盘文件,那里有老一代游戏制作者对于数据结构的归纳心得。

8

主题

1801

帖子

3450

积分

论坛元老

Rank: 8Rank: 8

积分
3450
发表于 2013-5-30 10:43:58 | 显示全部楼层
好文顶一下

2

主题

14

帖子

102

积分

注册会员

Rank: 2

积分
102
发表于 2013-5-31 00:05:16 | 显示全部楼层
作为一个程序 得吐槽几点:
1.(我认为数据表结构应该由策划提供)
   如果策划不懂关系数据库的各项规则,那么我敢肯定的说,他设计的表绝对是混乱和存在大量数据冗余的。
2.表连表频繁
   这是无法避免,对于大型网游数据,就算你在精简,总是有各种各样的关系存在。我推荐在数据库中建模,利用数据库本身的强大约束功能,对各种关系进行管理,同时可以提供给策划基于数据库的程序工具,最终发布的时候把数据库中的数据导出游戏中所用的格式即可

3.对于各项公式
  其实程序只要提供合适的曲线编辑器,就能解决大部分的问题

4.由于表是程序建立的,程序说了,加一列“可否对建筑有效”,布尔型
   如果有那个程序这样做了 ,只能说明他在偷懒,一个正常的程序是不会干出这种事情来的

5.后面的段落你想多了,你在用策划的思想去思考程序的做法,很可笑的

13

主题

405

帖子

1034

积分

金牌会员

Rank: 6Rank: 6

积分
1034
发表于 2013-5-31 00:30:29 | 显示全部楼层
同意由策划建表

顺带回楼上。那种程序员不少。少部分是初心,大部分是偷懒,更大部分是前面的人或者项目都这么做,要改已经很累了,如果这类改动不多的话,那么‘我’也偷个懒

98

主题

784

帖子

4495

积分

版主

Rank: 7Rank: 7Rank: 7

积分
4495
 楼主| 发表于 2013-5-31 00:49:21 | 显示全部楼层
SUN_OGRE 发表于 2013-5-31 00:05
作为一个程序 得吐槽几点:
1.(我认为数据表结构应该由策划提供)
   如果策划不懂关系数据库的各项规则, ...

其实我觉得你之所有这样的槽点,是因为……怎么说呢?因为你没有把开发游戏当作Teamwork。
1,数据表的建立是由策划来的,但并非由该策划自己说了算,并且也不是说他在迷茫的时候得不到技术支持。但事从你的说法中,我更多的看到的是——把数据表和数据库的内容混淆了。
2,我觉得这是一个不错的idea,但是之所以不用数据库做这样的事情有很多原因,如果它真的如你预期的工作这么好,很多团队的程序员就不会把delphi当成数据库软件来使用了。
3,excel的功能已经够强大了,虽然我们团队的程序策划都是很多大(无论是名声还是技术)项目的主程序出身,但我们并没有自信做一个超越excel的东西。这些功能我用excel都能做到,然而excel比我玩的好的策划,我相信是绝大多数的。
4,你的说法看起来非常有道理,但是那只是外行眼里,任何一个有项目经验的人都知道,这种半途的需求往往都是在已经有了至少几十行数据之后产生的,如果你肆意的修改表的数据类型,这会造成不必要的工作以及不应发生的错误,因此老牌程序员都会提出新增一列的做法,至少excel在填表中,空格子代表了缺省值这很好,从项目开发的角度上来说,尤其是中期的时候数据已经有成千上万条的时候,也只能如此,这不能怪策划初期设计问题,因为在项目的不断进行中,我们总是会不断面临新的问题和新的想法,这是经验,也是这种创意型行业独有的特色,因此为了解决这样的矛盾发生去寻找一些方法是有必要的。
5,策划的思想去思考程序的做法,我不太明白你说的程序的做法究竟是怎样的,诚然程序的进步是非常快的,我不敢肯定自己总是跟得上时代,就像最近我们在用haxe3写手机游戏,先模拟了一套cocos2dx所有的东西之后,总结进化了模式,也许是因为这样的做法和传统的程序员不太一样了吧?可是我们这里不太在乎这个,我们在乎的是,东西能做出来,我们团队的分工是:策划负责整个游戏的逻辑代码,而程序负责底层的优化。

0

主题

45

帖子

122

积分

注册会员

Rank: 2

积分
122
发表于 2013-5-31 10:28:20 | 显示全部楼层
我觉得这里提出的3点都有好的方面,但也有一些不足和矛盾的地方,当然以下是个人观点和经验,可能与作者经历的开发环境不同导致
首先,拿经验值曲线说事这不太合理,可以很明白的说,任何游戏的经验值表,是肯定有表的,尤其是那些做的好的游戏,特别是初期,玩家升级的经验值绝对不可能用任何一个数学公式来取近似值。“2个都接近于公式y=power(a,b),区别在于前者的b要大于1而尽可能小于1.5,后者只要大胆的大于等于2就好了”,在这里,看似很简单的公式,但是你准备把这个公式给程序说,“诺,这个公式直接写死在程序里”?显然不可能,最后给程序的必定是已经推导出来的数值结果列表,程序只要获得“lv”、“exp”字段就可以了,而如果给公式,则需要设置更多的内部参数以保证分段函数的取值域,用不同的定义来区分“前者”与“后者”,真正游戏中经验值分段会更加零散和不规则以配合游戏进度,不是么?
第二个加权值应该没什么问题,我认为应该绝大多数游戏都是这么做的,先设立掉落组,设定掉落组概率,然后掉落组内部则使用加权值进行比例分配
至于第三个,抱歉,我觉得tag反而麻烦,没有id那么直接明确的逻辑关系。“表A没完成弄不了表B,而没有表B,表A也搞不了”我觉得这本身就是建表没建好,没有将表的功能明确划分而导致数据相互嵌套。另外,任何表内的mainId应该都不是顺序的(不是指编号连续性),而是分段分类的,例如A道具是消耗品,可能以1000作为开头,而B道具是耐用品,用2000开头,C道具是任务道具,从3000开始,这样就不会存在“不知道这俩道具最后id会是多少"这样的事情,因为很简单,分配给它们未使用的合法id就行,哪怕策划表中这个道具只有id和道具名,没有详细数据,那么也可以认为这个道具已经设立好了,仅仅是数据没完善而已,接着配其他表呗,等其他数据齐备了再回来补完数据就行。反正你没有上传进行转换的策划表,空着一些数据也是没影响的。

另外回到第一点,数据表应该是由策划提供的,但的确不是策划规定,通常我都是会建立一份预案表,给程序,向程序讲解这张表的数值构成,哪个字段是什么用的,哪里需要读取,和其他表的逻辑关系等等,程序会反馈说,这字段是否合理或者这字段与另一个字段是否可以合并之类的问题,通常只要程序能说出理由或者2个或以上字段的确没有单独存在的必要,则会进行并项以减少output的输出内容,一张数据表是否繁杂,最后还是以output数据作为判断依据的。

2

主题

14

帖子

102

积分

注册会员

Rank: 2

积分
102
发表于 2013-5-31 11:11:40 | 显示全部楼层
如果我认为游戏开发不需要团队合作 就不会出来讨论这些东西。就是因为团队合作,团队中的每个角色应该优劣互补,在数据的抽象化设计方面,我不认为策划比程序更有优势,策划的优势在于用户需求和内容设计,而不是具体实现。
   1.不是我把数据库和数据表混为一谈,而是你不理解数据库的知识。对于一张表是否设计的合理科学,数据库这门学科中有专门的知识和评价体系去验证,这比纯经验设计具有更可靠的保证
  2.对于中小公司来说,没有时间和精力去做通用化的工具链,但是如果做了,那么对以后的项目都是一个很好的技术积累。
  3.我不否认excel的强大和满足日常项目的开发,其实上面我没说,我真正想说的是如果能懂matlab等专业的数学建模工具,在数值这一块,策划更能够得心应手
  4.我还是那句话,程序在这方面更有优势
  5.没什么不一样,只不过你们所做的只是脚本化编程,脚本化编程是趋势,能够让程序专注于系统与框架设计,策划专注于内容设计。但是话说回来,能够写逻辑不代表你理解程序的思考方式,对于程序更重要的抽象化设计

7

主题

776

帖子

913

积分

高级会员

Rank: 4

积分
913
发表于 2013-5-31 11:31:14 | 显示全部楼层
本帖最后由 turwater 于 2013-5-31 11:34 编辑

1)表建的不好是经验和智商问题,没什么大惊小怪。
2)还有表是什么样子对高级程序来说完全可以和游戏数据读的是最终结构没关系。
3)真看重配置这块的管理所谓teamwork,表就不是谁都可以建的了,有专业人员把关。
4)复杂的表和简单的表只是习惯问题,明确告诉楼主,再复杂的表对亲自建立他的人来说都是用的顺手很通的东西。好策划根本不介意这些表恶性还是不恶性。因为EXCEL水平完全拟补这块的狗血操蛋事,(现在谁直接在配置表上做终极操作,是个人都有复合自己习惯的草稿运算表)。但不是说这块对新人不重要。
5)数据结构很多程序都学不好,其实也不用太指望谁能一下就建好,任何项目最后时候你发现很多东西都可以重构。楼主是不是去撞墙?
6)在成本可以预估的情况下。能不用公式的地方最好别用公式,这和建表没什么关系。但和游戏关系大多了。

21

主题

3926

帖子

5142

积分

论坛元老

索尼已经断气了.jpg

Rank: 8Rank: 8

积分
5142
发表于 2013-5-31 11:32:56 | 显示全部楼层
难得一见的好文

不过未来的趋势是高度集成的编辑器

纯粹的表格更多是用于规划和前期设计

表格尽量隐藏在后台,只有核心人员管理就ok了

21

主题

3926

帖子

5142

积分

论坛元老

索尼已经断气了.jpg

Rank: 8Rank: 8

积分
5142
发表于 2013-5-31 11:34:01 | 显示全部楼层
这种帖子基本看不到那几个中二空想家

可喜可贺

点评

因为他们看不懂,不知道怎么插嘴  发表于 2013-6-4 14:33
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-8-26 20:25

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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