将厄运移植到速度无服务器平台

2021-04-22 11:38:17

由于其可接近的Codebase和清洁抽象,ID软件的厄运已成为历史上最往返的游戏之一。它感觉像是一个完美的项目到occumpute @ Edge,基于无服务器计算环境,以试验产品的不同应用。

显示厄运可以在计算@边缘交互地运行,这将是推动产品上性能界限的方式,并且有一个有形的演示,我们可以指向地面的股份 - 展示令人兴奋的可能性@ Edge Presents Compute @ Edge礼物。让我们探索我们如何做到。

厄运是1993年由ID软件开发的游戏,并于当年12月发布。 ID软件已成为开发高质量的2D游戏的生活,但是在1992年的Wolfenstein,然后举行了次年,他们将历史悠久的飞跃进入3D,利用了快速发展的PC硬件景观来推动行业的边界。

1997年,厄运是在1997年开放的,自述人员携带这些词,“将其移到您最喜欢的操作系统”。许多粉丝只是这样做,厄运被移植到数百个平台,从显而易见的是模糊的。作为厄运和员工速度的粉丝,我想测试计算@ Edge的潜力。以下是我将这种标志性的视频游戏带来计算@ Edge的方式。

值得注意的是:Fabien Sanglard的“游戏发动机黑书”是这个项目中经常被称为奇妙的资源。这是关于沃尔芬斯坦的另一本关于Wolfenstein的书,很深远地进入游戏开发历史的关键时刻,并正在娱乐和教育。

获取独立于平台的代码(即代码不依赖于任何特定的体系结构/平台SYSCALL或SDK)编译和运行。这是大多数人都将考虑“游戏玩法”。

根据目标平台替换特定于平台的API呼叫。这是主要处理输入和输出的代码,包括渲染和音频。

对于C绑定没有官方公共接口,因此在家中尝试,您将必须从速度 - SYS箱中推断C API。

在没有渲染或音频上播放的厄运运行或在Compute @ Edge上相当直截了当。 CodeBase在每个函数名称上都有前缀,方便地使用“i_”来实现所有实现特定功能,因此易于通过CodeBase并从编译中删除这些功能。一旦完成了,我使用WASI-SDK来定位母乳二进制。 WebAssAseMbly旨在编译本机代码而无需大惊小怪,因此这种变化非常直接。

我需要使游戏作为网上装配二进制文件所需的修复与在32位计算时开发的厄运有关。代码假定指针的一些地方是4个字节,当时是一个完全合理的制作的选择。厄运中的数据从包含开发团队创建的所有资产的文件加载,并在发布时间内捆绑在一起。该数据直接加载到内存中并投用到它代表的游戏内C结构。如果这些结构中涉及任何涉及的指针,请在64位环境中加载数据将导致数据在结构上正确覆盖,从而导致意外行为。这些相当简单地追踪,并且最初会导致相当明显的撞车。

为了获得在Compute @ Edge上运行的公共代码,我必须重构厄运使用的传统游戏循环。典型的游戏将初始化,然后在无限循环中运行,进行输入和gt;仿真 - >以所需的频率逐渐滴定,从键盘,鼠标或控制器等局部输入设备上取消输入,并输出视频和音频。然而,在Compute @ Edge中,平台最终将释放这样的过程,因为意图是为了启动实例,请执行一些工作,然后返回调用者。因此,我完全删除了循环并将实例更改为仅运行单个游戏帧。

在以下部分中,我将详细了解每个步骤。

在视频游戏中,保存到播放器的最终图像的内存称为帧缓冲。在现代游戏中,帧缓冲器通常在专业的GPU硬件中构建,因为最终图像通常是在GPU上运行多个管道步骤的结果。但是,1993年,渲染是在软件中完成的,并且在厄运中,将在基本C阵列中的程序员中使用最终缓冲区。这种设计使厄运移植到新的平台相对无痛,因为它给开发人员提供了一个简单,可以理解的起点来工作。

在Compute @ Edge的情况下,我想将帧缓冲返回到播放器的浏览器,在那里可以显示它。这与使用C API写入响应机身的CAPI时一样简单,然后在下游发送该正文:

当浏览器中运行的客户端从Compute @ Edge接收HTTP响应时,它将解析帧缓冲并在浏览器中渲染它。

