找回密码
 立即注册
查看: 673|回复: 20

如何在游戏开发领域深入发展?

[复制链接]
发表于 2021-10-16 12:45 | 显示全部楼层 |阅读模式
本题已加入知乎圆桌 >>游戏的奥秘 I 游戏制作者在路上,更多「游戏设计」讨论欢迎关注。
本人是在开发u3d,不算精通,也算是有一些基础。现在对以后的发展有一些迷茫了,因为找不到自己的定位,想深入到某一方面,比如深入游戏AI或者shader什么的。我以前的老师说,进入核心团队需要c++基础,但是我并不想深入到引擎开发,而想在应用层之上进行开发。但是发现应用层之上好像没有什么领域可以深入的,shader是不太想走这方面,而游戏AI技术好像比较成熟,怕深入的话可以研究和创造的地方不多,中国的游戏也不太在意AI。
       上面都是我的一些感觉,很可能不对,比如对AI的看法,就想知道游戏开发领域里面应用层之上什么方面可以深入有发展空间的,并且最好是与引擎关系不大的,比如什么算法,架构思想之类的。
       现在对比做游戏引擎的,好像很多人都觉得做游戏的技术要差一等,难道在做游戏上没有有难度可以深入的地方了吗?一定要深入引擎层面才可以有自己的核心竞争力吗?        经答主提醒的确还有服务器部分。 另外又查了查资料,游戏AI也有可以深入的地方,还没进入瓶颈期,游戏AI开发也可以形成核心能力,是不是这样呢?
       各位误解了,我并不是对什么都不感兴趣,只是想找到最合适的,其实兴趣主要是在AI方面,但是见识太少了,问这个问题就是担心会出现这个领域不需要太深的知识的情况,如果知道这个方向有深度的话,就好专研这方面的资料然后给自己定位。
       有答主说我不愿意学C++,不愿意做基础,可能是我没有描述清楚,不是不愿意学C++(其实也有一些C++基础),只是不愿意开发底层,不要误解,底层可不是基础哦,底层引擎是很难的,和做游戏毕竟有交集但是还是不同的流程,只是兴趣点不在底层而已,兴趣在一些应用层的抽象不依赖于实现平台的技术上,比如AI算法之类的,毕竟我只是想做菜,难道非要学会做锅才有核心竞争力吗?当然这只是我的看法,见识太有限,还请大家指出来。
发表于 2021-10-16 12:52 | 显示全部楼层
除去各种底层技术值得专研外,请不要忽视了一个重要的东西 GamePlay,你是游戏程序员,不是完成需求的机器。

给你讲讲我比较佩服的一为朋友的经历,国内金牌制作人,名字就不提了。他本科学的平面设计,计算机是自己中学自学的,从小就爱开发游戏,但是他的关注点是 “如何创造有意思的游戏”,单纯说技术,他自己都承认,自己的技术很烂,但是我每每看到他用各种“很烂”的技术开发出来的东西都会被吓一大跳:

机器人大战



这是一个他学生时候写的人工智能竞赛游戏,有多种机器人类型可供购买。为渴望挑战人工智能及喜爱收藏的人们提供了新的交流方式。同时机器人品种的可扩展性带来了很多乐趣,虽说该游戏在入手方面有点难度,但是在 PCHome 上一度登上游戏类下载排行榜。



他花了两个月用 TurboC 独立开发出来的,今天看起来效果一般,但你今天别用U3D,别用cocos,去 turboc下实现试试,何况抛开图形,就游戏核心玩法的复杂度,放在今天熟练的程序员也要开发很久,可人家还是学生时候做的。当时引起了很多人群的关注,他们学校里同学们用这个作品组织了一场校际比赛,结果引起了极大的反响,虽然在一开始没有多少人主动参加这次比赛,但是比赛的那天有很多同学被精彩的对抗所吸引,几乎所有的观众都在自己的座位上看完了整个比赛。他说:“现在想想那时候的情景都能让我兴奋不已。”

多人乱斗



他大学时候继续使用落后的 TurboC 开发的游戏,没学习过 3D 但是美术学过透视作图,相似三角形计算远小进大,然后用伪3D 的模式开发出来。游戏中既有远程射杀武器,又有近距离搏斗技巧,还有夸张的碰撞效果,还可以躲避敌人的视线来实现隐秘行动,这个游戏手感很爽快,可玩度很高,但是图像的确太糟糕了,于是他又做了一款改进版:



加入了简单的多边形绘制,镜头自由移动,不知道zbuf,但是他知道远处东西先画近处东西后画的画家算法,没学习过3D,但是他最厉害的就是 “创造性” 三个字上:能充分发挥现有技术,创造出让人眼前一亮的效果来,效果上有所提高的同时加入了更多武器,潜入玩法,敌人有视线范围,还有比较拟人的AI,你要注意避让,还可以从后面上去偷袭,当然,如果技术够好,被敌人发现了也不怕,一场激烈的枪战而已,可以利用各种武器制胜,还要充分利用地形,比如射击汽油桶会爆炸,普通墙壁可以躲避。我玩了一下,还真有点合金装备的意思呀。

我当时问他,为什么不再 Windows 下开发,更简单了,他说他没有学习过 Windows 程序设计,主要是把时间花在实现游戏各种乐趣上了,Windows 下程序设计他也看过,但是 Dx, OGL好多东西新学费时间,没个一年多他弄不出来,不过 DOS 下内存少载入的东西多了就退出,我说我给你写个简单的框架吧,写起来也挺简单的,他试用了一下,觉得不好用,还是习惯 DOS 编程,后来我给他用 Watcom C++写了一套库,满足他 DOS 下继续开发游戏的想法,解决了图像弱智,没有音乐,没有音效,性能上不去等问题,他用着很爽,又用它开发了好几个游戏,他虽然不擅长钻研底层技术,但是确实能够充分的将他会的东西发挥的比较淋漓尽致的人。

