开个新坑:模板快速开发io类游戏怎么做?

开个新坑:模板快速开发io类游戏怎么做?

一直很喜欢io游戏,经常在国外聚合网站上尝试各种各样的io游戏。 如果没有专用的加速器,大多数游戏都无法流畅运行。 国产io游戏非常少见,大部分都是商业发行的游戏。 与网络上的免费版io游戏相比,无论是数量还是创意都远远落后。 io游戏对抗性很强,很容易失去新鲜感,所以我认为网页版io游戏以其丰富的数量和创造力真正体现了io游戏的内涵。

我计划维护一个开源项目,用于快速开发网页io游戏。 我会尽量用最简单的方法解决网络同步等问题,让开发者可以专注于游戏性。 我希望中国能有很多有创意的想法。 可以流畅玩的网页io游戏(可能已经有很多了,只是我没找到)。

网络同步方式

首先是选择网络同步方式。 目前主流的网络同步方式有两种:状态同步和帧同步。

两种同步方法都有各自的优点和缺点。 不同的游戏模式适合不同的同步方法。 下面从几个不同的角度对两种同步方式进行比较。

服务器代码编写复杂度:帧同步较好。

状态同步需要大量的服务器代码开发。 几乎所有的游戏逻辑、物理碰撞等都需要在服务器端处理。 客户端只是将用户输入传输到服务器并渲染返回结果,几乎没有任何逻辑处理。 因为如果在客户端本地进行碰撞等逻辑处理,会因为网络延迟导致判断结果不一致。

例如,玩家A发射的子弹击中本地页面的玩家B,则判定玩家B在本地死亡。 然而,由于玩家A的网络较差,玩家A实际上在1s前攻击了玩家B的位置。 此时,玩家B的位置是客户端,根本没有受到任何人的攻击,但却莫名其妙地死亡了。 如果被击中这么重要的判断应该在本地,即玩家B的客户端中进行,就会导致玩家A与玩家B战斗很长时间没有任何效果,在玩家B的客户端也会发生同样的情况。 A长时间的攻击不会对他造成任何伤害,因为他还停留在前1秒。

为了保证逻辑判断的一致性,重要的逻辑判断必须放在服务器上。 这就导致服务器端代码编写量很大,而且一个游戏必须写一套服务器代码,不能被不同游戏通用。 如果你是游戏服务器开发者还好,但对于使用Unity3D、cocos2d等游戏引擎的单机游戏开发者来说,那就是噩梦了。 服务器代码基本上是使用socket.io加上一些开源js物理引擎编写的。 没有任何带有图形界面的ide。 想象一下,您已经制作了一张精美的瓷砖地图。 如何将重要的碰撞区域放在服务器端的地图上? 毛呢布料。 事实上,由于下面提到的原因,大多数io游戏都是状态同步的。 这就是为什么io游戏看起来场景简单,甚至没有场景。 空旷的地方,一群人正在打斗。

我曾经尝试使用另一个玩家C作为宿主进行逻辑判断,然后分发给大家进行渲染。 这样逻辑就可以写在Unity3D等游戏引擎中游戏开发玩家遍历,服务器只负责分发。 玩家A->服务器->玩家C,判断完成后->服务器->玩家A游戏运营,但是双倍的网络延迟,即使是国内网络也无法流畅玩游戏。 如果再优化一下也许会更好。

帧同步不需要服务器进行逻辑处理。 服务器只需要简单的分发数据包。 玩家A的攻击操作(如鼠标左键)会同步到玩家A和玩家B的客户端。两个客户端同时判断玩家A的攻击并得到相同的结果。 因为每一帧都是同步的,所以所有两个客户端的玩家位置都是相同的,并且做出的攻击决策也必须相同。 那么如果玩家A有1秒的高延迟怎么办? 那么A按下攻击按钮1秒后才会看到攻击效果。

客户端代码编写复杂度:状态同步较好。

状态同步的客户端只进行显示,不进行逻辑处理。 任何游戏引擎都可以轻松完成这项工作。

帧同步要复杂得多。 它必须保证每个玩家客户端的计算结果是一致的。 这里有一个随机数问题。 例如,玩家A攻击玩家B,造成10到20点之间的随机伤害。A的客户端随机造成20点伤害,玩家B的客户端随机造成10点伤害。 我们需要一种随机方法,能够在同一位置给出相同的随机结果。 幸运的是,有一个伪随机函数(线性同余生成器)。 我们只需要在游戏开始时向每个玩家分发相同的种子即可。 使用相同的种子,每次获得的随机数都在每个玩家的手中。 相同,因此玩家AB可以获得相同的伤害数。 但问题并没有那么简单。 为了获得相同的随机结果,不同客户端的执行顺序必须完全相同。 如果玩家A在计算伤害之前先于玩家B使用过一次随机函数,那么双方的伤害就会不一致。 为了保证执行顺序的严格一致,在编写过程中,一些没有固定顺序的数据结构,比如js的map、C#的字典等,一定要谨慎使用,因为这些并不能保证顺序一致3D动画,可能会因为内存地址等原因被遍历。 返回顺序不一致。

