实施动态奖励制度

时间:2011-08-04 09:48:45

标签: java poker

我一直在开发在线扑克游戏。但我一直在撞墙。我想在系统中实施奖励,但我希望它们是动态的。意思是我不想重新编译我想要添加的每个奖项。

我考虑过为每个奖项使用Python代码。然后,当服务器检查用户是否有资格获得奖励时,它运行带有Jython的python脚本(服务器在Java和Netty NIO中),如果函数返回某个值,我将奖励授予用户。哪个可以工作但是可能有更高效的技术,每次我需要检查用户是否获得奖励时,不会强迫我运行数百个python脚本。

什么时候进行这些检查的最佳时间?我已经考虑了一个钩子系统,我将指定钩子([onconnect] [ondisconnect] [chatmessage.received])。哪个也可以工作,但感觉有点粗糙,我仍然需要从数据库运行所有脚本。

4 个答案:

答案 0 :(得分:6)

如果我是你,我会有一个完全独立的过程来授予奖励。它可能每天在包含所有播放器/游戏数据的底层数据库上运行一次。

您的面向客户的核心应用程序了解奖项,但它所知道的只是它从数据库加载的数据 - 例如标题,图像,描述,可能有多少人获得奖励等等,以及(基于数据库表格获得该奖项。

您的“奖励过程”过程只需按批次模式运行,每天/每小时等一次,并为符合条件的玩家颁发新奖励。然后面向客户的核心应用程序通知他们,但实际上并不知道如何授予他们的聪明才智。这使您可以随时自由地重新编译和重新运行奖励,而不会对核心应用程序产生影响。

另一种方法,取决于您的奖励受限制,将是编写一个简单的规则界面,允许您在数据中定义规则。这对于实现你所描述的内容来说是理想的,但在我看来,这对于没有多少奖励来说是相当多的工作。

PS - 在运行类似在线扑克服务器的东西时,你会一直遇到这个问题的版本。您绝对需要开发一种部署新代码的方法,而不会中断您的服务或有停机时间窗口。从长远来看,围绕以Java为中心的奖励代码解决方案并不能解决这个问题。您应该查看有关运行真正24/7服务的文献,有很多方法可以解决这个问题,而且这些日子实际上并不困难。

答案 1 :(得分:3)

我能想到很多选择:

  • OSGi如上所述 - 它需要付出代价,但可能是那里最通用和最动态的解决方案
  • 如果你打开重启(只是不重新编译),一个众所周知的文件夹和spring中的jar集合会给你一个更便宜但同样通用的解决方案。只需让你的奖励bean实现一个标准的界面,就像豆子一样,让春天将所有可用的奖励计算在你的检查器中。
  • 如果奖励执行是相当标准的,并且奖励之间的唯一差异是规则本身,您可以使用某种脚本配置。那里有很多选项,从你描述的python(除了我要管理所有奖项的几个大脚本),到基本的正则表达式,LUA和Drools在中间。在所有情况下,您都在寻找某种规则引擎架构,这种架构在奖励可以触发的方面具有灵活性,但在奖励可以带来的方面(即完美的成就)方面却没有多大的灵活性。

答案 2 :(得分:3)

批量创意的答案有些评论: Implementing a Dynamic Award System

批处理可以在单独的服务器/机器上进行,因此您可以随时重新编译应用程序或重新启动服务器。可以使用例如添加罐子并重新启动服务器的上述方法来处理新的奖励,也可以随时引入新的批处理作业,等等。因此,您的核心应用程序在99%的时间内运行,批处理服务器可以经常重启。所以单独的批处理机器很好。

当您需要部署新版本的核心应用程序时,我认为您可以通过向用户发送维护通知来停止,部署和启动它。这种方法甚至被顶级扑克室用得很好(例如FullTiltPoker这样做,现在它由于许可证丢失而下降,但他们的网站说“系统更新”:)。

因此,版本更新的一种方法是在非工作时间重新部署/重新启动。

另一种方法是实时更新。通常,它是通过将用户逐束迁移到新版本来完成的。所以同时一些用户正在使用旧版本,有些用户正在使用旧版本。扑克软件不是很酷,不同版本的用户可以互动。但是,如果您确定版本的“兼容性”,则可以使用该方法,例如在登录时检查用户的客户端版本。

在我的回答中,我试图说你不需要为你的代码引入24/7支持逻辑。保留硬件的系统可用性问题(故障转移,负载均衡器等)。您可以遵循用于编写代码的任何好技术,只需记住您的关键核心逻辑不经常部署(例如每周一次),并且如果需要,可以随时更新/重新启动批处理部分。

答案 3 :(得分:2)

据我了解,您可能不必从应用程序运行外部进程也不必使用OSGI。 只需创建一个简单的Java接口,并将每个插件('award')实现为实现接口的类。然后,您可以简单地编译任何新插件,并使用Class.forName(String className)在运行时从应用程序中将其作为类文件加载。 这种插件所需的任何逻辑都将包含在接口上的方法中。

http://download.oracle.com/javase/1,5.0/docs/api/java/lang/Class.html#forName(java.lang.String)