即时战略



这还是他学生时候开发的即时战略,虽然比起商业即时战略弱智很多,但还是有很多经过他自己精心设计的部分,如:支持双人对战;机器人会变形,幻影战车(速度快,激光导弹难以瞄准),士兵由农民进入兵营训练而成,弹药补给,自己组配士兵装备以及战车配置等。

他经常羡慕我知道各种底层技术,但是我面对他的一款款作品,却自愧不如,他是能够将现有技术充分发挥作用的人。计算机的技术再怎么发展终归都是有限的,而人的创造却是无限的,以无限的创造衡量有限的技术,以无法以为有法,以有限而为无限。即便是只使用 DOS 下几种弱智绘图方式,他手底下也能点石成金,变成一个效果上超出大家预期,充满乐趣的游戏。

比如他读中学才学习电脑的时候,接触的是 FoxBase 这个财务软件,他无师自通的使用 FoxBase 开发出一个 RPG 游戏来:


他高中时候 FoxBase 下的 RPG 游戏,玩起来别有一番风味。对于他而言,技术是达到目的的手段,发掘快乐的本源,完善游戏各种细节,流畅的手感,有张有弛的节奏,这一切才是 GamePlay的核心。

2003年时我闲着无聊,帮他优化了一款动作游戏,《Hurricane2》,主要是他开发的,一款比较爽快的动作游戏,虽然图形一般,但他后面又修修补补加了很多有趣的元素,这是我硬盘上至今保存的比较完整的他的作品了:
http://www.skywind.me/mw/images/a/ac/Hurricane2.7z

这是他学生时候为了做游戏,自学美术的一些手稿:



他当年毕业后以程序的身份去到盛大,因为工作中出色的表现,几年后便升为产品经理,为盛大开发了两款月入六百万级别的 RPG 游戏,不算太高,但是当时的端游,失败率那么高的情况下,第一次做产品经理,没赔也算挺不错了。

工作至余,他继续保持学习和提高,除了在电影,美术和动画方面学习各种知识外,他终于学习了 C#,正式步入游戏圈子自然结识到了更多朋友,其中一位志同道合的伙伴为他开发了一套支持卡通渲染的 XNA 图形引擎,于是他开始了独立的 C#游戏开发之路,因为小时候学习武术他一直希望能够做出一款武打游戏来,于是自己学习3DMax,自己学习骨骼动画,学习展UV,学习蒙皮,这些技巧性的不算难,难的是游戏里几个主角全是他自己画出来的。



这就是当年他开发的 DOS下《Hurricane2》的高级版本,沿袭 前作爽快的节奏感和简单的操作,最牛的是几个主角传神的武打动作都是他一个人一点点调出来的,超过很多专业调动作的美术:


终于有机会将他动作游戏的想法付诸实践了。不过这是他业余开发的单机游戏,并不是什么网游,XBox Live上却卖了好几万分,还在国际上得了个什么奖。

他工作上的取得的成绩我就不说了,上面说的都是他在没有任何人要求他的情况下,业余搞出来的东西。而且业务,开发,策划,美术,音乐,各个环节他都有涉猎。

程序也是半个策划,直接面向玩家的人,即便写的再明白的策划案,不可能写到像素级别交给你,如何更好的实现各种效果,如何让游戏变得更有趣,如何充分发挥现有技术的优势,是值得到家深刻考虑的问题,游戏本来就是艺术和技术的合体,GamePlay 做得好,游戏是有灵性的,是有生命力的,而只知道呆板实现的人,同样的东西,做出来的效果却是一塘死水,毫无生机。

之前公司在开发一款模仿《DiabloII》的游戏,虽然碰到很多坑,但是开发者的态度令我敬佩,他们为了实现 DiabloII里面金币掉落的效果,试了很多次,抛物线,不像;加大重力(两倍G)有点象但是还缺点什么,找半天就是找不到,后来他们把 D2的录像拿过来一帧帧的播放,一帧帧的分析,金币到底是怎么掉落的,最后才发现,D2的金币掉落是和物理知识反着来的,首先金币加速上升,然后悬空停顿,最后重重的砸到地下,按照这个过程配合恰如其分的音效终于实现了D2的效果,让金钱掉落的过程充满快感。对于这个效果,策划案上就只有几个字:“模仿D2钱币掉落”,而美术也就给了几个金钱状态的图片,后来又听他们说了如何做鼠标的手感,飞行武器如何判定,地图如何自动生成等。

听完后我想,一个小小的金币掉落,他们都能花这么长时间,不管游戏最终如何,但精品游戏还真得这么一步步的扣出来。真正做得好的游戏,都是玩家觉得好玩,但是却又说不出来好玩在哪里,大量的精心制作的细节支撑起一款款成功的 3A 游戏。

游戏对于程序员而言,有蛮多值得挑战的东西,GamePlay就是其中重要的一环,如果你想突破自己,请始终不要忘记,你是做游戏的,不是一个工具,更不是一架只会完成需求的机器。游戏本来就是快乐的,如果开发者本身没有任何感情去做他,本身都不快乐,那你怎么能让玩家快乐呢?

如果开发者丝毫不考虑玩家感受,没有产品意识,只知道实现策划的功能,象一架机器一样麻木的完成各种需求,那么这样永远得不到成长。

