提问人:expressnoob 提问时间:1/16/2011 更新时间:8/24/2012 访问量:3418
Node.js 存储游戏状态,如何?
node.js storing gamestate, how?
问:
我正在用 javascript 编写一个游戏,为了防止作弊,我让游戏在服务器上玩(这是一个棋盘游戏,就像一个更复杂的跳棋)。由于游戏相当复杂,我需要存储游戏状态以验证客户端操作。
是否可以将游戏状态存储在内存中?这很聪明吗?我应该这样做吗?如果是这样,如何?我不知道这是怎么回事。
我也可以存储在redis中。这种事情对我来说很熟悉,不需要解释。但是,如果我确实存储在 redis 中,问题在于,在每一次移动中,游戏都需要从 redis 获取数据并解释和解析该数据,以便从头开始重新创建游戏状态。但是,由于搬家经常发生,这在我看来非常愚蠢。
我该怎么办?
答:
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我的意思是,在任何游戏中的每一步后都可以更新数据库吗?
评论
Game
Player
Piece
Thread
Game