在网易游戏的第四年——Jerish的2022总结

Posted Jerish_C

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在网易游戏的第四年——Jerish的2022总结相关的知识,希望对你有一定的参考价值。

这是【游戏开发那些事】第58篇原创

时光飞逝,不知不觉在网易的第四年结束了,第五个年头也已经拉开了序幕。由于前段时间状态不佳,所以今年的总结来的晚一些,照例先祝大家新年快乐、开工大吉~

2022年是游戏行业极为跌宕起伏的一年,我们见证了微软史上最大的游戏公司收购案、目睹了运营3年的Stadia服务被谷歌草草关闭,“元宇宙”热度骤降、公司HC紧缩,裁员风波持续,业内的朋友们或多或少都遭遇了不小的冲击。但与此同时,虚幻5的正式发布、版号颁发的恢复、欧洲议会38条“游戏新政”的通过,依然鼓励着我们在游戏这条路上继续向前。

作为历史洪流中极为渺小的一员,也作为一名身处游戏行业的普通开发者,我的一年仍然是写写代码,学学知识,软技能上有了一些成长,技术上却遇到了一点点瓶颈。用一句话来总结我的2022——在曲折的道路上缓步前进。

学习与思考

去年在行业技术领域的深耕确实拓宽了我的视野,更让我意识到了自身技术深度的匮乏。举例来说,我可以很熟练地在引擎中使用接口来构建各种对象,却并没有深刻地理解每个参数背后的意义和应用过程,我也可以通过调用GC函数来释放内存,但对其中的原理与细节却并不十分了解。比如,

    • UE引擎类的构造函数为什么要使用ObjectInitializer进行初始化?

    • UE里面的Object对象是如何高效地组织和查询的?

    • UObject对象的生命周期是如何管理的?

    • 为什么UE使用标记清扫这种GC方式?

    • 如何在合适的时机GC?

    • 如何优化GC带来的卡顿?

这些问题看似与逻辑功能无关,却会在你进行系统设计、功能优化、bug查找的时候影响你的决策和思路。

因此,挖掘代码背后的原理变成了我上半年的首要任务。我开始尝试深入分析我写过的每一行代码,包括梳理NewObject是如何根据class构造出一个我想要的游戏对象,分析不同蓝图资源是如何从硬盘加载到内存并把空壳对象反序列化成实际的对象的、研究UE里面的数据结构是如何提高访问效率的。慢慢的我发现,引擎里面的很多设计都源于书本上的基础原理,比如

    • 用一个索引数组可以将UObject某些属性的查询优化到O(1)级别的时间复杂度,而数组本身不方便扩容和增删就可以通过分段拼接实现逻辑上的“伪数组”;

    • 通过生成Hash表来快速查找到UObject来优化字符串查询对象太慢的问题;

    • 为了方便迭代查询特定类型的对象,可以为所有对象分类型生成哈希表;

    • 为了减少内存空间的浪费,尽可能将对数据的操作精确到每一个Bit;

map示意图,可以依据cache命中率进一步优化(源自hackingcpp 可视化做的非常好)

总的来说,大部分代码的设计都是基于实际的生产环境,综合权衡时间复杂度和空间复杂度而来(手机上可能还有功耗,发热等问题)。而这些知识之所以很难被大家灵活地应用到实际项目中,一方面是由于个人经验积累的不足,另一方面就是因为平时缺少思考,没能将知识融会贯通,与实践相结合。

经验的缺失需要项目的磨练,而思考与融会贯通的能力是可以锻炼出来的。我的方法很简单,就是从我写的代码开始思考,不断对自己进行提问并分析解答。

比如下面UE引擎中一个简单射线检测代码就可以挖掘不少内容,

FCollisionQueryParams LineParams(SCENE_QUERY_STAT(ComponentIsVisibleFrom), true, IgnoredActor); 
FHitResult OutHitResult; 
bool const bHadBlockingHit = World->LineTraceSingleByChannel(OutHitResult, FVector(0,0,0), FVector(0,0,1), TraceChannel, LineParams);
  • “射线检测的结果是从哪里得到的,如何确定一个物体是否会被Block?”

  • ”FCollisionQueryParams有哪些参数可以设置?bTraceComplex和IgnoreMask有什么意义?“

  • “Trace通道的逻辑在代码上是怎么处理的?通道是通过什么数据结构来维护的?”

  • "角色人物移动是否也是通过Linetrace去检测碰撞的?"

  • ”Unreal是如何通过引入PhysX来处理物理逻辑的?“