在这个新模型中复制游戏循环要求我们在某处保存状态,以便当我们调用Compute @ Edge供后续帧时,我们可以告诉我们在游戏中的新实例。我能够利用游戏中存在的节省负载功能,最初提供了将游戏节省游戏状态的磁盘,然后重新加载游戏并继续在他们离开的地方进行播放。

我使用与帧缓冲区的状态相同的机制:在游戏框架的末尾,我调用了保存系统以获取代表游戏状态的缓冲区,然后我返回到帧缓冲区时返回HTTP响应时返回到帧缓冲区呼叫者。

//获取到FrameBuffer字节* Resp = GetFrameBuffer(& FrameBuffer_size)的指针; //获取GameState,将其附加到帧缓冲区resp + fb_size = getgamestate(& endy_size); Bodywrite(BodyHandle,FrameBuffer,FrameBuffer_Size + State_size,......); senddownstream(手柄,bodyhandle,0);

随附此更改,修改客户端以分离帧缓冲和状态并保持本地存储的状态,同时在浏览器中显示帧缓冲区。下次发出计算@ Edge的请求时,它将在请求主体中传递该状态,然后将计算@ Edge实例从请求身体读取并进入游戏,如下所示:

此时,如果我们运行我们的游戏框架,它将发生,好像它在保存游戏状态后发生勾号。

我们需要的下一件事是用户输入,所以玩家实际上可以播放游戏!厄运的输入系统是用输入事件的概念抽象的。例如,“播放器按下键”w,'或“播放器移动鼠标x距离。”我们可以使用标准的JavaScript事件侦听器在浏览器中生成浏览器中的输入事件,该浏览器将使用标准的JavaScript事件侦听器更轻松地预期:

document.addeventListener('keydown',(事件)=> {//保存事件。{//保存事件以稍后的表格中的表单});

我在使HTTP请求计算@ EDGE时,请将这些输入事件与状态一起发送。然后,实例将它们解析为我们可以在运行帧之前传入游戏引擎的表单。

这个演示的第一个工作版本在每轮旅行中达到〜200ms。互动游戏是不可接受的。典型的游戏在33毫秒运行,它转换为30fps或16ms,转换为60fps。鉴于延迟将是我们更新频率的非平凡部分,我决定瞄准50毫秒,这是对基本版本的4倍改善。

我设法实现实现的许多优化在运行连续游戏循环到运行单个帧时居中居中。许多游戏系统围绕每个刻度为前一帧的三角洲的概念设计。游戏保持状态不会在保存游戏中捕获,但是使用每个帧进行决策。许多这些系统需要调整,以确保功能正常工作并出于性能原因。如果他们正在工作好像不是第一帧,那么许多这些系统都可以获得最佳,此时初始化了大量变量和状态。

该游戏在启动时做了许多预测,主要涉及三角形,用于对世界空间计算进行视图空间。这些预先计算的表也需要了解游戏的屏幕分辨率,这就是他们在运行时完成的原因。出于我的目的,我正在保持渲染分辨率修复,我可以嵌入表格到编译的二进制文件,并避免每帧执行此启动计算。

我设法让游戏每次刻度为50-75毫秒运行。仍然可以做到这一点,可以将这种越来越靠近博览会,但这证明我们可以在Compute @ Edge上迭代这样的项目。

这是我第一次进入Compute @ Edge,并且我不确定在调试和迭代方面如何期待。该平台正在积极和不断改进,并且在整个三周内工作,我看到了改进,成形,提高了部署可靠性和调试性。具体而言,我想调用日志尾拖,这让我可以在近实时看到厄运出来的印刷品。在相当不透明的C程序迭代时,特别是在我有渲染工作之前,看到这些印刷品对调试问题势在必行。总的来说,部署到计算@ Edge类似于在传统的视频游戏控制台上工作。

要清楚,这不是运行实时游戏需要在及时频率的实时游戏的理想解决方案。通过以这种方式运行这种排序游戏,没有真正的优势。该实验的目的是推动平台的界限,创造一个引人注目的演示,以发现和展示的可能性,并为平台提供灵感和兴奋。利用这个平台的视频游戏肯定使用案例,我们很高兴继续调查为更多行业进行推动的产品来调查计算@ Edge。

如果您想自己尝试演示,我们将在我们的开发人员中心运行。一探究竟。

我们不时向即将到来的活动,新产品,&amp发送电子邮件;最新的行业趋势,但只有你想要他们。选中该框以同意接收这些消息。

通过提交您的请求,您同意您在美国迅速传输的信息,以便处理与我们的隐私政策一致。