この記事は Tekka Advent Calendar 2017 12日目の記事です。
シミュレーションゲームにおけるゲームオブジェクトの更新(Update)は、
更新の順序により挙動が大きく変わるケースがあります。
例えばゲームオブジェクトAがゲームオブジェクトBに「電力」を渡し、
ゲームオブジェクトBが「電力」を消費して資源を生産する、という場合。
・Aが1フレームでBに渡す電力:20
・Bが資源の生産に消費する電力:100
であれば、順当に考えればBの資源生産には5フレームかかることになります。
ゲームオブジェクトの更新順が、A・Bの順であれば想定通り10フレームで資源生産が行われます。
1フレーム目:Aの電力受け渡し→Bの電力量20
2フレーム目:Aの電力受け渡し→Bの電力量40
3フレーム目:Aの電力受け渡し→Bの電力量60
4フレーム目:Aの電力受け渡し→Bの電力量80
5フレーム目:Aの電力受け渡し→Bの電力量100→資源生産
しかし、更新順がB・Aの場合。資源生産には1フレーム余分に必要となります。
1フレーム目:Bの電力量0→Aの電力受け渡し
2フレーム目:Bの電力量20→Aの電力受け渡し
3フレーム目:Bの電力量40→Aの電力受け渡し
4フレーム目:Bの電力量60→Aの電力受け渡し
5フレーム目:Bの電力量80→Aの電力受け渡し
6フレーム目:Bの電力量100→資源生産→Aの電力受け渡し
これがいわゆる更新順バグとなります。
更新順バグの実例。 画面中央のギヤのマークのブロックについて、左側2個のブロックは資源を2個続けて受け取りますが、 右側2個のブロックは1個ずつしか受け取れません。ぬわあああこういう処理順依存バグを極力なくしたいから色々頭ひねってたのにィィィ…でもこういうバグも更に頭ひねることで解決できるのも独自エンジンのいいところ。 #Siv3D #gamedev pic.twitter.com/1imkPem6wP
— AiNI@1日目金曜コ-39b (@aini_bellwood) 2017年11月5日
このような処理順依存バグは、更新処理を1フレーム内に複数回行うことで解消できます。
オブジェクトAのPreUpdate:電力受け渡し
オブジェクトAのPostUpdate:制御なし
オブジェクトBのPreUpdate:制御なし
オブジェクトBのPostUpdate:資源生産
とした場合、
1フレーム目のPreUpdate:A:電力受け渡し→B:制御なし
1フレーム目のPostUpdate:A:制御なし→B:資源生産
となり、AとBの更新順が入れ替わった場合でも、
1フレーム目のPreUpdate:B:制御なし→A:電力受け渡し
1フレーム目のPostUpdate:B:資源生産→A:制御なし
このように想定した順序を維持することができます。
ところでこのゲームですが、コミケで頒布します。
— AiNI@1日目金曜コ-39b (@aini_bellwood) 2017年11月16日
1日目金曜日コ-39b。 #Siv3D #gamedev pic.twitter.com/Pfo0cAyr92
このような複数回の更新を導入したゲームをコミケで頒布します。
1日目コ-39b「Tekka」でお待ちしています。