作者:望尽天涯 | 来源:互联网 | 2023-05-28 12:34
我读过"Purely Functional Retrogames"系列
http://prog21.dadgum.com/23.html
它讨论了一些有趣的技术来构建(半)纯游戏世界更新循环.
但是,我有以下方面的评论,我似乎无法理解:
假设你有一个系统,每个敌人,每个玩家都是独立的演员,或者是单独的纯粹功能.
假设他们都得到一个"WorldState"作为输入,并输出一个New WorldState(或者,如果你用演员术语思考,将新的WorldState发送给下一个actor,以例如"Game Render"演员结束).
然后,有两种方法可以解决这个问题:
要么你从一个演员开始,(对玩家来说),并向他提供"当前世界".然后,你将新世界,下一个敌人,等等,直到所有演员都改变了世界.然后,最后一个世界是你可以提供给渲染循环的新世界.(或者,如果您按照上面的文章,最终会得到世界上发生的可以处理的事件列表).
第二种方式,就是同时给所有演员当前的WorldState.它们产生任何可能发生冲突的变化(例如,两个敌人和玩家可以在相同的动画帧中获取硬币) - >由游戏系统通过处理事件来解决这些冲突.通过处理所有事件,Game actor创建新世界,用于下一个更新框架.
我有一种感觉,我只是面对完全相同的"竞争条件"问题,我希望通过使用具有不可变数据的纯函数来避免这个问题.
有什么建议吗?
1> Pascal..:
我没有读过这篇文章,但是用硬币的例子你正在创建一种全局变量:你给所有演员一个世界状态的副本,你想每个演员都会评估游戏,做出决定并期望他们的无论最后阶段是解决冲突,行动都会成功.我不会称这是一种竞争条件,而是一种"盲目条件",是的,这是行不通的.
我想你来到这个解决方案是为了允许并行性,在解决方案1中没有.在我看来,问题在于责任.
硬币必须属于应用程序中的任何actor(作为资源管理器的服务器).这个演员是唯一负责决定硬币会发生什么的人.
应该将所有请求(有东西抓住,抓住它,丢弃东西......)发送给这个演员(每个单元一个演员,或每个地图,等级或任何对游戏有意义的分裂).
您管理它的方式取决于您:在接收顺序中提供所有请求,缓冲它们直到同步消息到来并做出随机决策或优先级决定......无论如何,服务器将能够回复所有成功或失败的参与者没有任何竞争条件的风险,因为服务器进程在单个核心上运行(至少在erlang中)并且一次进行一条消息.