除了随机问题之外,还有物理引擎问题。 大多数物理引擎都不是确定性的,因为它们使用大量浮点数。 由于精度等问题,浮点数的计算结果在不同的机器上是不同的。 即使两个玩家之间的计算结果相差几位小数,在长时间的计算过程中也会出现蝴蝶效应,导致两个客户端的计算结果相差很大。 由于帧同步只同步玩家的操作,并没有同步游戏内对象的状态,导致两个客户端之间的差异无法得到纠正。

中途加入游戏:更好的状态同步

状态同步对于中途加入的玩家来说非常友好。 您只需要将所有对象的状态同步给新玩家,几乎不需要任何额外的工作。

帧同步比较复杂。 由于服务器中没有对象状态,中途加入的玩家需要重新执行从第一帧到加入时的所有历史输入帧,才能同步到与其他玩家相同的状态。 这种追赶最新帧的过程称为帧追逐。 想要赶上别人,肯定需要更快的执行速度。 这个追帧的过程相当于快进。

当开始时间很短时,帧追踪是可以接受的。 例如,大多数io游戏可以玩几十分钟。 如果在中间加入,以最快的速度追框游戏开发玩家遍历,则要等待几分钟甚至十几分钟。 跟上来。

所以使用帧同步的游戏基本上无法通过中通加入,比如王者荣耀。 比赛一开始就进行,中途人数满了就无法加入。 在大多数io游戏中,你可以随时进入和退出。 无需等待匹配,也不用担心人少时无法匹配。

服务器带宽要求:较低的帧同步要求

帧同步仅同步玩家输入,每次传输的数据量是玩家数量的倍数。 数据量小,小带宽足以满足多人同时在线。

状态同步时每次传输的数据量是根据游戏中对象的数量计算的。 需要同步的对象越多,传输的数据量就越大。 基本上这个量是远远大于玩家数量的,所以在使用状态同步的时候,需要能够让数百人同时在线,服务器带宽是一个必须考虑的问题。 服务器带宽并不便宜,是服务器的主要成本。

帧同步不需要考虑游戏丰富度和带宽的压力,可以做出内容更丰富的游戏。 相比之下,状态同步就相对单调了。

客户端游戏体验:更好的帧同步

帧同步:由于所有碰撞都是在本地进行,因此响应会更加灵敏,影响也会更强。

在客户端输入状态同步后,需要等待服务器返回才能看到结果。 延迟肯定是严重的。 即使延迟是40ms,在国内比较好,但是返回给客户端时也有相当大的延迟。

因此,帧同步可以营造出类似格斗游戏的感觉,但状态同步对于大多数io游戏来说也足够了。

防作弊:更好的状态同步

状态同步 由于所有判断都是在服务器上进行,因此不存在作弊的可能性。 所有关于帧同步的判断都是在本地进行的,而浏览器是一个完全开放的环境,所以基本上不可能防止作弊。 不过,对于io游戏这样的娱乐休闲游戏来说,反作弊似乎并不是主要的考虑因素。

项目介绍

为了让游戏开发者能够快速使用,我选择先实现帧同步版本,主要是因为一个服务器可以用于各种游戏,所有的游戏逻辑都写在客户端,这样可以保证原有的开发流程越多越好。 降低学习成本。 以后有机会的话会实现状态同步。

服务器使用nodejs+colyseus。 colyseus() 是一个开源游戏服务器。 由于不需要编写帧同步的服务器代码,因此基本上可以一次编写并被所有游戏使用。

游戏引擎使用cocos2dx Creator,对于Web支持更好。 Unity3D、Godot、Egret如果以后有更多人需要的话可以添加。

下一期主要是用一个简单的游戏来实现帧同步,主要包括服务器、cocos2dx Creator的帧锁定、玩家输入的分配,以及测试box2d的物理引擎是否会造成不一致。

如果您觉得还有什么遗漏,欢迎补充。

欢迎游戏开发者和游戏爱好者提出意见和建议。 您的关注是我创作的动力。 谢谢。

文章来源:https://indienova.com/u/cyclegtx/blogread/11315