系列:从零开发ARPG

前言 UE最近看了不少,关于Locomotion和Gameplay相关的也看了很多。想着开个坑重新练练手,顺便把用到的知识都内化一下。 顺便做一些简单的记录,如果后面能有人用到就更好了。

2025年12月11日 · 阿肠

Horde和UBA初窥

前言 最近赋闲在家(被迫),有时间可以看一下一些UE的新技术。其实Horde和UBA对我来说也不算特别“新”,我大概是在2025年初的时候就知道有这么个东西。不过当时心思不在,就没去折腾。昨天在B站虚幻引擎看到介绍,就搭建了使用一下,整体效果还不错。对于Homelab,能有效替代Incredibuild免费版。对于大型团队,复杂的网络环境,有待验证。 Horde和UBA是什么 做过游戏项目的都知道,打包、测试、发布这几个流程是非常折磨人的。不管是什么引擎(UE更甚),几乎打打包都需要耗费大量的时间,尤其是版本日(估计行业内看到这个词都PTSD)。我在这里姑且先不讨论打包为什么需要这么久。Horde和UBA就是EpicGames提出一个解决方案。 UBA提供联机编译,替代的是IncrediBuild的生态位,目前支持Shader和C++联机编译。相对IB,UBA的功能更加简单、纯粹。它只提供联机任务执行的框架,其他IB的例如节点管理、节点发现等都是由Horde提供。 而Horde相对来说更加复杂,提供了很多功能,后面会针对这个功能逐一细说。关于这两者的安装和使用,以下这两篇文章12基本都提到了。唯一的区别是我是Docker安装Horde服务器,也很简单,官网有参考的Compose文件。 唯一需要注意的是,Project范围的BuildConfiguration.xml似乎没生效;在用户目录下有个BuildConfiguration.xml,在那里修改UBA和HordeServer才生效。 联机编译 性能初略测试 测试了两遍,3700X+5950X,全新编译Larya(不包含引擎),大概2分钟。 全引擎编译重编(Build All),UE5.7Release全新checkout的代码代码,3700X+5950X+E3 1280,大概是2个小时30分钟。 全引擎编译重编(Build All),UE5.7Release全新checkout的代码代码,3700X+5950X+E3 1280+8809G,编译时间2小时。Build completed at 22:46 and took 02:02:55.179 hours 带有一个简单UBA Visualizer如下图: 结论 对于目前有限次测试来说还是很稳定的,Horde基本没出现挂掉的情况。偶尔会出现Agent连开以后又断开,原因暂时未知。 免费、不限CPU数量很香,比IB的免费版香太多了。 安装难度比IB麻烦一点,要先装一个Toolbox,然后再安装Agent,还要改BuildConfiguration,如果能都集成在Toolbox就完美。 观察到发起编译的机器也会被Horde分配到联合编译当Helper,相当于发放了两倍任务。虽然总体完成时间不会有太大差异,但是内存占用是实打实翻了一倍。 单核性能太弱鸡的建议不要放到Pool里面。最后几个任务总会拖后腿,高性能的机器总在等待,最长有10-20秒。 分发的启动稍微有点慢,参考图1,基本发起要在Initiator编译完1.5轮以后才全部连接上。不过其实IB也是这样,分发的策略也保守。 CI/CD Horde还有一个很重要的功能,就是提供CI/CD。本来看视频的时候还寄予厚望能替代Jenkins,没想到还是一个要靠编辑服务器JSON写流程。对于协作来说没有可操作性,不过文档看起来还挺Promising的,后面有机会可以试试。 不过相比于完善编辑器,我觉得更加希望可以将其他步骤都进行分布式,尤其是Cooking,这个才是日常打包耗时大户。 设备测试 可以连接移动端的设备。除了跑自动化测试框架之外,似乎还能跑Job,暂时还不清楚怎样跑Job,有什么能力。 工作室遥测 这个其实是一个相当有用的概念。它可以测量编辑器在工作室内部的卡点,有什么特别耗时的地方。不过对于Horde的统计和分析能力我觉得是要打个问号。仅从文档来看,只提供了一些Charts的定义方式,远不如传统的ELK分析灵活。不过还好Horde也提供了透传日志的功能,算是额外的扩展。 我觉得更有价值的是编辑器提供打点的插件。简单搜了一下UE5.7的代码,目前提供的打点不少。工作室内部在这个基础上扩展肯定有一番作为。 总结 我觉得Horde和UBA算是开了一个很好的头,EpicGames也意识到天下苦打包久矣。对于低成本的公司、工作室,通过免费的联机编译作为“诱饵“,吸引他们入局使用,然后提出意见修改,算是比较好的切入点;相反,对于已经购买IB授权的大公司,这个诱饵对他们的吸引力不强。而其他功能也没能完善到开箱即用、非用不可的地步。 如果能投入更多的人力,把分布式Cooking搞掂,Horde才能实现自己更多的野心。 UE5.4 UBA分布式构筑和打包 初探 ↩︎ 虚幻5 Horde服务安装和配置 ↩︎

