Project1

标题: 如果你使用【自动存档】时【并行事件】出现问题,请看此帖 [打印本页]

作者: Mr.Jin    时间: 2021-10-26 23:18
标题: 如果你使用【自动存档】时【并行事件】出现问题,请看此帖
本帖最后由 Mr.Jin 于 2021-10-26 23:41 编辑

Project1.zip (1.32 MB, 下载次数: 4)

首先请用该工程执行以下操作:

New Game 进入一盘新游戏,然后和 NPC 对话
当他讲到 Please Exit 时,退出游戏
重新打开游戏,读取刚才对话时生成的自动存档,你会发现并行事件的执行出了问题——

复现到此为止,出现该问题的原因是,在我们进行一个地图事件执行的过程中,其它并行事件也在处理,且可能并没处理完——
在这种情况下,直接调用 DataManager.save_game 方法进行存档,就会将这些并未处理完的并行事件(尤其是不含显示文章、等待这种会阻塞处理的空转事件列)状态以错误的方式进行存储,导致再次读取数据时,执行到错误的条目,进而可能进入错误的分支,引发十分隐晦难解的错误

相信这类问题会经常发生,但可能被误诊为事件本身相关的条件变量和开关问题却找不到解决方法,只能不了了之;所以特将此类问题的源头公布出来,让大家更易捉虫

============== 常用解决方案 ================

上策:自己编写一个方法,在自动存档时把请求存到 $game_temp 或是什么地方去,然后在所有事件处理完的时机再进行实际的 DataManager.save_game
下策:在会出问题的并行事件最顶部垫一条"等待 1 帧",可以避开问题,但是极为不推荐
作者: gqxastg    时间: 2021-10-30 02:46
本帖最后由 gqxastg 于 2021-10-30 09:16 编辑

研究了一下...
确实光修是修不好的,还是需要个人注意用法
(其实说真的并行处理的事件还是应该套一层循环,每次执行完会空一帧太伤了)
试图修正
结果仔细想了一下,并行处理错误存储的根源是指令根本没执行
一旦执行了不是瞬间完成就是在等待结束,而等待结束的也基本不适合重设(还是有等待和显示动画之类的不适合跳)
所以还是可以只限制未执行的不推后,剩下执行中的统统跳过
(至于直接在条件分歧里save_game本身就应该避免,可以不管)
暴力修正
所以最后结合这两点,只有在执行指令时且排除特定几个指令之外才跳过就可以了
(当然可能有点偏离主题了,排除指令纯粹是附加的)
最终修正

作者: Mr.Jin    时间: 2021-10-30 09:20
gqxastg 发表于 2021-10-30 02:46
研究了一下...
确实光修是修不好的,还是需要个人注意用法
(其实说真的并行处理的事件还是应该套一层循环 ...

其实推荐的做法还是做一个新的指令来自动存档:
也就是先设一个要存档的 flag,但并不在事件处理中直接执行存档,而是在所有事件处理完后检查该 flag,进行存档并削除该 flag




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1