通过这种思考和深挖,我很快就能搜索到各种相关的书籍、论文、回答、视频等,然后构建一个详尽的知识树体系去学习。当然,每个看似简单的问题都可能涉及到数学、物理、语言机制、存储、CPU、编译、操作系统、硬件架构等各种知识和技术,不可能一蹴而就。因此合理安排时间并把握学习的深度,能够做到点到为止并循序渐进也是十分重要的。

除了“如何挖掘和应用代码里的知识”这种技术层面上的思考,我认为将这种思维习惯拓展到学习方法上其实更加重要。比如,

    • 怎样才能更有效的查找资料(提高学习效率)?

    • 如何妥善地利用工具来解决问题(提高工作效率)?

    • 如何挖掘问题背后的原因来规避同类型问题(避免重复性工作)?

只有带着思考去学习和复盘,形成一套适合自己的思维方式和学习习惯,成长才是有加速度并且可持续的。

工作

坦白说,从技术角度来看,今年在工作上并没有太明显的进步。除了维护之前的系统,主要对引擎架构进行了更加深入的学习,包括UE4中物理引擎的架构、动画系统架构、Unlua实现原理、UE4对象和内存管理等。

不过随着工作经验的增加和持续的复盘总结,我在一些常见功能的实现方法上有了更加清晰的思路,比如一个合适的Buff系统应该怎么做,游戏里面的表演镜头应该如何实现,一个灵活的日志系统应该如何设计等,这使我在辅导新同学,提升团队效率方面受益颇多。

举两个具体的例子,

  1. 很多项目中都会有翻越、攀爬等一些特定的带位移动画需求,尤其是动作类游戏。有了经验以后,会发现类似的需求本质上都是给定触发时间,然后未来持续N秒的时间里播放动画并调整位置和旋转。考虑到网络同步的兼容,这些功能在UE里面基本上就是交给RootMotion去做的(可以定制不同类型的RootMotion),然后再根据实际的需求去调整移动组件的逻辑代码。

  2. 大部分项目都会遇到蓝图、C++、脚本的权衡问题。蓝图不好进行版本管理、逻辑不够清晰但迭代灵活且快速;C++迭代不够灵活但逻辑清楚、运行速度快;脚本不方便策划使用、性能较差但更新和管理相对简单。你会发现每种方式都有缺陷和优点。通常比较合理的方法就是快速迭代时,允许策划使用蓝图实现原型,需求稳定后程序封装节点并让策划最小限度地使用蓝图进行开发,同时所有高性能开销的操作避开脚本和蓝图,把Tick等逻辑塞到C++里面去实现。

理解需求和问题

工作经验的增加,还让我能更好地对接和挖掘策划提出的需求。很多程序在对接功能的时候,没能很好地理解需求以及策划的意图,最后不得不返工和重构。

我认为,任何程序在接到策划案后都应该思考并问清对方到底想实现什么功能、想解决什么问题?很多时候策划只是想“借鉴”并结合某几个游戏的功能,但这些功能在实现的时候其实是有冲突,或者是不合理的,这种方案在实现上和迭代上都很困难,并不是最优解。

就算一个需求在讨论过后真的没有完美方案,我们也可以结合时间成本和实现效果给出一个目前相对理想的解决方案,然后在不同的阶段重新审视项目并进行调整和重构。毕竟游戏项目中的需求瞬息万变,这种重构与调整才是开发中的常态。

除了对需求的挖掘,我在修复Bug的时候也开始习惯去进行深度思考,来尽可能地从根本上解决问题。比如常见的空指针崩溃,不是简单的判空就可以了,要去思考这里为空是不是合理,如果为空后面的流程是不是能继续跑通等。还有一些问题不仅要从技术的角度上去分析,还要从工作流程上进行分析,比如资源和代码的提交顺序造成的崩溃、服务器版本部署的位置调整造成的报错等。总而言之,要尽可能避免这种无意义的偷懒,否则后续就有可能面临无穷无尽的缝缝补补,非常折磨人的心态。

学会复盘