现在游戏挣钱了,很多人进来开发游戏,更多的是冲着钱字进来的,比起早年开发游戏的人来说,更少了一份 “纯粹” 多了几分 “浮躁”。我面试时也碰到很多年轻人声称自己 “喜欢游戏”,可我想问一句,你说你喜欢游戏,你为 “喜欢” 二字付出过什么?对比起我上面说的这位朋友几十年不停息的努力,你这个喜欢又算得了什么?

现在我也不想谈 “情怀” 两个字,这两个字已经被说烂了,我说个更烂的 “梦想” 两个字,请问你作为这个行业的新人而言,你的梦想是什么?你为它付出了多少?

本帖子中包含更多资源

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

×
发表于 2021-10-16 13:01 | 显示全部楼层
谢邀。

人各有志,当今的游戏开发早就不是像十年之前那样都得从头开始搞起,将来分工只会越来越明确。如果你的目标不是在3A制作组做一个螺丝钉,而是定位在中小团队,实在不想搞引擎这部分的开发也没什么可纠结的。

但是你可以不了解引擎的各种实现细节,基本的性能调优还是得弄明白,这个引擎哪些地方会有坑,如何改进和避免必须清楚。当然这些归根到底还是经验问题,别人说再多不如你自己实际去踩一下。

除了引擎和gameplay,有一点很重要也很少有人提到,就是工作流的整合

游戏开发不仅仅是程序员的工作,美术、策划都会参与到这个过程当中。如何有效地创建/整合高效的工具链,提高团队中每一个人的开发效率?这是需要思考的问题,而且这个问题的重要性不亚于引擎本身。

3A团队和中小团队的玩法是不同的,前者从引擎底层开始到游戏业务逻辑做一条龙开发(比如说小岛秀夫做了六年的Fox Engine),后者侧重于在某个成熟引擎的基础上做工具链的开发和整合。对于中小团队,你应用层的基础件做得越扎实,工具链越完善,开发效率就越高,迭代得也越快,那么你永远都能跑在别人的前面。

这个就是最好的例子:



从第一代推出到现在,短短一年时间里竟然出了四代,收入2000万美金,而且开发者只有一个人。虽然有骗钱的嫌疑,但这也充分证明了工具链对于开发流程的重要性。如果开发速度不够快,等过个一年半载再出第二代,好不容易聚集起的人气恐怕已经消散了,山寨产品也早已烂大街。

另一个例子:



光一个对话树的插件,就有这么多团队在开发,有的还卖很贵。为啥?欧美RPG游戏里面庞大复杂的对话树就是核心玩法之一。如果你的RPG在开发时能用最快的速度搞定这个问题,其价值是不可估量的。

第三个例子:



虽然这引擎功能限制很大,脚本编辑器也是一坨屎,但还是有相当多游戏(包括倍受好评的To The Moon)用这个工具做了出来。为啥?难道这些开发者都不知道这些问题?显然不是。仅仅是因为它功能够用,方便,用起来顺手。

作为一个身处中小游戏团队的开发者,你没必要也没有这个资源像3A团队一样所有事情都亲力亲为。做好工具链的整合,提高整个团队的工作效率,就是核心竞争力。

本帖子中包含更多资源

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

×
发表于 2021-10-16 13:10 | 显示全部楼层
其实高层和底层并没有相距那么远。

以游戏 AI 来说,
    为了实现各种需求,我们需要使用各种算法。由于游戏的实时性,这些算法需要高性能的实现。
    为了高性能,在 Unity (或其他引擎上)中可能会使用原生方式实现。游戏业界中,原生实现最常用的是 C++,有时候会加上汇编。为了进一步提升性能,需要考虑多线程、缓存、SIMD 指令集
注意到,上面并不是说,越底层就越深入。而是在理论与实践上都可以深入挖掘。

我觉得题主在决定深入之前,首先广度上要足够,清楚游戏 AI 和其他方面的具体程况,再下判断。
发表于 2021-10-16 13:19 | 显示全部楼层
“AI也很成熟了, 没什么研究的了”, 这话说的就像:登月都已经实现了, 没什么技术含量啊,我就不登月了, 你们玩吧。

你先搞个像样的试试?
或者, 你先写个普通的RPG服务端试试, 业务逻辑就不要实现了, 没策划给你提需求, 还是先实现个大概的吧, 普通已有RPG里用到的AI, 天气, 任务, 碰撞,最普遍的地图格子什么的。

要搞其实还有事搞, 其实其他行业用lz这么眼光看过去, 也会是这种感觉:
web开发还有什么好研究的? 就特么http来去, cache一下, 下面redis, mongodb之类的,然后就等着请求过来, 再深入不就是优化优化么。

移动app有什么搞的?已经很成熟了, 就特么把UI拼起来,事件触发一下, 再不行就直接h5,看着淘宝那种app抄一下, 感觉也很成熟了。

没有故意喷的意思哈, 只是lz这样说, 会让已经在做游戏的人, 觉得自己好渣。
发表于 2021-10-16 13:23 | 显示全部楼层
其实你是想学习 可迁移的gameplay相关技术 ,内容很多,我只能推荐点好书
双击再看,养成习惯
荐书

AI

一、


本书的作者都是游戏人工智能的专家,在游戏行业摸爬滚打多年,其观点和技术均在自身产品中进行过验证。讨论了通用智能、体系架构、运动与寻路、战略与战术、agent 意识与知识表征、竞速以及其他领域的游戏AI技术。部分内容提供了源码。
二、


介绍有限状态机、模糊逻辑和神经网络之类的技术,并给出源代码。从基本的追赶、躲避、基于模式的运动和聚集等游戏行为到玩家行为预测。包括了确定性和非确定性AI技术的混合。
三、


