はじめてゲームプログラミング 関数化

はじめてゲームプログラミングはノードン数512個までというシステム制約が厳しい為様々な節約テクニックがあります。このモーメントでは今回実践した関数化について纏めています。
2
きゃべつ @cabbagestole

はじめてゲームプログラミングの関数化について はじプロに興味ある人しか読まないモーメントの為、前提は省略。関数化にまつわる現時点での知見を得たので後に続く人にむけて整理しておく。

2021-12-24 21:29:33
きゃべつ @cabbagestole

構造 自機との位置関係に応じて行動を変化させる敵機を想像してほしい。プログラム上では入力、計算、出力のパートに分かれる。 入力は敵機と自機の座標や敵機の状態、計算は移動方向の決定や攻撃行動に移る条件を満たしたか、出力は実際画面上に現れるオブジェクトその物だ。

2021-12-24 21:30:39
きゃべつ @cabbagestole

入力と出力は敵機毎に異なる為共通化は出来ないが、計算処理は全て同じだ。単に入力値が異なり出力先が違うだけの事である。 よってはじプロでも計算部分を関数化する事でノードン節約の余地があり検討に値する。

2021-12-24 21:30:53
きゃべつ @cabbagestole

関数化は入力値を単位時間で順番にタイムスライスし計算部分に流れる値と出力される値を制御する構造である。 入力(引数)と出力(戻り値)には、対象オブジェクトの計算時間が来たことを示すシグナルとの掛け算(×)ノードンを追加する。

2021-12-24 21:31:04
きゃべつ @cabbagestole

ここだけ見るとノードン増に感じられるが引数、戻り値、タイムスライスする対象数(以降多重度,M,mと表記)と関数部分の大きさからノードン減になる損益分岐点が存在する。 手法に応じた計算式があるので後ほど紹介する。

2021-12-24 21:31:18
きゃべつ @cabbagestole

手法 「おめくり式」は計算ノードン間のシグナル伝達が1/16フレームで実行される特性を利用した1/16フレーム単位でタイムスライスを行い関数部を共有する方式 「WO式」はカウンタノードンを0~nループさせ1フレーム単位でタイムスライスし関数部を共有する方式

2021-12-24 21:32:07
きゃべつ @cabbagestole

関数内部にカウンター、フラグは含めない。このノードンを通過する際1フレームの遅延が生じる事、オブジェクト状態を保持するインスタンス変数の性質が強い。 0から変わった瞬間は1フレームの間1を出力し続ける性質上、カウンターやフラグと同じ性質と捉え関数内部に使用しない。

2021-12-24 21:33:19
きゃべつ @cabbagestole

おめくり式 メリット 計算処理が1フレーム以内に完了する。この為毎フレーム計算結果が得られる(計算処理が長過ぎる場合を除く)

2021-12-24 21:34:37
きゃべつ @cabbagestole

おめくり式 デメリット 関数内部のおめくり式対応によるノードン増。 2値の計算(+ー×÷AND)が入力時点から同じワイヤー数になるよう+ノードンを追加する調整が必要 また出力時点で16/16フレームになるよう+ノードンを追加する調整が必要

2021-12-24 21:34:47
きゃべつ @cabbagestole

WO式 メリット 1フレーム単位での実行にプログラマが習熟しているで理解が容易 関数内部の変更は基本的に不要

2021-12-24 21:35:02
きゃべつ @cabbagestole

WO式 デメリット 計算処理がmフレーム毎に行われる。自分の番でないフレームでは出力値が0になる為対策コードが必要になる オブジェクトの動作に関わる引数の場合、オブジェクトが荒ぶる原因になる。(例えばヒンジへの入力)

2021-12-24 21:35:13
きゃべつ @cabbagestole

ノードン数見積計算式 引数の数をP,戻り値の数をO、多重度をM、関数部分をF、対応に伴う増分をおめくり式をα,WO式をβとする 支配的な計算係数M,P,O,Fの関係性が同じである事、αとβは関数により異なる事からノードン削減効果は同程度、若干WO式が有利かも?

2021-12-24 21:35:36
きゃべつ @cabbagestole