最后,再强调一下复盘的重要性。可能很多朋友和我一样,工作时间长以后就难免习惯做一些重复且熟悉的内容,慢慢地就会变得对工作麻木,成长也会明显放缓。

我建议大家分出来一些时间进行复盘和总结,问问自己最近做了哪些需求,花费了多长时间,为什么会比预期慢。如果你是项目中的骨干,你要思考的内容就要更加深入,比如项目目前有哪些问题?我能解决哪些问题?我可以找谁帮我一起去解决问题?我可以从主管那里得到什么帮助?


我们的工作真的不单单是写几行代码,解决几个bug,思考做什么和思考怎么做一样非常有难度有价值。此外,如果发现自己在某个技术领域已经非常熟悉了,也可以主动向上级主管申请承担另一个想深入学习的模块,这样就可以在工作的同时去研究自己感兴趣的内容了。

面试

做好面试者

今年作为面试官参加了许多场校招和社招的面试,也有不少新的思考和收获。

首先不得不承认,现在的校招同学真的很优秀,卷也是真的卷。简历上都是各种国外实验室Lab、游戏/渲染Demo、服务器框架等,远远超出了我当年毕业时的水平。与此同时我也发现一个问题,就是很多同学花费不少时间用UE4/Unity做一个游戏Demo,虽然功能上都能跑通,但很多原理性的内容理解的并不透彻。这样就会显得面试者深度有限,难以在众多竞争者中脱颖而出。

Games104完结,明年说不定人手一个游戏引擎Demo?

其实校招面试更关注的是大家的基础素质,提问最多的还是C++和计算机基础,如果你的时间并不充足,建议还是多花些功夫在基础上面。我相信,一个能很好理解代码的运行原理,熟悉内存分配和使用,妥善处理好数据结构中每一个字节的同学,写几个游戏Demo并不在话下。

另外给一些其他的建议,

  • 简历最好用PDF,Demo项目一定要贴链接,最好是GitHub

  • 简历不需要事无巨细,着重要点和难点

  • 态度上认真诚恳一些,很多同学连游戏开发做什么都不清楚,岗位随便投递,这样面试官的印象分会大打折扣

  • 和工作相关性不强的项目尽量不要写,如果没有项目就去找一些技术含量比较高的计算机基础项目(操作系统、服务器、线程池、内存池等)

做好面试官

不少同学在面试时可能都比较紧张,其实面试官并不见得比你轻松,他要思考的内容要更多更复杂。刚开始面试时,我作为面试官也会遇到很多问题,

  • 除了常见的基础知识外,不知道如何根据简历提问或者问题比较浅显,不能很好地挖掘面试者的水平

  • 忽略或者过分在意面试者的情绪状态和需求

  • 难以判断对方是否达到进入下轮面试的要求

这些问题的产生,除了自身经验不足,还有一点就是我作为面试官没有搞清楚面试的目的。面试是一个双向选择的过程,本质上就是找到一个合适的人选和你一起长期工作,解决问题。所以除了基础知识,面试官完全可以拿平时工作遇到的问题来提问,一步步深入来观察对方的解决思路和逻辑。因为面试也并非单纯考察对方的技术水平,还需要了解对方的基本素质,解决问题的方式,表达能力甚至是工作习惯。很多人把面试归结为技术考察其实是很片面的,如果没有意识到自身其他方面的问题,缺乏换位思考能力,面试被拒也在情理之中。

那么面试官在提问时有什么技巧或思路呢?我简单整理了一些自己的想法给大家参考,

  • 明确问题:选择你熟悉且对方简历上有的技术点。

  • 概括梳理:让面试者尽可能简单地描述一下某个工作内容的意义和实现方案。

  • 方案与场景:提问面试者是如何思考并设计某个项目方案的?使用场景是什么?

  • 底层原理:方案的底层原理是什么?代码上是如何实现的?涉及到哪些模块内容?

  • 问题与优化:当前方案存在什么问题?如何进一步优化?

按照这种思路,我通常都可以很好地了解对方的技术能力与解决问题的能力,然后进一步判断面试者的综合素质以及面试通过与否。

软技能

技术能力之外,我在软技能上也有了一些突破和成长。

  • 做了一次500+人数的技术演讲

  • 担任Mini项目的导师,辅导了几位新入职的校招同学

  • 参加公司的“软实力”培训