介绍在游戏开发中怎样应用遗传算法和人工神经网络来创建人工智能
四、


通过一个足球游戏来介绍状态机的实现。介绍目标驱动的智能体的实现、触发器与模糊逻辑在游戏中的运用。讨论图在游戏中的用途及各种不同的图搜索算法。还专门用一章讨论了游戏中的路径规划如何完成。顺带讲了游戏脚本语言的优点,并以lua脚本语言为例进行了说明。
算法



内容几乎兼容所有游戏,无论这些游戏采用何种风格、开发语言和框架。
脱离特定平台来讲解2D和3D图形学、物理、人工智能、摄像机等游戏行业中常用的算法与技术。
作者详细分析了两款完整的游戏,展现了前面章节讲到的很多技术和算法。
游戏综合

一、


被作者Jeannie Novak的背景惊到了,以下是背景介绍:
资深游戏设计师和游戏开发培训师
网络艺术学院”游戏艺术和设计”与”媒体艺术和动画”的网络课程总监
“Game Development Essentials”系列丛书第一作者和丛书编辑
Novy Unlimited联合创始人及 Kaleidospace公司首席执行官
参与开发”Second Life”等多款经典游戏
曾在多所高等院校担任游戏讲师和课程开发专家
与他人合著《PIay the Game:The Parent's Guide to Video Games》及《Creating Internet Entertainment》
任职国际游戏开发者协会洛杉矶分会副主席
迈阿密动画节 (ANIMIAMI)游戏大会主席
游戏教育峰会咨询委员会委员
入选由《MicroTimes》杂志评选的100位最有影响力的技术人物
二、


既适合游戏开发者阅读,也适合重度游戏玩家阅读。从游戏设计者和玩家两个角度出发,以大量游戏为例。从玩家角色、敌人角色、关卡设计、碰撞检测、镜头这5个角度来探讨如何让3D游戏更加有趣
三、


细致讲解了游戏开发需要用到的各种编程模式,提供了丰富的示例
内容分为3大部分。第一部分介绍了基础知识和框架;第二部分深入探索设计模式,讲解设计模式与游戏开发之间的关系;第三部分介绍了13种有用的游戏设计模式。
----------------------------------------------------------------------------------------------------
这些书籍资料我整理了一下


链接:https://pan.baidu.com/s/1C-9TE9ES9xrySqW7PfpjyQ  提取码:cqmd
架构思想

我一直没找到架构方面的好书(哪位大大有好书求推荐),只能自己上网,下面是对ECS架构的一点总结
对于很多人来说,ECS只是一个可以提升性能的架构,但是我觉得ECS更强大的地方在于可以降低代码复杂度。
在游戏项目开发的过程中,一般会使用OOP的设计方式让GameObject处理自身的业务,然后框架去管理GameObject的集合。但是使用OOP的思想进行框架设计的难点在于一开始就要构建出一个清晰类层次结构。而且在开发过程中需要改动类层次结构的可能性非常大,越到开发后期对类层次结构的改动就会越困难。
经过一段时间的开发,总会在某个时间点开始引入多重继承。实现一个又可工作、又易理解、又易维护的多重继承类层次结构的难度通常超过其得益。因此多数游戏工作室禁止或严格限制在类层次结构中使用多重继承。若非要使用多重继承,要求一个类只能多重继承一些 简单且无父类的类(min-in class),例如Shape和Animator。


也就是说在大型游戏项目中,OOP并不适用于框架设计。但是也不用完全抛弃OOP,只是在很大程度上,代码中的类不再具体地对应现实世界中的具体物件,ECS中类的语义变得更加抽象了。
ECS有一个很重要的思想:数据都放在一边,需要的时候就去用,不需要的时候不要动。ECS 的本质就是数据和操作分离。传统OOP思想常常会面临一种情况,A打了B,那么到底是A主动打了B还是B被A打了,这个函数该放在哪里。但是ECS不用纠结这个问题,数据存放到Component种,逻辑直接由System接管。借着这个思想,我们可以大幅度减少函数调用的层次,进而缩短数据流传递的深度。
基本概念

Entity由多个Component组成,Component由数据组成,System由逻辑组成。
Component(组件)

Component是数据的集合,只有变量,没有函数,但可以有getter和setter函数。Component之间不可以直接通信
struct Component{
        //子类将会有大量变量,以供System利用
}Entity(实体)

Entity用来代表游戏世界中任意类型的游戏对象,宏观上Entity是一个Component实例的集合,且拥有一个全局唯一的EntityID,用于标识Entity本身。
class Entity{
        Int32 ID;
        List<Component> components;
        //通过观察者模式将自己注册到System可以提升System遍历的速度,因为只需要遍历已经注册的entity
}Entity需要遵循立即创建和延迟销毁原则,销毁放在帧末执行。因为可能会出现这样的情况:systemA提出要在entityA所在位置创建一个特效,然后systemB认为需要销毁entityA。如果systemB直接销毁了entityA,那么稍后FxSystem就会拿不到entityA的位置导致特效播放失败(你可能会问为什么不直接把entityA的位置记录下来,这样就不会有问题了。这里只是简单举个例子,不要太深究(●''●))。理想的表现效果应该是,播放特效后消失。
System(系统)

System用来制定游戏的运行规则,只有函数,没有变量。System之间执行顺序需要严格制定。System之间不可以直接通信
一个 System只关心某一个固定的Component组合,这个组合集合称为tuple。
各个System的Update顺序要根据具体情况设置好,System在Update时都会遍历所有的Entity,如果一个Entity拥有该System的tuple中指定的所有Component实例,则对该Entity进行处理。
class System{
        public abstract void Update();
}

