Node.js 存储游戏状态,如何?

node.js storing gamestate, how?

提问人:expressnoob 提问时间:1/16/2011 更新时间:8/24/2012 访问量:3418

问:

我正在用 javascript 编写一个游戏,为了防止作弊,我让游戏在服务器上玩(这是一个棋盘游戏,就像一个更复杂的跳棋)。由于游戏相当复杂,我需要存储游戏状态以验证客户端操作。

是否可以将游戏状态存储在内存中?这很聪明吗?我应该这样做吗?如果是这样,如何?我不知道这是怎么回事。

我也可以存储在redis中。这种事情对我来说很熟悉,不需要解释。但是,如果我确实存储在 redis 中,问题在于,在每一次移动中,游戏都需要从 redis 获取数据并解释和解析该数据,以便从头开始重新创建游戏状态。但是,由于搬家经常发生,这在我看来非常愚蠢。

我该怎么办?

JavaScript 数据库 节点 .js

评论

1赞 Marcus Whybrow 1/16/2011
这与 JavaScript 没有任何关系。你基本上只需要一个服务器,它可以处理所有不同的连接客户端,而且由于程序在内存中执行,所以它会很快!仅当您需要“保存”游戏时,才将游戏状态保存到数据库中。在代码中表示您的游戏状态!
0赞 expressnoob 1/16/2011
@Marcus谢谢,我正在征求有关实施的建议,因为这对我来说并不那么明显。如何在代码中表示游戏状态?
0赞 Marcus Whybrow 1/16/2011
@expressnoob变量和类。这些是工具,使用它们来表示游戏中的对象,例如 、 等。设计由您决定,并且特定于您的游戏。GamePlayerPiece
0赞 expressnoob 1/16/2011
@Marcus如何让它们在每个单独的游戏中在服务器上持久存在?
0赞 Marcus Whybrow 1/16/2011
@expressnoob 为服务器可能正在编排的每个游戏创建一个单独的游戏,并为每个游戏提供一个实例,那么如果“持久性”是指在服务器关闭后,您可以序列化所有对象并将它们保存到文件(或数据库)或以更定制的方式将其转换为数据库表。ThreadGame

答:

5赞 slebetman 1/16/2011 #1

如果你真的不想要 I/O 的开销,那么只需将游戏状态存储在一个由游戏 ID 键控的全局对象中:

var global_gamesate = {}

然后在每个连接上检查游戏 ID 是什么以检索游戏状态:

var gamestate = global_gamestate[game_id];

据推测,您已经拥有将客户端会话映射到游戏 ID 的机制。

通常,游戏状态很小,几乎不会占用太多 RAM。让我们悲观一点,假设每个游戏状态占用 500K。然后,您可以为服务器上的每 GB RAM 提供 200 万款游戏(如果我们假设每款游戏有两个用户,则为 400 万名用户)。


但是,我想指出的是,像MySQL这样的数据库已经实现了缓存(这是可配置的),因此加载最常用的数据基本上是从RAM加载的,并且具有较小的套接字I / O开销。数据库的优点是,您可以拥有比 RAM 多得多的数据,因为它们将其余数据存储在磁盘上。

如果你的程序达到了你开始考虑编写自己的磁盘序列化算法来实现交换文件的负载,那么你基本上是在重新发明轮子。在这种情况下,我会说使用数据库。

评论

0赞 Jeena 5/3/2011
并发性呢?如果两个客户端想同时更改相同的全局游戏状态,它们会不会相互干扰并搞砸状态?
0赞 slebetman 5/3/2011
Javascript 没有线程,因此不支持“真正的”并发。所有代码都是原子的,进程边界进入事件循环(在脚本的最后一行之后,进入 setTimeout/setInterval、ajax 回调等)。较新的 javascript 解释器支持工作线程,但在该模型中,所有线程只能通过事件循环进行交互,因此没有并发问题,因为不允许线程共享全局变量(每个线程都有自己的全局范围)
0赞 Herokiller 5/19/2015
例如,在重新加载时保存服务器状态(所有游戏的进度及其用户)的好方法是什么?
0赞 slebetman 5/19/2015
@Herokiller:如果希望在重新启动服务器时保留状态,请使用数据库。或者,如果您坚持不使用数据库,请使用 .但我仍然鼓励你看看数据库JSON.stringify()
0赞 Herokiller 5/19/2015
@slebetman我的意思是,在任何游戏中的每一步后都可以更新数据库吗?