2025年11月27日 · 阿肠

GODOT引擎中的一些概念

Server 一个引擎内部代码组织代码概念,主要用途是用来将引擎内部一些比较独立系统组织起来。 只是一个逻辑概念,代码上没有一个框架,都是每个Server按照自己的情况去创建。 嵌入到引擎也是通过Hardcode(例如在main.cpp初始化某些Server) 一般来说每个Server都是有自己一套线程运行,跟主逻辑线程主要依赖CommandQueue(引擎提供),主线程一般只在需要的跟Server做同步(例如物理、渲染) Server本身是一个Object,可以发送信号到场景对象。 Modules和GDExtensions 两者都是C++扩展引擎的方式,主要区别是Modules是以静态方式编译进引擎,GDExtensions是动态库方式。 Modules功能更全,因为和引擎一起编译,可以访问所有的API。不过官方承诺如果发现GDExtensions实现不了的功能,可以提Ticket,尽量保证和Modules功能相近。 GDExtensions编译更快,Modules修改需要重新编译整个引擎(但是我觉得只要依赖正确,基本多不了多少时间) GDExtensions由于是二进制,可以使用其他语言开发(社区有个Rust的)。大概只需要将引擎的API导出到Rust就可以(不过引擎API的二进制兼容性如何?) iOS不支持动态库加载,GDExtensions似乎无法使用,也没法直接将GDExtensions静态连接到ios。 参考: What is GDExtension? Why does Godot use Servers and RIDs?

2023年10月16日 · 阿肠

HybridCLR浅析

周日心血来潮开了一下Unity,突然想起之前有一个据说秒天秒地秒空气的热更框架huatuo,打算找来研究一下原理。 搜索了一下,发现huatuo已经归给掌趣,作者后来自己开了一个HybridCLR。知乎、B站、Google搜了一圈,发现基本都是同样的内容,像极公关稿。说什么工作在IL2CPP层、没有虚拟机、性能牛B、开箱即用,玄乎到不行。好奇行心驱使下,看了一下源代码,大概明白工作原理: 在IL2CPP生成完Unity自身C#对应的C++代码之后,插入一些HybridCLR的C++代码,其中包含所谓的interpreter和transform。 interpreter本质就是一个虚拟机,用来执行HiOpcode。 transform就是用来做IL->HiOpCode转译 interpreter传宣是register based,但是代码看来就是stack based。不知道作者是否有商业版本的实现 HiOpCode就是基于Unity的一个特化指令集。只要指令集命中的执行效率肯定高,除此之外通用性能可见的不太理想。另外虚拟机的指令集是变长的,想要优化效率估计有困难。可以简单类比CISC和RISC的区别。 相比现有脚本解决方案,绕一层C#再到引擎接口,HybridCLR直接通过interpreter调用IL2CPP::vm接口,确实性能会有优势。还是那个前提,只要你的代码能命中特化的opcode。 这个方案的本质还是Unity不提供纯C++库的调用方式。IL2CPP::vm这个胶水层虽然比直接C#要薄,但是相对纯C++接口还是太厚了。如果Unity自己能提供一层C/C++的封装(类似fmod那样),对脚本接入就不用这么纠结。 综上所述,HybridCLR所获得的性能提升主要在更薄的胶水层和特化的OpCode;相对应的通用解析性能可以预见的不高(盲猜,没有任何证据,不用杠。杠就是你对)。对于纯C#的项目,想获得一些热更修复的能力,可以考虑。如果是想达项目的脚本化,HybridCLR估计有难度。 ILRuntime的原理其实也类似,只是我记得最早ILRuntime是直接运行IL OpCode的。今天看了,好像也用了类似的方式。

