Functional programming 处于功能/状态的鸡或蛋

Functional programming 处于功能/状态的鸡或蛋,functional-programming,erlang,game-engine,Functional Programming,Erlang,Game Engine,我读过“纯功能游戏”系列 它讨论了一些构建(半)纯游戏世界更新循环的有趣技术 然而,我有以下附带的意见,我似乎不能左右我的头: 假设你有一个系统,其中每个敌人和每个玩家都是独立的参与者,或者是独立的纯功能 假设他们都得到一个“世界状态”作为输入,并输出一个新的世界状态(或者,如果你用参与者的术语思考,则将新的世界状态发送给下一个参与者,例如以“游戏渲染”参与者结束) 然后,有两种方法可以实现这一点: 要么你从一个演员开始(f.i.玩家),然后喂他“当前世界”。 然后,你把新世界喂给下一个敌人,

我读过“纯功能游戏”系列

它讨论了一些构建(半)纯游戏世界更新循环的有趣技术

然而,我有以下附带的意见,我似乎不能左右我的头:

假设你有一个系统,其中每个敌人和每个玩家都是独立的参与者,或者是独立的纯功能

假设他们都得到一个“世界状态”作为输入,并输出一个新的世界状态(或者,如果你用参与者的术语思考,则将新的世界状态发送给下一个参与者,例如以“游戏渲染”参与者结束)

然后,有两种方法可以实现这一点:

  • 要么你从一个演员开始(f.i.玩家),然后喂他“当前世界”。 然后,你把新世界喂给下一个敌人,依此类推,直到所有演员都改变了世界。然后,最后一个世界就是可以馈送到渲染循环的新世界。(或者,如果您阅读了上述文章,您将得到世界上发生的事件列表,这些事件可以被处理)

  • 第二种方法,就是同时给所有参与者当前的世界状态。它们生成任何可能发生冲突的更改(例如,两个敌人和玩家可以在同一动画帧中拿走一枚硬币)->由游戏系统通过处理事件来解决这些冲突。通过处理所有事件,游戏参与者创建了新世界,将在下一个更新帧中使用

  • 我有一种感觉,我正面临着完全相同的“竞争条件”问题,我希望通过使用带有不可变数据的纯函数来避免这个问题


    这里有什么建议吗?

    我没有读过这篇文章,但在硬币的例子中,你正在创建一种全局变量:你给所有参与者一份世界状态的副本,你假设每个参与者都会评估游戏,做出决定,并期望他们的行动会成功,而不管最后一个阶段是解决冲突。我不会称之为比赛状态,而是“盲目状态”,是的,这是行不通的

    我想您使用此解决方案是为了允许并行性,而在解决方案1中不可用。在我看来,问题在于责任

    硬币必须和应用程序中的任何东西一样属于参与者(充当资源管理器的服务器)。这个演员是唯一负责决定硬币会发生什么的人

    所有请求(是否有要抓取的东西、抓取的东西、放下的东西……)都应发送给该参与者(每个单元格、每个地图、每个关卡或任何对游戏有意义的分割)


    您将如何管理它取决于您:按照接收顺序服务所有请求,缓冲它们直到同步消息出现,并做出随机决定或优先级决定。。。在任何情况下,服务器都能够成功或失败地回复所有参与者,而不存在任何竞争条件的风险,因为服务器进程(至少在erlang中)在单个内核上运行,并且一次只处理一条消息。

    除了Pascal answer之外,您还可以通过拆分来解决并行化问题(我假设是巨大的映射)对于依赖于其邻居的最后一个状态(或部分状态,如边)的较小块。这允许您将此游戏分发到多个节点。

    有趣的是,每个硬币都可以有这样一个服务器。在你回答之后,我仍在努力理解的一件事是,系统如何知道所有参与者都采取了行动。如果所有玩家/敌人都在同一个世界实例上行动,我将如何实现终端状态?或者我只是做一个“轮换”演员,处理结束移动消息并使用需要达到0的剩余玩家值重播。有什么见解吗?每个硬币一台服务器可能是极端的:o),主要是因为游戏的每个参与者都必须知道它的pid才能与之通信,但正如我所说的,每个细胞一台服务器是可以实现的。有趣的是,每个过程只有很少的简单事情要做。编写速度快,易于测试,如果使用OTP的gen_server,只需测试“无状态”回调函数。如果游戏是同步的,即要求所有或部分演员参与,然后游戏继续进行,“回合”演员可以完成任务。消息在一个VM中传递是高效的,比用户界面快得多。是的,这很有趣,但我会做相反的事情:将地图分成块,每个块取决于当前状态,在块内部,让每个参与者取决于块中不同参与者的产品状态?@buddhabrot很难说。这取决于具体的游戏。我认为演员不应该得到整个世界,而应该只得到对他们来说重要的东西,然后他们在轮到的时间内做出决定,并将决定发送给演员。如果它因某种原因被拒绝,那么它可以做出另一个快速的决定或坚持到下一个回合。请注意,当它等待前一个WorldState产品时,实际上并不需要参与者(它不是并发的)。在区块主循环中也可以这样做,而不必为每个参与者复制WorldState。游戏世界中的并行性必须得到支持,而不是通过使用全局状态来对抗。你可能会发现这里的讨论是相关的:同时要记住的最重要的一点是,每个参与者对世界都有自己的看法——如果不停止系统对其进行取证检查,就永远无法完全观察到“全球状态”。这就是现实世界的运作方式,与全局状态的过程方式相比,在Erlang中编写模拟更容易推理。第一个解决方案将序列化所有播放器进程的处理,并消除大部分并行性,而第二个解决方案假设您可以拥有一致的全局状态,所有人都可以同时访问。将世界状态保存在一个单独的进程/进程集中,并允许播放器进程在需要读取/保存状态时访问它。这保留了更多的并行性,并且是m