【问题标题】:How do Real Time Strategy games work in PHP?实时策略游戏如何在 PHP 中运行?
【发布时间】:2012-03-17 05:05:45
【问题描述】:

Travian 或 oGame 等一些 MMO 即时战略游戏是用 PHP 编码的。

您能否简要解释一下这样的游戏在幕后是如何运作的?游戏如何在没有玩家请求的情况下进行实时数据库更新?

此外,在运行具有 1000 名活跃玩家的 RTS 游戏(例如 Travian)时,需要什么样的服务器负载/带宽?

【问题讨论】:

  • 我不会在 PHP 中编码,即使它可以完成。我会在 NodeJS 中编写代码。
  • 嗯,这就是我的想法,但是 Travian 和 oGame 非常“有名”,而且它们是 PHP。我不是说这是正确的方法,但它似乎是可行的。
  • OGame 是几年前由一个普通的私人开发者作为一个业余项目编写的(相信我,你不会希望看到任何真正旧的 OGame 代码现在已经被替换)。在这一点上,node.js 甚至还不存在,python 并没有真正广泛用于 Web 应用程序。因此,除非您想使用 Perl、Java 或 ASP,否则 PHP 几乎是唯一的解决方案。
  • @AlienWebguy 你能告诉我为什么你喜欢NodeJS而不是PHP,如果你想做像Travian这样的事情吗?

标签: php database mmo


【解决方案1】:

尽管这个话题已经相当老了,但我确实认为我仍然对您的问题有一个“更好”的答案(如果我自己可以这么说的话),然后是模糊的“更新由 cronjobs 完成”的答案。

Travian 即通过使用 javascript 给您一种实时的错觉。后面实际发生的情况如下:

玩家 A 向玩家 B 发送攻击。在 MySQL 数据库中,这会记录有到达时间戳。每次玩家 A 更改或刷新页面时,都会启动一个脚本(通过使用包含)来检查与该玩家有关的任何活动(援军到达、攻击到达目标等)。该脚本显然会检查当前时间并查看时间戳小于当前时间戳的所有活动。这意味着该行动应该已经发生。就在那个时刻,动作实际上得到了处理。

这也意味着,如果玩家 A 和玩家 B 都没有再次登录,则永远不会计算攻击,除非其他人也攻击了玩家 B - 然后玩家 B 和攻击玩家的所有活动都将被处理。

【讨论】:

  • 谢谢。这是我想多了之后想到的:)
  • 唯一的问题是,当一个攻击影响了高分或者像在ogame中那样会在战场周围制造一些碎片。因此,即使两个玩家都没有登录,服务器也必须处理这些战斗(在高分的情况下,这可能每小时都会进行一次......对于碎片,这可能更频繁)。此外,尽可能使用空闲 cpu-time 来计算这些更新也会很好。所以想象一下,晚上每个人都执行他的操作并注销.. 早上服务器需要为每个人计算:)
  • 那么他们如何计算存储中的大米、木材等正在增加?很有意思。有相关文档吗?
【解决方案2】:

通常有两部分:Web 界面和后台守护程序(通常称为“事件处理程序”)。

Web 界面执行所有只读内容和无害的事情,而竞争条件根本不是问题 - 密码更改、重命名等。

诸如建造单位或与其他玩家战斗等更重要的事情会提交给事件处理程序,在那里它们将被检查、验证并存储,直到达到执行时间。在这个地方而不是在 web 界面中执行检查的好处是您可以完全消除竞争条件的风险(例如发射包含行星上所有单位的船只,同时建造一些昂贵的东西,这基本上会导致重复可用的单位播放器),只要您确保在给定时间仅运行一个动作/事件(例如,没有多线程、多处理等)。

如果您的不是完全实时的,而是使用“滴答声”(例如,动作仅每 x 分钟发生一次),您当然可以使用 cronjob 而不是后台守护程序 - 但是您需要使用其他方式来避免竞争条件.


在我自己的游戏中,我有一个后台守护进程,它有一个类似 RPC 的接口,所以在 web 接口中我只需调用一个函数syncCall('someFunction', ....);,然后它将通过套接字连接到后台守护进程并执行给定的函数,返回任何内容该函数返回。

但是,如果我现在写一个新游戏,我肯定会使用异步解决方案,例如 node.js 或其中一个异步 python 框架。它消除了拥有两个不同部分的需要 - 但对于某些部分,您必须注意锁定,因为每当您从节点本身调用的函数之一返回时,可能会执行来自另一个事件的回调。

【讨论】:

  • 那么事件处理程序不是用 PHP 编写的,或者很可能不是,对吧?
  • 如果你对所有事情都使用相同的技术,这通常很容易,所以在我的例子中,它是用 PHP 编写的。这样做的好处是我可以包含相同的函数库,而不必用两种语言编写相同的东西。
  • 非常感谢您的出色回答。 this 你的意思是 “我有一个后台守护进程” 吗?
  • @Accountantم:我在screen 会话中运行它(所以技术上不是守护进程);现在我可能会使用 docker 容器或 systemd 服务来运行它。最重要的是,我当然不会再使用 PHP 了 ;)
【解决方案3】:

更新最有可能由 cron 作业完成,或者另一种可能性是它们在登录/任何页面更改时进行。带宽可能会有很大差异,具体取决于活跃用户的数量、有多少可能性等。我认为您应该在 localhost/test hist 上使用示例请求对其进行测量,因为它在很大程度上取决于项目。

另外,如果有相当多的玩家等等,我会考虑不要用 PHP+MySQL 编码,而是用 Python&PostgreSQL,甚至可能是 Java,或其他系统。

【讨论】:

  • Cron 工作?这是否意味着他们必须每秒执行一次 cron ?因为它实际上是实时的。即使您不在线,其他玩家也会实时看到其他玩家操作的结果。
  • 我认为这些是半实时的,也许他们每分钟左右都会这样做。
  • 好吧,一旦你对他人的攻击“命中”,你就可以看到结果,所以它必须立即存储在数据库中的某个地方,对吧?人们可以在攻击之前从一个账户向另一个账户派遣军队,所以它必须是实时的,或者至少他们的后端必须每秒钟检查一次变化,甚至更多。我说的对吗?
  • 我从未玩过这些游戏,但我确信只有定时操作(攻击、部署等)使用 cron/事件处理程序(由 ThiefMaster 提到),其他的(开始攻击,部署)由点击本身完成。对于定时,我不知道哪个更好,你必须决定它是否必须是 100% 实时的。
  • 为什么 Python/PostgreSQL 优于 PHP/MySql ?速度?
【解决方案4】:

正如 user1842120 所说:Travian 实时是一种幻觉..

我将简单解释一下“实时”在网页游戏中的工作原理...

假设有 3 个玩家,其中 2 个在线..,P1 攻击 P3,当重新加载页面或更改页面时,脚本将被激活,P3 将被攻击..

P3 离线,他看不到攻击,但它正在发生。,当 P3 上线时,P3 看到他/她的村庄正在受到攻击,简单地说:

您只需要一个客户端(在线用户/页面上的浏览器)即可运行游戏....

【讨论】:

    【解决方案5】:

    我认为我会使用 iframe 和 javascript 来更新它们。因此,就像隐藏的 1 个信息 iFrame 和 qui/output iFrames,其 url 指的是 php,并且一直在更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 2021-08-10
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      相关资源
      最近更新 更多