class ASystem:System{
        Tuple tuple;

        public override void Update(){
                for(Entity entity in World.entitys){
                        if(entity.components中有tuple指定的所有Component实例){
                                //do something for Components
                        }
                }
        }
}一个Component会被不同System区别对待,因为每个System用到的数据可能只有其中一部分,且不一定相同。
World(世界)

World代表整个游戏世界,游戏会视情况来创建一个或两个World。通常情况下只有一个,但是守望先锋为了做死亡回放,有两个World,分别是liveGame和replyGame。World下面会包含所有的System实例和Entity实例。
class World{
    List<System> systems;                   //所有System
    dictionary<Int32, Entity> entitys;      //所有Entity,Int32是Entity.ID

    //由引擎帧循环驱动
    void Update(){
        for(System sys in systems)
            sys.Update();
    }
}由ECS架构出来的游戏世界就像是一个数据库表,每个Entity对应一行,每个Component对应一列,打了代表Entity拥有Component。
Component1Component2...ComponentN
EntityId1
EntityId2
...
EntityIdN
单例Component

在定义一个Component时最好先搞清楚它的数据是System数据还是Entity数据。如果是System的数据,一般设计成单例Component。例如存放玩家键盘输入的 Component ,全局只需要一个,很多 System 都需要去读这个唯一的 Component 中的数据。单例Component顾名思义就是只有一个实例的Component,它只能用来存储某些System状态。单例Component在整个架构中的占比通常会很高,据说在守望先锋中占比高达40%。其实换一个角度来看,单例Component可以看成是只有一个Component的匿名Entity单例,但可以通过GetSingletonIns接口来直接访问,而不用通过EntityID。
例子

守望先锋种有一个根据输入状态来决定是不是要把长期不产生输入的对象踢下线的AFKSystem,该System需要对象同时具备连接Component、输入Component等,然后AFKSystem遍历所有符合要求的对象,根据最近输入事件产生的时间,把长期没有输入事件的对象通知下线。
设计需要遵循的原则

    设计并不是从Entity开始的,而是应该从System抽象出Component,最后组装到Entity中。
2. 设计的过程中尽量确保每个System都依赖很多Component去运行,也就是说System和Component并不是一对一的关系,而是一对多的关系。所以xxxCOM不一定有xxxSys,xxxSys不一定有xxxCOM。
    System和Component的划分很难在一开始就确定好,一般都是在实现的过程中看情况一步一步地去划分System和Component。而且最终划分出来的System和Component一般都是比较抽象的,也就是说通常不会对应显示世界中的具体物件,可以参考下图守望先锋System和Component划分的例子。


3. System尽量不改变Component的数据。
    可以读数据完成的功能就不要写数据来完成。因为写数据会影响到使用了这些数据的模块,如果对于其它模块不熟悉的话,就会产生Bug。如果只是读数据来增加功能的话,即使出Bug也只局限于新功能中,而不会影响其它模块。这样容易管理复杂度,而且给并行处理留下了优化空间。
使用心得

我在一个游戏demo里尝试使用ECS去进行设计,最大的感受是所有游戏逻辑都变得那么的合理,应对改动、扩展也变得那么的轻松。加班变少了,也不再焦虑。在开始使用ECS来架构业务层之前,我对ECS还是存有一丝疑虑的。担心会不会因为规矩太多了,导致有些功能写不出来。中途也确实因为ECS的种种规矩,导致有些功能不好写出来,需要用到一些奇技淫巧,剑走偏锋。但这些技术最终造就了一个可持续维护的、解耦合的、简洁易读的代码系统。据说守望团队在将整个游戏转成ECS之前也不确定ECS是不是真的好使。现在他们说ECS可以管理快速增长的代码复杂性,也是事后诸葛亮。
引擎层的System比较好定义,因为引擎相关层级划分比较明确。但是游戏业务逻辑层可能会出现各种奇奇怪怪的System,因为业务层的需求千变万化,有时没有办法划分出一个对应具体业务的System。例如我曾经在业务层定义过DamageHitSystem、PointForceSys。
推迟技术:不是非常必要马上执行的内容可以推迟到合适的时再执行,这样可以将副作用集中到一处,易于做优化。例如游戏可能会在某个瞬间产生大量的贴花,利用延迟技术可以将这些需要产生的贴花数据保存下来,稍后可以将部分重叠的贴花删除,再依据性能情况分到多个帧中去创建,可以有效平滑性能毛刺。
如果不知道该如何去划分System,而导致System之间一定要相互通信才能完成功能,可以通过将数据放在中的一个队列里延迟处理。比如SystemA在执行Update的时候,需要执行SystemB中的逻辑。但是这个时候还没轮到SystemB执行Update,只能先将需要执行的内容保存到一个地方。但是System本身又没有数据,所以SystemA只好将需要执行的内容保存到单例Component中的一个队列里,等轮到SystemB行Update的时候再从队列里拿出数据来执行逻辑。
但是System之间通过单例Component有个缺点。如果向单例Component中添加太多需要延迟处理的数据,一旦出现bug就不好查了。因为这类数据是一段时间之前添加进来的,到后面才出问题的话,不好定位是何处、何时、基于什么情况添加进来的。解决方案是给每一条需要延迟处理的数据加上调用堆栈信息、时间戳、一个用于描述为什么添加进来的字符串。
各个System都用到的公共函数可以定义在全局,也可以作为对应System的静态函数,这类函数叫做Utility函数。Utility函数涉及的Component最好尽可能少,不然需要作为参数传进函数Component会很多,导致函数调用不太雅观。Utility函数最好是无副作用的纯函数,不对Component的数据做任何写操作,只读取数据,最后返回计算结果。要改Component的数据的话,也要交给System来改。
函数调用堆栈的层次变浅了,因为逻辑被摊开到各个System,而System之间又禁止直接访问。代码变得扁平化,扁平化意味的函数封装少了,所以阅读、修改、扩展也很轻松。
如果可以把整个游戏世界都抽象成数据,存档/读档功能的实现也变得容易了。存档时只需要将所有Component数据保存下来,读档时只需要将所有Component数据加载进来,然后System照常运行。想想就觉得强大,这就是DOP的魅力。
优点