おめくり式 M×(P+O+1)+5+F+α < M×F を満たす場合有効 WO式 M×(P+O)+F+β < M×F を満たす場合有効

2021-12-24 21:35:45
きゃべつ @cabbagestole

概要は以上となる 続いてはトライ&エラーの詳細

2021-12-24 21:35:55
きゃべつ @cabbagestole

XEVIOUS的な 使い回し敵機の行動パターン7種 Z軸反応 トーロイド、タルケン、カピ X軸反応 ゾシー、ジアラ、テラジ 距離反応 ブラグ・ザカート 敵機だけで100ノードン使うので関数化しないと4機以上登場出来ません(現在250ノードン) 頑張る... #はじめてゲームプログラミング pic.twitter.com/2E5qXGSL44

2021-12-20 16:23:25
きゃべつ @cabbagestole

おめくり式関数の解説動画を自分で作っておきながら詳細忘れてるので再度動画見て履修するマッチポンプ

2021-12-19 18:53:23
きゃべつ @cabbagestole

関数化するにあたり先人@WO33427414 さんの第九惑星の実装を参照 参考実装を沢山見たほうが良いし、新たな工夫発見があるかもしれない ビクンビクンしてる3多重の箇所を発見! 解析しよ

2021-12-20 20:34:27
きゃべつ @cabbagestole

今回のおめくり式関数化は引数4,戻り値3,グローバル変数3を参照というスパゲッティコード待った無しのとてもお行儀の悪いリファクタ(?)作業です 自分でもこれ動くんか?と大変心配です笑 試行錯誤の連続だろうけど後に続く人の為、作業手順ツイートしますね

2021-12-20 23:06:49
きゃべつ @cabbagestole

おめくり式関数化前に入力/出力パラメータ数の検討 敵の移動方向を角度で保持しているが、これを位置に置き換える事も出来る ではやるべきか否か おめくり式のノードン数見積式は 5+ M×(P+1) +M×O +F である(戻り値Oの数も式に含めた) pic.twitter.com/YIpfi5Tvkp

2021-12-21 09:07:50
拡大
きゃべつ @cabbagestole

引数に角度を与えるか、x,yを与えるかの違いを検算 シンプルにP,Oの増えた数×多重度が増える 今回は(1+1)×6=12が増える pic.twitter.com/vIeo4DAP2W

2021-12-21 09:12:36
拡大
きゃべつ @cabbagestole

角度方式だと角度を位置にノードンが関数の外側(敵インスタンスの固有処理)になる X,Y方式だと関数内に含まれ現実装から-6されるが、関数化の枠組み増分+12が増えるので結局損する 結論 同じ意味なので移動X,Y座標より角度を扱うほうがお得! pic.twitter.com/OsiOtI9Q94

2021-12-21 09:17:56
拡大
きゃべつ @cabbagestole

何となく角度で実装(引数、戻り値を減らした方が得っぽい)とゴーストが囁いたのでそれに従ったけど、勘が当たってた事を再確認

2021-12-21 09:25:12
きゃべつ @cabbagestole

関数部Fは内部実装が違っても平行処理数×16の倍数になるまで+ノードンで穴埋め(NOP命令の追加)をするのでノードン数への影響は無い 無視して構わないと言える

2021-12-21 09:10:26
きゃべつ @cabbagestole

おめくり式関数化、変更前 ちゃんとノードン数数えた 総数 262 エネミー 79(コメント含まず) 固有部 38 関数部 41 関数内部でエネミー種類と自機XYを参照するけどグローバル変数として関数から外出しした 昨今の設計では引数渡しが常識なのでグローバル変数使う選択しただけで動悸が上がる pic.twitter.com/Sc5ZoNLPdz

2021-12-21 10:52:21
きゃべつ @cabbagestole

敵種類も敵の属性だと最初考えていたが、同時に同じ敵しか出現しない仕様とした(XEVIOUSも殆どの場面が同様) これによりインスタンス変数からグローバル変数に再定義出来て引数の数を減らす効果がある 異なる敵が同時に現れると難易度上がり極まった人しか楽しめないのを避ける

2021-12-21 11:03:42