正在保存无赖游戏状态?


11

我正在使用HTML5和jQuery进行基本的roguelike,但遇到了问题。

按照游戏当前的状态,每次用户在楼层之间移动时,系统仅保存游戏状态-以最大程度地减少开销。这样做的危险是,如果用户遇到麻烦,他们可以简单地关闭窗口并在当前楼层的开头返回他们的游戏。这极大地降低了游戏难度(并几乎打败了“流氓”游戏的目的)-但是在每位玩家移动或攻击时保存游戏状态是不合理的。

我研究了在浏览器窗口关闭时保存游戏状态的方法,但我对它们不满意。我的问题是:假设“保存游戏状态”意味着适当的ajax / post请求,那么我如何阻止这种欺骗行为呢?与保存整个地图状态相反,是否存在已知的方法来量化2d地图的增量/过程变化?请注意,我不是在要求“最有效的方法”,而是在寻找现有的方法来纠正我的经验不足。


非常通用的JavaScript编程问题。我投了反对票,但随后我重新考虑,因为如果您考虑如果无法触发on-unload事件该怎么做,这很有趣。
蒂姆·霍尔特

也许我改写一下以直接解决该问题=)
CodeMoose

@TimHolt-根据您的建议进行编辑
CodeMoose

Answers:


8

显而易见的解决方案是将每个播放器命令发送到服务器,并让服务器记录它们。这样,如果游戏因任何原因中止,可以重播已记录的命令以将游戏恢复到退出状态。

当然,进行适当的保存后,旧的命令日志可能会被丢弃(尽管您也可以将其保存以允许重播旧游戏;如果这样做,则可能需要在日志中包含时间戳以进行实时重播) )。您可能还希望自上次保存(执行n = 1000)后执行n个命令后自动进行完全保存,以避免在玩家关闭或崩溃游戏之前停留在同一级别上的时间过长而导致重放时间过长的情况。 。

如果您的游戏涉及随机数(并且可能是流氓行为),则还需要确保在重播期间可以正确地重新创建它们。一种解决方案是在重播日志中包括每个随机数。另一种方法是使用确定性伪随机数生成器并在保存游戏时保存种子。

请注意,可以通过篡改客户端来利用所有这些方法,但是每当您在客户端上具有游戏逻辑时,这都是不可避免的。作为一种防作弊的选择,您可以在服务器上运行实际的游戏,而只是让客户端将所有玩家命令发送到服务器并接收显示更新。对于流氓来说,这可能是可行的。显然,这也可以解决您的状态保存问题(尽管您可能仍想在服务器上实现某种形式的命令日志记录,以实现重播功能并允许从服务器崩溃中恢复)。不利之处在于,这样做将无法进行离线播放(当然,除非您还使服务器端代码可供玩家在需要时在本地运行)。


1
AFAIK所有RGN都是伪随机的。您需要专门的硬件来获取真正的(非种子)随机值。
bobobobo

1
@bobobobo .net平台中存在伪随机(种子),并且具有加密安全的随机数(未种子)。它可能/可能不是硬件随机的,但它足够接近以至于无法仅存储种子。
Rangoric

2

请参阅/programming/3888902/javascript-detect-browser-close-tab-close-browser,以获取有关同一问题的更一般的询问。

还应考虑在整场比赛中保存完整的比赛,并在每次移动中保留增量增量。然后,您可以重玩游戏直到最后一步。

假设使用了一些随机数生成器,则可以在每个新楼层的开头生成并重新设置随机数生成器的种子,然后将其与该楼层一起保存。然后,您可以在负载下进行种子设定,并且应该能够以相同的顺序重播动作,直到最后一个动作完成为止。


蒂姆(Tim),谢谢-一旦我进入了游戏开发者的思维定势,就可以很容易地将所有与游戏开发者相关的东西都存储起来。无论如何提供答案的道具。
CodeMoose

不用担心-也请参阅我对问题的修订评论:)
蒂姆·霍尔特

我也会说每一步的增量增量
bobobobo

2

采取的方法不是增量保存,而是寻找时间进行完全保存:

  • onunload, 就像之前提到的。我发现这是可靠的(但使用localStorage,而不是网络,这可能会改变情况)。
  • 当窗口失去焦点时保存。
  • 定期保存:上一次保存未在n分钟内完成,并且用户未在m秒内进行任何输入。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.