模式简单
结构清晰
通过组合高度复用。用组合代替继承,可以像拼积木一样将任意Component组装到任意Entity中。
扩展性强。Component和System可以随意增删。因为Component之间不可以直接访问,System之间也不可以直接访问,也就是说Component之间不存在耦合,System之间也不存在耦合。System和Component在设计原则上也不存在耦合。对于System来说,Component只是放在一边的数据,Component提供的数据足够就update,数据不够就不update。所以随时增删任意Component和System都不会导致游戏崩溃报错。
天然与DOP(data-oriented processing)亲和。数据都被统一存放到各种各样的Component中,System直接对这些数据进行处理。函数调用堆栈深度大幅度降低,流程被弱化。
易优化性能。因为数据都被统一存放到Component中,所以如果能够在内存中以合理的方式将所有Component聚合到连续的内存中,这样可以大幅度提升cpu cache命中率。cpu cache命中良好的情况下,Entity的遍历速度可以提升50倍,游戏对象越多,性能提升越明显。ECS的这项特性给大部分人留下了深刻印象,但是大部分人也认为这就是ECS的全部。我觉得可能是被Unity的官方演示带歪的。
易实现多线程。由于System之间不可以直接访问,已经完全解耦,所以理论上可以为每个System分配一个线程来运行。需要注意的是,部分System的执行顺序需要严格制定,为这部分System分配线程时需要注意一下执行先后顺序。
缺点

在充满限制的情况下写代码,有时速度会慢一些。但是习惯之后,后期开发速度会越来越快。
优化

一个entity就是一个ID,所有组成这个entity的component将会被这个ID给标记。因为不用创建entity类,可以降低内存的消耗。如果通过以下方式来组织架构,还可以提升cpu cache命中率。
//数组下标代表entity的ID
ComponentA[] componentAs;
ComponentB[] componentBs;
ComponentC[] componentCs;
ComponentD[] componentDs;
...参考资料

    《守望先锋》架构设计与网络同步 -- GDC2017 精品分享实录http://gamadu.com/artemis/http://gameprogrammingpatterns.com/component.htmlhttp://t-machine.org/index.php/2014/03/08/data-structures-for-entity-systems-contiguous-memory/http://blog.lmorchard.com/2013/11/27/entity-component-system/浅谈《守望先锋》中的 ECS 构架
----------------------------------------------------------------------------------------------------
小弟才浅,如果本篇文章有任何错误和建议,欢迎大家留言
感谢各位人才的点赞收藏,可以关注我和专栏「游戏开发碎碎念
微信搜一搜「三年游戏人」关注一个有情怀的游戏人,文章持续更新

本帖子中包含更多资源

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

×
发表于 2021-10-16 13:31 | 显示全部楼层
不知道为什么被邀请了,总之先感谢一下
不过说起来惭愧,虽然我之前以及现在是搞技术的,但是我已经不准备在技术的路线上发展了,所以即使回答,大概也不能作为题主想要的参考。不过我可以说说我最近的看法。
首先我准备离开技术路线,但不是离开游戏行业,而是转向设计路线。就是广大玩家嘴里的狗策划的方向。我之所以想要转到这个路线,是因为我觉得,目前整个游戏行业的瓶颈在游戏设计上。技术虽然对游戏的品质也有很大的影响,但是再牛逼的技术,如果摊上一坨屎一样的设计,也只能做出狗屎。而且目前,游戏技术的发展已经明显超过了游戏设计的发展水平。
在过去,欧美游戏和日本游戏相比,日本游戏的设计水平明显高于欧美游戏,但技术水平明显落后于欧美。但是从游戏的销量和口碑上来说,那个时期一直都是日本游戏处于领先的地位。但是后来,欧美的技术水平已经达到一定的水平之后,欧美的游戏厂商开始更加注重游戏设计,而日本的厂商的技术还没有跟上,所以在不久之前,我们都看到了,欧美游戏的崛起和日系厂商的没落。而最近的几年,可以看到的是日本厂商技术进步,已经逐渐追的上欧美的技术水平,所以最近几年的日本游戏又在处于一个崛起的状况。所以我想说的是,现在和过去的不同,现在的游戏设计已经不像过去那样受到技术的严格限制,换句话说,现在的游戏设计水平已经有一点跟不上技术的发展了,虽然技术仍然很重要,但是目前整个游戏开发的瓶颈,可能在于设计之上。所以可能我想说的东西并不能够帮到题主什么忙。
不过我感觉说一说我对游戏设计的想法,可能也还能符合这个题目,所以我觉得分享一下我的看法也无妨吧