技术演讲

先来说说技术演讲。在杭州5月份举办的UnrealCircle中,我受邀分享了一场关于“UE4回放系统”的技术演讲。虽然技术分享的现场氛围通常都比较轻松,但我还是抱着“提升演讲能力”的目标认真准备了2个月左右。从现场效果和录播视频来看,除了开始有一点紧张,整个演讲过程还是比较流畅顺利的。

据我平时的观察,大部分程序同学(包括我)都比较热衷于钻研技术和编码,不太习惯参加过多的社交活动,也不太在意技术之外的尝试。但技多不压身,生活不应该仅限于几行代码,也不能总是在自己的“舒适圈”画地为牢,适当地放宽视野,去尝试一些没做过的事,多掌握一些其他的技能,这些都会为我们带来更长久的收益。

培训

在去年的4月到12月,我参加了公司的软实力培训,培训内容比较广泛,主要围绕“情绪管理”、“非职权影响力”、“沟通技巧”、“项目管理”等多个方面展开。虽然很多课程点到为止,但确实会让我在写代码之余去思考一些“技术”之外的内容。比如

  • 如何更好地提升自我认知(情绪,能力等)

  • 如何更好地利用同理心与他人沟通

  • 如何跨部门协作 如何挖掘对方的深度需求等

经过这些思考和讨论,我发现自己可以更好地跳出主观思维的盒子,更换角度来解决问题。举个例子,如果我们作为面试官想邀请对方加入、或者在跨部门协作时需要获得对方的帮助,这种场景下我们其实很容易陷入主观的思维误区,不断跟对方强调我们有什么优势等等,但对方很可能对这些点并不在意甚至反感,那么合作失败是在所难免了。比较恰当的方式其实应该多提问,多挖掘,多倾听,尽量做到足够了解对方、理解对方的需求后,再结合自身的客观条件来进一步阐述。

身心

我一直有着日常锻炼的习惯,身体状况也都不错,今年为了增肌还报了几个月的私教。健身的前两个月确实效果不错,卧推和蹲起的重量不断增加,体脂也有一定的下降。但在7月份左右,项目比较忙加之各种杂事的堆积,导致我的身体和精神状态都异常疲惫,甚至需要在健身前小睡半小时来休息一下。这种情况持续了一个月后,身体出现了不适,不得不放弃健身,开始好好休息调养。今年在公众号和知乎上更新频率的下降,也正是因为这个原因。

所以还是建议大家多关注一下自己的精神状态和身体状态,看看自己是不是长期处于一个紧张的情绪中、身体是不是有一些小的异样,避免在疲劳状态下过度锻炼,同时定期体检,尽量把熬夜、坐姿不规范等不好的习惯改掉。

毕竟,身体才是革命的本钱。

结语

新的一年,我打算制定相对可行的短期目标来保持一定频率的正向激励,一方面计划跟着Games104 写写引擎并深入研究物理相关的内容,另一方面就是在空余时间多关注一下C++的迭代,多看看Nvida、Intel、Epic等行业巨头的官方视频和Demo来持续跟进业内技术的更新和发展。

我相信2022年是承上启下、继往开来的一年,2023年会变得更好,也祝愿大家的事业都能步步高升!

 往期文章推荐 

游戏开发技术系列【想做游戏开发,我应该会点啥?】

虚幻引擎技术系列【使用虚幻引擎4年,我想再谈谈他的网络架构】

游戏科普系列【盘点游戏中那些“欺骗玩家眼睛的开发技巧”】

C++面试系列【史上最全的C++/游戏开发面试经验总结】

我是Jerish,网易游戏工程师,6年从业经验。该公众号会定期输出技术干货和游戏科普的文章,关注我回复关键字可以获取游戏开发、操作系统、面试、C++、游戏设计等相关书籍和参考资料。

以上是关于在网易游戏的第四年——Jerish的2022总结的主要内容,如果未能解决你的问题,请参考以下文章

在网易游戏的第二年——Jerish的2020总结

在网易游戏的第三年——Jerish的2021总结

在网易游戏的第三年——Jerish的2021总结

在网易游戏的第三年——Jerish的2021总结

网易游戏还能否撼动腾讯游戏霸主地位?

macOS丨国内最流畅的手游模拟器-网易开发