2023年7月18日 · 阿肠

Cocos2D-X历史回顾

今晚在整理以前的笔记,发现一篇关于cocos2dx renderer的设计摘录。cocos2dx可以说是我客户端之路的启蒙引擎,对我有很大的启发,也跟随着我经历过一段神奇的工作经历。好奇心驱使下,去搜了一下目前的状况。发现2018年基本已经停止更新,最新的版本也停留在v4.0(2019年)。后来的替代者是cocos-engine。简单的浏览了一下文档,虽然增加了不少新的特性,绑定语言也变成了TS,从代码树来看似乎也继承了cocos2dx部分代码。但是整体的功能和设计不要说跟双U比,就算跟目前的后起之秀GODOT也差了不少,论坛也比较冷清。 这不禁使我思考,为什么当时如日中天的coco,为什么后来会掉队呢? 崛起 cocos2dx其实是从coco2d的’翻译’过来的(我记得后面甚至原作者也跳到cocos2d)。coco2d是一个基于ios objc的2D引擎,一开始定位就是做2D小游戏的。在这样的背景下,再加上钓鱼达人在手游的爆火,作为幕后功臣的cocos2dx自然得到更多人的关注,而当时正处于手游崛起时代,国内(国外)游戏引擎近乎空白。cocos2dx自然顺利成章的’补位’。 转折 对于cocos2d-x v2.2之前的历史我所知不多,但对于v2.2以后甚至v3.0的版本,可以说这个引擎的巅峰,时间大概是2012-2015年。伴随着各大传统厂商入局手游,市场迅速扩大。cocos2d-x可以当时游戏研发的唯一选择,当时的触控科技可以说是当红炸子鸡。触控当时也看到移动设备的性能不断攀升,推出了重构了渲染层、’支持’3D的v3版本。在我看来,正是这个风向的转变,让cocos2d-x从第一梯队掉队。我认为主要原因: 兼容性。V3当时的定位是V2的迭代,迭代了渲染队列和增加能显示3D的节点Node3D(如果我没记错的话?)这就导致花了大量时间的V3实际只是一个能显示3D模型的准2.5D引擎。从现在我个人的角度来看,如果要做3D的话,原有的引擎API根本不适合,单说场景管理这块就已经很头疼。另外3D引擎的工作流需要有很强的定义和整合能力,当时cocos2d-x也是一个渲染引擎,根本达不到这样的高度。与其从V2兼容迭代,不如另开炉灶,做一个领先时代的新的产品。事实上触控后面也开了Cocos Creator,UE3->UE4也是完全重写(虽然用了不少UE3的代码)。 稳定性。对当时cocos ui 编辑器的稳定性印象深刻。每天都会crash不少次,还会有一些性能问题。即便是后面的版本也基本没有太多改善。对于inhouse的工具,可以忍;作为一个产品几乎无法接受。 技术滞后性。cocos2dx很长一段时间都是以一个单独的渲染引擎+UI编辑器存在。直到后面Unity出来,才发现可以将所有东西整合在一起作为一个编辑器。这时候Unity已经以技术领先态势抢占市场份额。回头Unity在3D引擎的基础上开发出2D引擎的内容把cocos2d-x仅有的2D市场也吃掉。 总结 其实,无论你之前处于什么样的领导地位,只要一次没跟上时代的步伐、看清楚形势就会被时代抛弃。无论是对于个人或公司,触控如是,诺基亚如是。反观同样是有自己产品和引擎的E宝,在Unity已经抢占手游市场的大半江山,依然能通过开源占领市场,并利用自己技术优势和不断迭代,重夺引擎市场桂冠。可惜,触控始终不是Epic,时代总要翻篇。

2023年1月27日 · 阿肠