如何在游戏开发领域深入发展,从游戏设计师的角度来看,我认为设计师是分很多层次的。先是“设计师”这个词,国内公司一般会把这个职位叫做“策划”,而国外的公司以及我个人,更愿意把这个职位成为“设计师”。设计师这个工作,一直以来都存在一个刻板印象,就是设计师是游戏开发岗位中入门门槛最低的,但是上限是最高的。但是门槛低,并不代表及格线就低。相比其他技术职种,可能其他技术职种入门即能达到及格线附近的水平,但设计师,很明显,有很多完全不合格的设计师也混迹于专业开发者之中。下面我来说说我对这个职业的看法。
首先最低级的水平,自然是不合格的水平的设计师,依靠拍头来设计游戏。这种人,觉得自己有一个独一无二的点子,或者自己的思维很广阔,很有创意。我不多做点评,按照这种标准的话,只要是长着头的人,就能做设计师。
弱智
再之上以及的水平,仍然是不及格的水平,依靠经验来设计游戏。这种人一般在游戏行业混迹了几年时间,有一些开发经验了,就觉得自己已经是一个高级开发者了。但是,这种人不仅仅在设计行业存在,我举个程序方面的例子可能更容易理解,一个人,工作了10年,这10年期间,只有第一年学习了一些新的技术,之后9年都在不断的用第一年掌握的技术工作。然后他的简历,写着他有10年的工作经验。第二个水平的设计师,我指的就是这样一类人。
高龄弱智
再往上一个水平,我认为才算能达到设计师的及格水平,这个水平依靠的是组织能力和逻辑能力。到达这个水平之后,设计师应该明白游戏是一个有组织,有规则的活动,在做设计的时候能够把每一个游戏系统,游戏元素有规则的组织在一起,一个高级游戏元素或者游戏规则,是建立在一些基本的规则之上的;一些游戏元素,是通过一些逻辑相联系的。这个级别的设计师应该可以设计一些逻辑规范的游戏系统了。至于系统好不好玩,有没有办法改进,这个阶段的设计师可能知道,也可能不知道,我认为这个阶段都是ok的。能设计出更好玩的游戏系统,我认为是更高水平的设计师应该掌握的能力。
再往上一个水平,我认为是利用理论来设计游戏的。到了这个水平,设计师应该要依靠一些游戏设计理论来设计游戏。设计师会清楚一个游戏系统的设计思路,设计目的,以及这种设计方式有些什么样的优缺点。到达这一个层次之后,设计师应该了解到怎样的设计会让游戏更有趣。并且到达这样一个层次之后,游戏设计师应该会逐渐向学术的方向靠拢。我认为现在整个游戏设计行业,就卡在了这样的一个瓶颈的位置。可能游戏行业已经开始在寻找一些稳定的游戏设计理论,并且已经实质性的取得了一些进展了,但是到目前位置,应该还没有一个统治性的,能像牛顿运动学定律在经典物理学中那样地位的系统性的理论出现。可能很多的开发者都有自己的一套理论,或者公认一些理论,但是还没有能拿出来作为新入行的人拿来做教材的理论体系出现。因为没有这样的一套了理论,所以其实对于新入行的人来说,初步涉足设计行业会产生一定的困难。而我相信,我的这个想法一定有人会反对。因为一定会有人认为,游戏设计应该是一个自由的,不受束缚的工作。而死板的理论一定会束缚思想,让游戏设计陷入一个死板的套路之中。其实这个问题,不仅仅是我,我已经看到了,一些试图建立学术性比较强的设计理论的人遭受了这样的质疑,但是我仍然认为,一套游戏设计理论可以帮助游戏设计更好的进行。
再往上一个水平,我认为是能够灵活的运用理论来设计游戏,能够在原有理论的基础上进行创新,亦或是合理的将理论应用于不同的游戏场景之中。这个层次也是我认为游戏理论应该存在的一个原因。这个层次是用理论来指导实践的过程。不仅仅是在游戏设计领域,对于任何一个科学生产的领域,理论指导实践都无疑是科学的生产方式。就算横向对比最为接近的艺术行业,比如摄影,没有构图,色彩,光照等等一系列的理论,能做得到拍摄出优秀的图片吗?比如音乐,没有乐理基础,如何能创作出优秀的音乐作品?就算是写作,也有一系列的套路可言。经典的英雄旅途,多少的编剧乐此不疲的在套用,并且不断创作出有趣的剧本来?而以上举出的例子,这些工作的成果都可以应用到游戏之中,那么就更不用怀疑在游戏设计行业需要理论做基础的必要性了。我这里想举个例子,育碧的游戏,经常被人调侃,公式化的开放世界游戏。我认为这个就是育碧自己有一套游戏设计理论的原因。平心而论,这样设计出来的游戏,实际上还蛮好玩的,起码已经达到了好玩的水平,但是对于老玩家来说这种玩法已经玩腻了,自然会觉得有点腻。育碧所处的水平很明显已经到达我所说的游戏理论的水平,但是还需要进一步突破,就是在原有理论的基础上,在做一些创新。而且近年来,玩家应该也能够看到,育碧也在不断的尝试着创新,育碧在玩家之间的口碑也在渐渐变好。
再往上一个层次,需要依靠的是经验。到达这个水平后,设计师需要积累一些实际设计游戏的经验。这个过程是从设计新手转变为专家的过程。通过见识不同的问题和解决他们,设计师可以在一定程度上达到自动化,即很快的构想出一些有趣的玩法,或者一针见血的找到能让游戏更有趣的方法。其实对于任何的其他行业,这个过程也都是存在的。
再往上一个层次,我认为是游戏设计师的最高层次,依靠的是拍头。到达这个阶段,设计师可能已经不能仅仅依靠理论或者经验来提升游戏质量了,只能靠灵感。俗话说的好,这个世界上的人,大部分人的努力程度,都还不到让他们有资格讲天赋的程度。只有能确实的达到很高水平的人,他们之间的优劣可能才能依靠天赋,灵感之类的东西去区分。
以上就是我个人认为的应该如何在设计师这条道路上深入发展。可能有人觉得我的最前两个级别翻过来就变成了最后两个级别,确实是这样的。另外我还举了一些其他行业中的例子,我认为很多很多行业的职业发展过程其实都是大同小异的,选择一个中意的方向,了解这个行业的运作原理,运用原理到自己的工作之中,并且在原有的基础之上进行一些创新和改进,来推进行业和自我工作效率,能力的发展,然后在工作中积累经验,成为专家。一般大部分人可以做到这一步已经算是不错的了,如果想要再进一步突破,就需要一些天赋了。只不过在这个大体的过程中,可能会碰到具体问题会有一些不一样。题主想要知道技术方面该怎么走,我由于已经准备放弃技术路线了,所以没有办法给出比较好的建议,所以题主可以在这方面看看其他人的建议。
发表于 2021-10-16 13:40 | 显示全部楼层
非常认同 @韦易笑 的答案
我试着再拓展一下
现在当大家谈到游戏编程领域的深入时, 普遍都认为这个深入是Engine层的深入,其实这个理解是非常片面的, 同时单纯的Gameplay深入,也是不合理的。这是结论。

