这是我在博客上所撰写的一系列文章。因为这些文章已经获得了一部分测试人员的肯定,所以我决定将其分享给全世界的读者。
故事始于3月。前年,我致力于DeNA Canada,帮助他们创建第一家工作室Canadian工作室(那时我是他们的第二名员工),同时也致力于招聘等等有趣的工作。在这一过程中我沉浸于“受服务器驱动”的游戏开发理念中——我在之前几款游戏中便经历过,但是程度却远不及我们在DeNA中所经历的。早在《巴哈姆特之怒》攻占排行榜之前我便开始接触这种理念——甚至在DeNA也没人真正相信这一理念能够大受欢迎,除了日本市场已经表现出了对于纸牌战斗游戏的欲望,并相信同类型游戏也将会取得成功。我在DeNA中待了1年时间,并学到了许多,其中有9个月时间我使用了Unity去创造基于服务器的游戏,并发现这种游戏架构具有非常大的潜力。如果你想知道DeNA和其它创造出畅销游戏的公司是如何通过游戏赚取利益的话,我会告诉你,受服务器驱动的游戏架构便是答案。
unity 3d
不管怎样,这是故事的开始。
首先我们需要找到一份新工作,或决定在成长过程中自己到底想要做些什么。其次,当然需要开始致力于自己的新游戏。我并不是那种会呆坐着去等待机会自己上门的人,我会不断挑战自己的极限,并且在短暂休息过后继续努力工作。
在仔细思考了自己到底想要创造怎样的游戏后,我发现了技术和设计具有一个明确的基础层面。不管你创造的是怎样的游戏,这些都属于核心建筑模块,并且我可以立刻就开始着手设计。
在我详细分析这些要点之前,让我们着眼于这一新项目的一些基本假设:
1.手机(因为缺少硬件所以在那时候只能选择Android)
2.免费游戏(IAP)
3.基于Unity的PHP服务器/终端
最近我与不少人提起了服务器/终端技术,似乎当前存在着2大阵营:
Java很少人能理解的Ruby和/或node.js等较难懂的框架
对此我不想谈论太多细节,但是归根结底,最简单的事实便是我不知道是否应该坦然地深入研究任何内容。在开始投身任何技术项目时,我们必须记得的一件事便是,你不仅希望获得自己想要的解决方法,同时它也能帮你轻松地找到开发者并在未来不管壮大团队。你的技术性解决方法的未来是,我们将更加难以找到熟悉技术的程序员,并且更加难以确保他们富有较高的效能。
关于像Java这样的解决方法,你至少在知识方面是有保障的,因为它会提供关于产业和教育世界的支持去帮助你训练未来的雇员/团队成员。那node.js/ruby又是怎样?还行。Python呢?这是一种“对象导向型”系统,带有自己的复杂性。
我个人的代码风格非常简单——主要有几点原因。首先,我经常会在各种语言间穿梭着,所以熟记特定系统中的特定语言间的细微差别并不能引起我的兴趣。其次,我发现最有用也是最容易理解的代码(同时也是最容易调试的)便是那些不会隐藏在各种抽象层/模版/特定语言功能中的代码。但这只是针对于我自己。也许我是一名糟糕的程序员,但浏览程序员的代码之树却一点都不糟糕,我甚至可以自信地说这至少是看待事物最合理的方法。
我好像有点离题了,好吧,让我们再回到整体上。
PHP或非PHP上面说了这么多,我唯一知道且信任的服务器语言便是PHP。在之前它从未让我失望,它的确是一种可合理伸缩的工具,有许多开发者都在使用该语言。同样地,我可以立即运行php并清楚自己能够快速前进。
所以让我们来说说上述的要求,特别是着眼于项目所需要的可重复使用的服务器框架。
服务器端受数据驱动的开发从游戏设计角度来看,分割游戏数据并整合到“云端”是最佳做法。
不间断的架构似乎萦绕着许多负面描述。我理解人们对于DRM等等的担忧,但从游戏设计角度来看,分割游戏数据并整合到“云端”是最佳做法。
这与“压榨用户”或侵犯版权没一丁点关系。基本事实在于,对游戏设计师来说,在如今快速变化的市场中能够进行更新(推出新内容或只是调整一些道具或任务的平衡),即只是调整调整服务器上的一些参数也是制约游戏能否成功的关键元素。
同时需要注意的是我并不是在宣称自己将使用“云端”去处理游戏中仆从的个体AI运转—-但是我认为作为2013年的游戏还有许多“必须拥有的”功能。即:
优势/服务端“必须拥有的”功能/永远在线设计1.持久的/云端玩家状态保存——设备间的移动,没有更多解锁/重新开始一款游戏
2.服务端数据允许你调整平衡/在发行后调整你的游戏
3.如果设计合理的话,服务端数据将允许你无需新客户端的推动而进行内容更新。这在iOS上非常重要,特别是当之前简单的游戏调整需要2周的周转时间去等待游戏最新构建的完成。
4.整合更大的用户登录/注册系统和第三方付费/虚拟货币平台去减少/删除用户开始游戏的摩擦,并开始在你的游戏上花钱。
服务器设计——4个元素从服务器设计角度来看,根据上述内容我们的服务器拥有2个关键元素,甚至可能是3个或4个(根据你所瞄准的平台)。
我们的服务设计的前2个元素可以划分为:
1.静态内容(元数据)
2.动态内容(玩家数据)
元数据元数据可以是你的游戏中任何静态内容,即不会因为玩家而发生改变。这可能是你的游戏中所有武器的库存,或者是所有关卡名称,对话文本等等的列表。我会建议你储存所有的这些静态信息服务端,如此你才能在发行后轻松地进行修改并更新。我并没有在开玩笑。这包括你的大型RPG中的任何武器,任何道具,任何角色细节以及整体故事。在服务器上保存所有的这些内容后你便能够动态地进行查询。也就是所谓的“脱机游戏”—-我在这里所说的一切都不会阻止脱机游戏,但最主要还是取决于你的决定。
玩家数据你的游戏中的动态内容是针对于玩家的用户数据,即储存自玩家开始游戏并在冒险中不断前进。这将包含他们穿越游戏技术之树的过程,他们的库存以及解开后的关卡等等。这也将包括一个更复杂的保存系统,即储存场景中个体对象的微状态。当玩家首次打开游戏/有效地“同步”游戏状态时,所有的这些信息将被带到服务器并进行动态分解。你所玩过的每一款MMO或者你在过去3至5年里玩的一些其它游戏都会做这样的事。不幸的是并不足以进行云端保存。
我们服务器设计的第3个元素与第1点相关:
内容传递随着游戏变得更大且更复杂,你便更希望能够动态地推动新内容或面向用户进行更新。创造一个能够提供这类机制的系统将帮助你避免一些麻烦,特别是当你尝试着向用户传递补丁或更新内容时。这与下载游戏中一个全新关卡或区域的特殊NPC所使用的纹理一样简单。像Unity等工具能够为内容下载提供一个强大的http类或AssetBundles,这能让你更轻松地整理游戏中的任何内容并根据需求传递给用户。你可以根据需求做到这点,或设置“自动更新”(在游戏发行或其它时候运行)。根据你所支持的平台,你可以选择不同的方法。
对于手机来说第4个元素更加重要,但它同样而已适用于普通的PC开发:
第三方集成今天,Facebook便是一大最受欢迎的第三方集成。你需要考虑的主要元素便是,你是否想要创造属于自己的用户注册/登录系统或使用第三方集成。Facebook是其中一个,市场上的其它集成还包括ScoreLoop,Playtomic等等。我所选择的是经过优化的PlayPhone,但却未100%决定好。
牢记着上述元素,下一次我将详细分析我是如何处理第1个元素和第2个元素。第3个元素较为直接,所以在一开始并不是什么大问题,但是我也将描述我是如何计划处理该元素。就像我之前所提到的,第4个元素将被分别覆盖,尽管我已经决定好使用哪一个系统了。
接下来我将根据自己的实验具体描述服务器的后端。
现在我们知道自己正在尝试着做些什么,让我们进一步讨论该如何做到这些。
需要说明的一点是,我的方法将会有悖标准,但是根本原则是基于我使用类似系统的多年经验,即从网页开发和游戏开发角度来看。我的职业是穿梭于这两者之间。也许几年前这对我来说有点陌生,但现在它们已经有效第与这一新方法融合在一起,我也发现自己能够更轻松地支持最后结果。
我在这一试验中的主要目标便是重新使用现有的代码和库存去最大化我在使用最少代码时的结果。作为单人的独立游戏开发者,我比编写一个完全的内容管理系统去处理项目的静态和动态元素面对着更大的挑战和任务,并且实际上,有些人可能已经编写了我想要做到的大多数内容。
在我详细分析每一个系统的细节前,让我们基于我的静态和动态系统而着眼于功能的更高级别设置,以明确是否存在一些共同主线能够帮助我缩小方法。
1.在标准LAMP(游戏邦注:LAMP代表Linux/Apache/MySQL/PHP,尽管在我完成前apache元素将被换为更有效能的网页服务器)中运行。这将托管并扩展系统的“已知量”,即并不需要一些难懂/专业知识。
2.无需重新编写大量代码而重新使用/提供更多功能。
3.为编辑游戏数据提供给我基于网页的界面(静态元数据或玩家游戏数据)。单单基于该原因,编写一个定制PHP/MySQL应用是不够吸引人的。为基于数据的应用创建一个容易使用的界面需要比创造核心功能花费更长时间,所以我希望现有的解决方法能够解决该问题。
4.轻松地伸缩—-不管是我能够接通亚马逊还是配置到云端系统的现有“工具”。我不相信云端系统能够彻底扩展一款应用,但是它们却能够为一种解决方法提供一个起点,并帮助我进行快速配置。你最后需要的便是让一款应用变得受欢迎并且未计划扩展应用。
5.提供一个JSON界面(或轻松访问数据从而让我能够面向服务器交流层创造定制JSON应用程序界面)。在过去几年里我一直介于服务器API使用JSON界面,并真心喜欢该界面所具有的便捷性。再加上PHP能够有效支持JSON序列化和解析,从而推动着我去创建服务器交流层面。我将在谈及客户端/前端设计时详细分析这一点。
这涉及了我对系统更高级别的要求。让我们详细分析一些细节。
静态内容管理(元数据)任何游戏都需要大量静态数据,也就是我所谓的元数据。当着眼于游戏中关卡数的所有元素的价值时思考这些内容,一次特定的波动将包含多少敌人,一个特殊敌人有多强大,一个特殊游戏事件将给予玩家多少XP等等。
对于一款传统的单人玩家游戏来说,这些数据是以硬编码的形式出现在游戏代码中(或以最小的文本配置文件形式)。使用像Unity等数据,元数据可以被当成你的类的公共界面,即Unity于设计过程中在编辑器中所呈现的。这并不是一个复杂并快速的规则,但对于我们来说这却是一个不错的起点。
为了进一步了解,让我们分解假设的游戏中一个潜在的类,并分析你想使用怎样的元数据去测试服务器。
让我们假设我们的游戏将出现各种类型的敌人与玩家相抗衡。这些敌人可能也拥有健康,移动速度,破坏力(或每秒破坏力),射程等等属性。这些变量都是触及服务器的有效元素。如果我们让它们以硬编码形式出现在客户端,那么在我们的游戏发行后,我将不能再更新或修改这些机制,除非我们能够推出一个全新客户端更新/补丁。如果我们的游戏在发行时并不能达到有效平衡(游戏邦注:说实话,很少人能够做到这点),我们便会深陷于这些价值中,直到最终能够为游戏创造出更新/补丁。这是每一款游戏都应该考虑使用的方法。
同样的方法能够用于我们游戏中的每一方面。我们游戏中任何可行的任务,每个关卡所出现的敌人(和数量)等等都会在运行时从服务器中恢复,从而实现我们代码库的最大灵活性。
大多数程序员都听过“受数据驱动的设计”。关于这点的传统描述是分割数据而从代码/逻辑中驱动应用从而让所有内容变得生动起来。这便意味着许多应用都拥有本地数据库。
我在这里所说的是关于这一方法较为直接的延伸。
现在每个人都知道如何使用这一方法对客户端和服务器进行整体设计,接下来我们将开始设计JSON服务器API而来回传递信息,并开始创造我们的客户端/服务器交流堆。会越来越有趣的。