如何在Haskell中最好地同步游戏引擎和网络服务器?

12
我正在设计一个小型足球游戏,其中游戏引擎(计算玩家移动等)在服务器上运行,渲染和键盘/鼠标处理由客户端完成。对于服务器(Haskell),我想使用以下内容:
  • 用于客户端-服务器通信的Happstack
  • 用于游戏引擎的Yampa / Reactimate
每隔20ms左右,客户端应通过HTTP GET将键盘和鼠标事件发送到服务器,接收当前游戏状态(JSON编码的球和玩家位置)并进行渲染。我考虑使用SDL基础设施进行游戏循环,输入处理和渲染。
服务器基本上运行两个线程:happstack服务器接收HTTP GET请求,将键盘/鼠标命令放入队列中,从第二个队列中读取当前游戏状态,并回答HTTP GET请求。
第二个线程运行一个Yampa游戏引擎,如Yampa Arcade paper所述:游戏引擎尽可能快地计算新回合(无打勾号)并将结果放入渲染队列中。

Architecture

一般问题:这个架构看起来可行吗?

具体问题:如何设计服务器端渲染队列:是否使用Chan?如果游戏引擎的平均速度比客户端上的“打勾”更快,队列将变得越来越长。如何用Chan处理这个问题?

非常欢迎您的评论!

3个回答

6
能否再详细解释一下游戏本身的情况?当我想到足球游戏时,我认为这是一个需要实时反馈的游戏,其中输入应该即时处理,并且我期望玩家输入信息立即通过网络发送。20毫秒是相当大的延迟,我认为当玩家按住键盘移动角色时会感觉到卡顿,这种卡顿类似于某些类型的垃圾收集器。
我也不明白为什么您要在此类游戏(任何游戏)中使用HTTP,几乎所有游戏都使用UDP,我可能会选择这条路线。对于您的游戏类型,这个教程看起来非常适合学习这种东西。
我还会质疑您的网络数据格式选择,为什么要选择需要进行非平凡解析/格式化的格式?我想象一下,发送大量数据并频繁地这样做将增加显著的时间。如果我要使用字符串,我会尝试使用最简单的格式,需要非常少的解析。在我工作的相关系统中,它是一个使用套接字进行通信的多进程实时系统,最初使用xml字符串作为网络数据格式,效率非常低下,而且所有进程都在同一台机器上。
关于Yampa和服务器端渲染,如果我们将FRP视为实现游戏逻辑和实体的手段,我认为大多数网络游戏都有服务器和客户端实体。通常,可呈现的对象是客户端实体,不可呈现的对象是服务器实体,我想某些实体在两者之间都有表示。因此,在这种情况下,您可能希望在服务器端和客户端上都运行Yampa,并且我会尽量避免与服务器端渲染相关的任何内容。我认为可呈现的对象应主要停留在客户端。是否有特定原因需要从服务器发送渲染命令?

非常感谢,这正是我在寻找的输入类型!至于服务器端渲染:我希望游戏引擎计算玩家和球的位置(仅X、Y、Z坐标),并将其发送到客户端(通过渲染队列和HTTP)。我仍然需要完全按照您提供的链接进行工作,但它已经对我来说像是一条走过的死路了... - martingw

4

2
如果您感兴趣的话,我曾经用 Haskell 写过一个类似基于服务器和客户端的足球游戏。您可以在 githubserverclient)找到源代码。当时我还是一个 Haskell 初学者,遇到了一些关于线程的问题(并且 写了博客),从未真正完成这个项目,但至少您可以从代码中看到如何不做。 (最后我放弃了服务器-客户端架构,并写了 freekick2。)我认为架构本身是可行的。
然而,就像snk_kid所写的那样,我不知道为什么你想使用HTTP。要在网络上运行而没有(明显的)延迟,你可能需要使用UDP以及客户端预测(这里有一些信息资料)。

谢谢,安蒂!我会看一下你的代码!我想我也会跳过CS部分,这个UDP调试似乎有点复杂... - martingw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接