Gameplay的深入,除了架构层面的问题,还有一个重要问题是细节,很多细节的优化也是不可能不动到Engine层的。(这里的细节并不是单纯指性能)

所以,这行的深入,其实并不是非此即彼的二元论, 而是你都需要会,都需要了解,同时你又在某一个方向,有深入专精。
发表于 2021-10-16 13:46 | 显示全部楼层
你需要知道自己喜欢做什么,自己能做什么,然后选用合适的工具,将自己最大程度滴扩展。
做这一行要耐得住寂寞,学一切你不知道得东西,并且保持一颗乐观的心。
发表于 2021-10-16 13:49 | 显示全部楼层
应用层有太多可以深入的地方了。结合我自己的开发经历,也结合其他网友的回帖,简单谈一下。

1. 人物动画。国产游戏的一大问题是人物动画生硬,缺少变化,动作单一。
这个问题除了美术的实力和投入不足之外,一大原因便是程序这边对动画的支持不够。

以刺客信条为例,这个游戏在人物动画上可以说是做到了极致,比如主角和NPC都可以做出不同速度的走,跑,跳跃,攀爬,格斗。。。等等各种充满了变化的动作。而动作和动作的衔接也十分流畅。除了预定的动作外,人物还可以对外界的任何刺激做出相应的反应。比如,在不同斜度的斜坡上奔跑是,人物的身体倾斜程度会不同。再比如,根据目标的远近和角度,主角会做出不同的动作来适应目标。

要做到这一点,除了传统的blend tree,还需要在程序端支持animation graph, layered animation, procedural animation, IK等高级的功能。甚至你还要自行开发一套动画编辑工具,从而让美术可以充分发挥他们的想象力。为了提高这个工具的迭代效率,它还必须能够和游戏引擎实时通讯,从而做到所见即所得。

开发和维护这一套系统,是需要一个专门的程序员+美术团队,以数年的时间来完成的。但这个团队里的程序员,其实严格来讲并不是引擎程序员,而是animation programmer和tool programmer。这里面的美术,其实是technical artist而不是一般意义上的美术师。

2. 人物AI。
AI这个话题可以很宽泛。比如path finding, path follow, behavior, state machine,这些其实都可以算是AI的内容。

以寻路为例,你做的寻路是基于路点的,还是基于navmesh的?如果是navmesh,你的系统支持动态navmesh吗?支持3d的navmesh吗?不同种类的单位,在寻路时用到的规则都不同。即使你完成了地面的寻路,还有水中的,空中的,甚至是太空中的寻路。光是寻路这一块,都够你研究几年的了。

你觉得AI没什么可做,那是因为你做的游戏类型不要求特别复杂的AI。
如果你是做开放世界的游戏,比如GTA,或者上古卷轴。你就知道AI的重要性以及复杂度了。因为在这些游戏里,NPC可以做出几乎和主角一模一样的行为。比如攻击,防御,攀爬,跳跃等。基本上,你的任务是把NPC的行为做的和真人一样真实可信。你知道这个任务的难度在哪里吗?

如果你是做RTS,那就更复杂了。首先,整个游戏世界里会有上千个单位,而这些并不是网游里的站桩机器人,因为他们的AI和行为比网游复杂的多。这些单位除了接受玩家的指令,还必须有自己的AI来自动完成任务。AI和AI之间还必须互相协作。比如你控制一队AI,让他们从一个地方,经过一个狭小的通道,到达另一个地方。这个群体寻路和群体path follow的技术含量是很高的。放眼全球的游戏开发界,能做出这个效果的公司不超过5家。

3. 物理
坦白讲,物理引擎本身不算是应用层。但如何使用市面上通行的物理引擎,在这之上做适合的封装,以达到游戏上层想要的效果,确实是一门学问。

比如在Uncharted 3中,主角可以在几辆高速行驶的卡车之上跳来跳去,同时做出各种复杂的动作以适应不同的车辆。在某一辆卡车上,主角还可以完成近身格斗,远程设计,攀爬等各种复杂的动作。这里面除了动画和游戏逻辑,物理碰撞的判定也是很重要的。

Uncharted 4的演示关卡,还出现了车辆拖行主角,在泥地上滑行的效果。这些都离不开物理的支持。也对游戏程序员有很高的要求。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-6-6 00:32 , Processed in 0.102303 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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