投稿記事

K-Shin07 2023/12/17 16:26

プロシージャル生成による効果音作成ツール『GameSynth』検証

はじめに

前から気になっていたプロシージャルサウンド合成による
効果音作成が可能な『GameSynth』を試しに使ってみました。

開発中のゲーム用効果音を作ってみて、
どんな感じだったのかを軽くまとめてみます。

そもそもプロシージャル生成とは

データを作る際に手作業で順々に作っていくのではなく、
処理を連続的に組み合わせてデータを生成していくものになります。

例えば次のような工程でデータを作成しているとします。

  • 処理A → 処理B → 処理C → データ完成

この場合、常に上記工程を辿ってデータが自動的に生成されます。

手作業でデータを作成している場合は『A』で行った作業工程だけを調整して
新しくデータを確認したい場合は、
『A』の調整後に『B』→『C』ともう一度加工する必要があると思います。

プロシージャル生成では全ての工程が『処理』になっているため
『A』を調整したら自動的に『B』→『C』も処理されて常に最新のデータが生成されます。

これにより、調整や工程の抜き差しが簡単に行えます。

自分は3Dモデルの作成で『Houdini』を主に使っているのですが
それもプロシージャル生成によるツールなため、
初めて使ったときは各途中工程の3Dモデル状態がいつでも確認、調整できて感動しました。

以下の動画はHoudiniによるプロシージャル生成で自作した歯車です。
完成したあと各工程のパラメータを調整して歯車の歯数を変えたり、
外見を変えたりしています。

効果音作成ツール『GameSynth』を使ってみた

サウンドモデルの選択

GameSynthでは基本的に下記モード(サウンドモデル)のどれかを選択して
効果音を作成するようです。

  • Whooshモデル(風切り音)
    • 剣を振るなどの風に関する音を作りやすい
  • Impactモデル(打撃や摩擦音)
    • 物がぶつかる音や引きずる音などを作りやすい
  • Retroモデル(8ビットゲーム効果音)
    • レトロゲーム音やUIの操作音などを作りやすい
  • Modularモデル(プロシージャルサウンドモデルを組み立てる)
    • プロシージャル生成手法で音を作り上げていくモデル
    • これを使えば基本的に何でも作れる
    • 他のモデルで作った音をベースに加工していくことも可能
    • ベースとなる音源(炎、風など)はたくさんあるので音を用意しなくてそれを加工していくだけでOK
    • 今回の記事で主に使用するモデル
  • Particlesモデル(断続的に発生する音)
    • キラキラ音や瓦礫が崩れる音など特定の音が何度も発生するような音が作りやすい
    • 作成した効果音を音源として利用する
  • VoiceFXモデル(ボイス加工系)
    • 持っているボイスに対して各種エフェクトをかける機能
  • Footstepsモデル(足音)
    • いろんなパターンの足音を簡単に作成できるモデル
  • Weatherモデル(天候に関する音)
    • 雨や暴風、雷、雹などの天候に関する環境音を簡単に作成できるモデル

基本的にModularモデルを今回使用しますが
他のモデルは簡単に扱いやすいものが多いので
下記で軽くいくつか紹介してみます。

Whooshモデル(風切り音)

以下の動画ような感じで風に関する音を作れます。
マウスで線を描いて軌跡に沿って音をならせます。
描いた線をランダムにほかの形状に変えることもできます。
※ペンタブを使用すると筆圧なども考慮されるようです

Impactモデル(打撃や摩擦音)

以下のように打撃や摩擦に関する音を作れます。

Retroモデル(8ビットゲーム効果音)

以下のようにレトロ風の効果音が作れます。

Modularモデル(プロシージャル生成)

以下のように各種ノードを組み合わせて音を作っていきます。
慣れるまでは時間がかかりますが、
扱えるノードが増えれば増えるほど自由に音を作っていけるようになります。

Particlesモデル(断続的に発生する音)

以下のように任意の効果音をベースとして
音をパーティクル的に発生させて作ります。
※ベースの効果音を複数にすることもできます

VoiceFXモデル(ボイス加工系)

以下のように任意のボイスに対してエフェクトを付与できます。

Footstepsモデル(足音)

以下のように足音をシミュレートすることができます。


Weatherモデル(天候に関する音)

以下のように雨や雷などの環境音をシミュレートすることができます。
※雨の強さや雨が当たる地面の材質を変更するなど各種パラメータを変更可能です。


実際にゲームの効果音を作ってみた

今回は主にModularモデルを使用してプロシージャルに効果音を作成してみます。

最近作ってたエフェクトの効果音を試しに作ってみました。
まずは完成品の動画です。


前半のエフェクトと後半のエフェクトで別々の効果音を作っています。
最初の効果音はこのようなノード構成になりました。

上記ノードを見るとなんだか複雑そうに感じると思いますが
実際に作業しているときは1つ目のノードから順々に作っていくので
思ってたよりは複雑に感じないです。
※上記では用意していないですがコメント文も配置できます

上記画像はいきなり他人のプログラムの完成したソースコードを
見せられているようなものなので
自分で組めばどこで何をしているかは把握できますね。


音を再生する際に動画も同時再生する機能があるのですが
こちらを利用すると実際のエフェクトを見ながら確認ができるので
音の調整がとてもしやすかったです。


ノードの種類がかなり多いので自分もまだほとんど理解できていません。
それでも10種類ぐらい使えるだけで
充分いろいろ作れるので意外となんとかなりそうです。

ツール内の『help > Manuals > モジュール周期表』を見ればどれがどのような機能を持っているか確認できる(動画もある)のでまずはここを見ていくのがよさそうですね。

プリセットもたくさんあるのでまずはそれを確認してみるのもおすすめです。


また、各ノードのパラメータを時間経過で変化させることが可能な
『Automation Curve』という機能があります。
このあたりの機能はなるべく早めに扱えるようになるとよさそうです。
(途中からピッチを急激に上げて音が高くなるような表現や音量のフェードコントロールなどが自由にできるようになります)



ちなみに後半のエフェクトの効果音はこのようなノード構成になりました。


まとめ

Modularモデル以外のサウンドモデルは割と雑に使っても
それなりに簡単に効果音が作れると思います。

Modularモデルは自在に音が作れますが
慣れるまでは時間がかかりそうですね。

ちなみに上記で作ったエフェクト効果音の作業時間は
だいたい1時間ちょいぐらいです。
機能を理解しつつ作っていたので、
理解が進めばもっと早く、もっとイメージ通りに作れるようになりそうですね。

一度作ったノードは使いまわすことも可能なので
作れば作るほど音の表現を自在に作れるようになりそうです。

今作っているゲームの効果音は
GameSynthを使って作ってみようと思います。

フォロワー向けに
他の作ってみた効果音やそのノード構成をいくつか公開しておきます。
(大したものではないです)

フォロワー以上限定無料

無料プラン限定特典を受け取ることができます

無料

K-Shin07 2023/12/15 20:11

【開発進捗】開発中のゲーム(Rewind)やWodistantについて

はじめに

最近の近況についてまとめたいと思います。
主に以下の内容についてです。

  • Wodistant Ver1.4.0βの予定について
  • ウディタで開発中のゲームについて

Wodistant Ver1.4.0βについて

もともと2023年9月~10月頃あたりの公開を予定していました。
ですが、今はゲーム開発の作業を優先していてほとんど手を付けていません。

しばらく作業する予定はないので
ウディタデバッガーα版を試したい人は公開中のα版をご利用ください。

β公開時期は今のところ未定です。
直近では作業予定はないので最速でも来年4月以降とかになると思います。


ウディタで開発中のゲームについて

どういうゲームを作っているかについては
今までほとんど情報を出していませんがウディコンに向けて開発中です。
(全ての素材を自作している状態なので正直来年に間に合う気はしていませんが間に合わせるつもりで作業中です)

約2年前の2022年1月26日頃から開発しているもので
開発休止してた期間を除けばだいたい開発期間は9ヵ月ぐらいだと思います。

ゲームジャンルとしてはプログラミングパズルRPGですね。
ゲームシステムの詳細はまだ伏せますが、
一般的なプログラミングパズルとは異なるゲーム体験ができるものを目指しています。

ゲームタイトルは企画段階から決まっていて『Rewind』というタイトルです。
最終的にはサブタイトルを付けるかもしれません。
(付ける場合の名前も一応決まってはいます)

※ジャンルやUI(仮)を含めた画像は今回が初出です。

作ったマップなどは一部Twitter(X)で公開していたこともあるので
公開していたマップ画像は改めてここにまとめておきます。



ちなみにマップはウディタのマップエディタを使用していません。
CLIP STUDIO PAINTをマップエディタとして利用しています。

ステージの移動可能な領域やイベント設定、敵配置、ギミック配置などの
各種ステージごとの設定も全てクリスタ上で行っています。


(最終的にPSDファイルで出力したあと自作のコンバートツールでウディタ用データに分解する流れですね)

最終的にマップは31~32マップほどになる予定で、
今のところ17マップ分は背景が完成しています。

現在は後半のステージ/イベント実装などを進めているところです。
基本的なゲームシステムはほとんどできているので
前半のステージはそれぞれ単体では遊べる状態になってます。

とはいえ、全体的なレベルデザインなどは
ほとんどのステージが実装できてから行う予定なので
目指したい完全なゲーム体験まではまだまだ先な状態ですね。

見た目もマップやエフェクト以外はほとんど仮です。
そろそろ見た目にも手を付けたいところ……。

最近Twitter(X)にあげていたエフェクトの動画も置いておきます。

エフェクトはエフェクト作成用の外部ツールなどは使用しておらず、
ウディタ内にEffekseerのような感じのパーティクルシステムを実装して再生しています。

巨大なパターン画像が不要になるので
低容量で高品質なエフェクトが量産できるのでおすすめです。
いつかこの辺のシステムの記事とかも書けたらいいなと思っています。


さいごに

以上が近況報告になります。
今後は開発中のゲーム(Rewind)についての近況とかも
書いていきたいところですね。

K-Shin07 2023/09/09 15:21

ウディタ3以降で開発するときに意識したい処理負荷解説

はじめに

昨年の2022年11月にウディタVer3へと大型アップデートが入りましたね。
皆さんご存じの通り、処理負荷も大きく改善されました。

Ver2世代と比べると圧倒的に高速に動くようになっています。

処理負荷の軽減についてこれまでたくさんのテクニックが
ウディタVer1~2の間に生み出されてきたと思います。

でもそのテクニックやこれまでの常識が
ウディタ3でも通用するのか?
ウディタ3での新しい処理負荷軽減方法はないのか?
そういった内容をまとめている人があまりいないような気がしたので
本記事でウディタ3での処理負荷軽減手法について新しくまとめてみようと思います。

ウディタ2以前との比較というより
ウディタ3で開発をする上での処理負荷軽減方法を新しくまとめてみます。

なので以前までの常識やテクニックは一旦忘れて
基本的なところも含めて、改めてまとめなおしていきます。
初心者~上級者全ての人に向けての記事として書くので
各々の技量に合わせてみたいところを見ていっていただければと思います。

またウディタで3Dゲームを作ろうとしている人も増えてきている印象なので
3D技術に関する負荷軽減手法についても軽く言及しようと思います。

初心者向け

そもそも処理負荷って何?

ウディタでイベントコマンドを挿入して作った全ての処理は
ゲームを実行しているときにパソコンに負荷がかかります。

どれくらいの負荷がかかっているかはゲームをテストプレイしているときに
下記画像のようにウィンドウ上部に表示されている情報から確認することができます。

上記画像では『0.1ms』と表示されています。
『ms』は『milliseconds』の略で『ミリ秒』を意味しています。
これはウディタがゲームの処理を1フレーム実行したときにどれくらい時間がかかったを示す処理時間が表示されています。

よって今回の例では『0.1ミリ秒』時間がかかっています。

イベントコマンドを挿入して処理を増やせば増やすほどこの時間が増えます。

また、この処理時間はパソコンのスペックに依存するため、
同じ処理を実行したとしてもパソコンのスペックが高ければ高いほど時間が短くなる傾向にあります。

処理時間が増えるとどうなるの?

ゲームがなめらかに動作せずにガクガクするような、
いわゆる『処理落ち』が発生します。

処理落ちはいつ起きるの?

ウディタの『ゲーム基本設定』で設定した
『ゲームの処理FPS』によって異なります。

ゲームの処理FPS(frame per second)とは

1秒間にどれだけゲーム画面を更新するかを指します。
『30FPS』を設定している場合、1秒間に30回処理を更新できます。

ウディタでフレームという単位で処理するイベントコマンドがたくさんあります。
これらのコマンドにこの設定が影響します。

例えば『60FPS』を設定している状態でウェイトコマンドを60フレームで実行すると
1秒間待機します。
※30FPSの場合は30フレームで1秒間待機

1フレームに処理可能な時間

  • 30FPSは30フレームで1秒1000ms / 30frame1フレームは約33.3ミリ秒
  • 60FPSは60フレームで1秒1000ms / 60frame1フレームは約16.6ミリ秒
    上記からわかるように設定したFPSによって1フレームの時間が変化します。

この1フレームにかかる時間が処理可能な時間となります。
よって『60FPS』の場合は16.6ms以内に全ての処理を実行する必要があります。

処理落ちが発生するタイミング

上記で説明した『1フレームに処理可能な時間』を処理時間が超えると
処理落ちが発生します。

※厳密には処理落ちの発生タイミングはもう少し複雑になりますが、詳細は中級者向けの『描画処理時間と内部処理時間』編で説明します。

処理時間を見てどうすればいいの?

『1フレームに処理可能な時間』を超えないように処理を調整します。
『60FPS』の場合は16.6msを超えないように調整する必要があります。

処理の調整については主に下記のような対応になると思います。

  • 軽い処理へ置き換える
    • アルゴリズムを変えるなど処理の実装方法を工夫する
    • 負荷の軽いコマンドで代用する
  • 処理を削る

※ただし、処理時間はパソコンのスペックに依存するため、比較的高スペックなパソコンで開発している場合は、手元でギリギリ処理落ちしないぐらいだと他の人の環境でまともに動かない可能性があるのでご注意ください

処理負荷を気にする必要はあるの?

ウディタの基本システムだけを使っている場合はそんなに意識する必要はありません。
特にウディタ3は高速なので、ほぼ意識しなくて問題ないです。

負荷を気にする必要がありそうなのは下記に該当している方です。

  • 基本システムを大きく改造したり独自のシステムを追加で動かしている
    • 他の人が作成したコモンなどを組み合わせている場合も該当する
  • 独自のシステムを作っている
  • 他の人が作成した独自のシステム(コモンイベント)を利用している

ただ上記に該当しているからといって、
今処理落ちが発生していなければ気にせずに作ってよいと思います。
処理負荷を気にするより、まずはゲームを完成させる方が大事です。

もちろん独自システムを作っている方で、
最初から処理落ちするぐらい負荷が高くなることが予測できているなら
対策を早い段階で意識する方が良いと思います。

数値変数と文字列変数の負荷

文字列変数に対する処理は数値変数よりもかなり負荷が高いです。
下記画像の例では20倍文字列変数の方が重いです。

毎フレーム実行するような処理では、
なるべく文字列変数は使用頻度を少なくしましょう。

マップイベントとコモンイベントの負荷

『マップイベント』と『コモンイベント』では
各コマンドの処理負荷に違いがあります。

変数操作コマンドはマップイベント上で使用すると約6倍重くなります。
複雑な計算を行う場合はコモンイベントを呼び出して計算処理を実行すると軽くできる可能性があります。

※コモンイベントを呼び出すという処理自体にも負荷があるため
 コモン側に処理を逃がす場合は『変数操作コマンド』を4つ以上組み合わせる必要があるかどうかを判断基準にするとよいです。
※『コモンイベントを呼び出す』負荷はだいたいコモンイベント上で実行する『変数操作コマンド』20個分です。
※マップイベントでは変数操作に約6倍の負荷がかかるので変数操作4つ以上コモンへ逃がすと軽くなる見込みがあります


中級者以降向け

描画処理時間と内部処理時間

ウディタには『描画処理時間』と『内部処理時間』の2種類の処理時間があります。
初心者向けの説明では『内部処理時間』による処理時間にだけ焦点をあてましたが、
こちらでは『描画処理時間』についても説明します。

描画処理時間ってなに?

これはウディタが裏で実行している
描画に関する処理にかかっている時間のことです。
※マップ描画やピクチャ描画などが該当します

『ピクチャ表示』で任意の画像や文字が表示できますが、
これはウディタに表示のリクエストを送っているだけで
『ピクチャ表示』を実行した瞬間に画面に描画されているわけではありません。
よって『ピクチャ表示』コマンドの処理は『内部処理時間』として計測されます。

実際の描画自体はあとでまとめて処理され、
それが『描画処理時間』として計測されます。


描画処理と内部処理の実行順

ウディタの処理の実行順を図で示すと次のような画像になります。

描画処理も含めた処理落ちタイミング

上記図で示したように1フレームの間に描画処理も実行する必要があります。

初心者向けの解説では『内部処理時間』が
16.6ms等を超えると処理落ちすると解説しましたが
実際には『描画処理時間』+『内部処理時間』の合計時間が超えてしまうと
処理落ちが発生します。

多量のピクチャを常に描画するようなケースだと
描画処理の負荷が高まってしまうため、内部処理に割ける時間も減ります。

描画処理負荷を軽減する方法

描画負荷が下がるケースや、
負荷を削減する手法について紹介します。

表示したまま描画負荷が変動する条件

※全てのパターンを調査したわけではないためご了承ください

  • 画像表示の場合
    • 不透明度が0の場合は描画負荷が大きく下がる
    • 画像全体が画面外に配置されている場合は描画負荷が大きく下がる
    • 拡縮が0の場合は描画負荷が下がる
    • 角度が0以外だと描画負荷が増加する
    • 自由変形で表示すると描画負荷が激増する
      • 自由変形でも他の描画負荷増減効果は発生する
  • 文字列表示の場合(画像表示と異なる点のみ記載)

    • 拡縮が100%以外の場合(0%含む)は描画負荷が大きく増加する
    • 画面外配置は1文字単位で描画負荷が下がる
    • 角度が0以外だと画面外配置による描画負荷軽減が発生しなくなる
      • もちろん描画負荷は増加する

上記のようにただ表示しているだけでも
表示位置や不透明度などの値によって描画負荷が上下します。

画面外のピクチャの扱い方

画面外に配置されたピクチャは描画負荷が下がりますが
描画負荷自体は消えません。

可能であれば画面外に行ったものは
ピクチャ表示処理自体を行わないようにすることをおすすめします。

ただ画面外にいるかどうかを判定する処理を効率よく組めない場合は
逆に判定負荷の方が重いみたいな結果になる可能性もあるため
各自の処理の組み方にあわせて判断してください。

毎フレームピクチャ表示しているようなケースだと
表示しないようにすることで『内部処理時間』の削減にもつながる可能性があるので
画面外判定処理がシンプルに組めそうであれば積極的に表示しないようにしてみてください。

※ちなみにこのような画面外などの不要な描画を省く技術をカリングと呼びます
※3Dゲームだと視錐台カリングと呼ばれます

ピクチャの裏に表示されたピクチャについて

大きなピクチャなどによって裏に隠れたピクチャにも
描画負荷が発生します。

裏に隠れたら描画しないようにすることで負荷削減が狙えますが
これを効率よく綺麗に組むのは難しいと思うので、
裏に隠れても負荷が発生するという点だけ覚えておいてください。

3Dゲームを作っている場合は導入が必要になるかもしれません。
もし3Dゲームを作っていて描画関連の負荷を削りたい方は
オクルージョンカリングで検索してみてください。
カメラから見えない遮蔽に隠れた描画物を描画しないようにできる技術です。
遮蔽が多い空間を表現する場合は有効だと思います。
ただし難しい技術なのでウディタで判定負荷に耐えられるように組むのは至難の業かもしれません。

ウディタ3で画面を撮影してピクチャとして表示できるようになったため
マップ画面の描画が重い場合は、下記のような利用ケースはお手軽で有効かもしれません。
※以下はメニューを開いている間はマップ描画の負荷を抑える手法
①メニューを開く際にマップを撮影してピクチャとしてマップを表示
②マップ描画は全て非表示にする
③メニューを開く
④メニューを閉じる際はマップ描画を再開して撮影表示しているピクチャを消去

DBへのアクセス負荷

データベースに対してアクセスを行うときの
処理負荷軽減テクニックについて紹介します。

データ番号のみ変数を指定する

DBへアクセスする際に
データ番号以外に変数を使用すると4倍近く負荷が増えます。

タイプ番号を変数で指定するケースは少ないですが
項目番号を変数で指定するようなケースは発生すると思います。
アクセス回数が多い場合はデータ番号以外に変数を使わないような処理やDB設計を意識することをおすすめします。

DB設計については効率よく完全に回避することはできないor難しいと思うので、
知識として頭の片隅に置いておいてください。

データの初期化について

『特定のデータ番号』の項目を初期化する場合に
負荷を軽減する手法について解説します。

全ての項目を初期化したい場合

DBの項目に対して手動で1項目ずつ代入して初期化するより
『全項目初期化』を使用する方が軽いです。

ただし、データ番号を1つ余分に確保できる状態であれば
ウディタ3で搭載された『データコピー』機能を使う方が圧倒的に高速です。
※初期化用のデータ番号を1つ確保してそのデータをコピーする

このやり方だと初期化値をDBで設定した初期値とは
異なる値にもできるので汎用性が高いです。

一部の項目を初期化したい場合

全ての項目を初期化する必要が無く、特定の項目だけ初期化したい場合は
個別に初期化する方が良いです。

ただし、初期化する必要が無い項目も初期化されて問題が無いのであれば
初期化する項目数が多い場合、『全項目初期化』を使用したほうが早い可能性があります。

もちろん『全ての項目を初期化したい場合』で紹介した『データコピー』機能の方が全初期化する場合はより高速です。

個別初期化とどちらが軽いかはケースバイケースなため
どうしても最適化したい場合は実際に計測してみることをおすすめします。

ラベルジャンプの負荷

ラベル名の文字数は影響するのか?

ジャンプ先の指定などに変数を一切利用していない場合は
ラベルジャンプの負荷に文字数は影響しません。
それに『変数操作コマンド』2個分程度の負荷しかかからないため、
かなり超高速でジャンプしてくれます。

変数で指定した場合は文字数の影響を受けるうえに
ジャンプ処理自体が超激重になるのでご注意ください。
※ウディタ2世代では変数を使わずとも文字数が多ければ多いほど負荷が高くなっていました。

コメント文の負荷

コメント文にも負荷が発生します。(変数操作コマンド0.5個分程度の負荷)
ただしコメント文が連続で並んでいる場合に限り
2個目以降のコメント文に負荷が発生しません。

コメント文と他のコマンドが交互に並んでいる場合は
全てのコメント文に負荷が発生します。


※ウディタ2世代では連続に並んでいても関係なく個々に負荷が発生していました。

チェックポイントの負荷

『チェックポイント』コマンドも負荷が発生します。
ただし、コメント文とは異なり連続で並んでいても個々に負荷が発生します。
負荷は1個につき変数操作コマンド0.5個分です。
※ウディタ2世代と特に変更はないです。

デバッグ文の負荷

デバッグ文はデバッグウィンドウがOFFの場合、大きく負荷が削減されますが
それでも負荷が発生します。
コメント文とは異なり連続で並んでいても個々に負荷が発生します。
負荷は1個につき変数操作コマンド5個分です。

デバッグ文の文字列が長ければ長いほど追加で負荷が発生します。

変数操作の一括代入負荷

変数操作コマンドで代入先のコモンセルフ変数を2個以上にして一括で
処理することができますが、負荷は一括で処理する方がかなり高いです。

毎フレーム実行するような箇所では個別に処理するようにしましょう。

ピクチャ表示とピクチャ移動負荷について

『ピクチャ表示』よりも『ピクチャ移動』コマンドの方が負荷が軽いです。
ウディタ3では画像ファイルを表示する場合約5~10倍の負荷差がありました。
※ピクチャ表示に指定するファイルパスが長いほど差が大きくなるようです
※ファイルパスが短ければ短いほどピクチャ表示負荷が軽くなります

文字列をピクチャして表示する場合も軽くなりますが
『ピクチャ移動』に変更しても2倍軽くなるかならないかぐらいのようです。

画像ファイル表示のピクチャの枚数が非常に多いゲームでは
『ピクチャ移動』による更新を主としたシステムに
変更することを検討したほうがよさそうですね。

※ただし、新機能であるピクチャコピーやピクチャID移動は超激重だったので
 この辺りの機能を併用して『ピクチャ移動』更新のシステムに改変するのは
 おすすめできません。

ピクチャ以外の画像更新停止

ウディタ標準のマップ機能を利用しない場合は
イベント制御の『ピクチャ以外停止』コマンドを使用して
マップ関連に更新を無効化することをおすすめします。

これにより描画負荷がわずかに下がります。

ピクチャの事前表示(メモリロード)は必要?

頻繁に使用するピクチャを画面外に不透明度0で表示しておいて
メモリロードにかかる時間を省略するテクニックがありましたが
現在ではほぼやる必要はないです。

現状のウディタでは
128MB以内の.wolfファイルはゲーム起動時に
メモリに読み込まれます。

よって配布時にデータを暗号化する人は
起動時にメモリに読み込まれるようになるため
画面外に表示する処理は無駄な負荷になるのでおすすめしません。

-- 2023/09/09 17:48 追記 --
ゲーム起動時にメモリに読み込まれていても
ピクチャのメモリロードは必要そうでした。
巨大な画像(8196x8196)などで試すと1枚の画像でも事前表示していなければ
初回表示に負荷が大きくかかるようです。

全て事前表示しないといけないわけではないですが
大きめの画像や一度に多量の画像を新しく表示する場合は
事前に画面外の不透明度0で表示するテクニックは今後も有効なようです。
※DirectX的にはテクスチャの作成に時間がかかっている?

条件分岐の分岐箇所負荷

条件分岐は先頭に近い条件を満たせば満たすほど負荷が軽くなります。
よってゲーム実行中に最も条件を満たす可能性が高い条件を先頭の分岐に設定することで
処理負荷の改善が見込めます。

上記以外に更に条件分岐を足すような実装を多重で行っていると
最も深い条件分岐を達成するにはかなりの負荷がかかります。
条件を満たしやすい分岐はなるべく先頭で行うことをおすすめします。

意識を忘れやすいものは、全ての条件を満たさないパターンです。
大量の分岐(8~12個以上)があるにもかかわらず頻度的には分岐を全て満たさない場合が多いときは
全ての分岐チェックを踏んでしまわないように改善しましょう。
1番最初の分岐は全て満たさないときに多い比較値で早期に条件を抜けるようなイメージです。

分岐数が20以上など膨大なうえ特に頻度の偏りもない場合は
最初に『10以下』と『10より大きい』など半分に分けて
二分探索していく方がよいです。

条件分岐の『データを呼ばない』負荷

直接数値を条件に指定したときに『データを呼ばない』に
チェックを入れた方が極わずかに軽くなります。
※変数操作コマンドでの『データを呼ばない』はチェックを入れると逆に激重になるのでご注意ください。


※無理に実装済みの条件分岐を書き換えていく価値があるほど軽くはなりません。
 実行回数の非常に多い箇所や、わらにもすがりたいぐらいな人向けです。

ループ中断の負荷

ループ内での『ループ中断』コマンドの負荷は
どのタイミングで実行しても負荷は変わりません。
※ウディタ2世代ではループの最後尾側で実行する方が高速でした。

[0]回ループの負荷

変数を使用せずに直接『0』回を指定した回数付きループは
ほぼコメント文1個程度の負荷しか発生しません。
※数値が『0』の変数を回数に指定した場合は高速化されずに本来の負荷が発生します

また、0回ループ内にどれだけコマンドを挿入しても
負荷は変化しません。
※ウディタ2世代では0回ループでも重いうえに0回ループ内のコマンドが多ければ多いほど処理が重くなる仕様でした

変数操作の実数計算負荷

変数操作コマンドで小数の計算を可能にする実数計算機能がありますが
このチェックボックスをONにして実数計算を行うと計算負荷が高くなります。

小数で計算する必要性が無ければ下記のように実数計算を使わない方法がおすすめです。

実数計算による小数で計算する必要があるパターンは
掛け算を行ったときにオーバーフローが発生する可能性がある場合です。
その心配が無ければ実数計算を使わない方が処理負荷を軽減できます。
うまく使い分けていきましょう。

変数操作のチェックボックス

変数操作の各種チェックボックスはONにすると
負荷が大きく上昇するので、不必要にONしないほうがよいです。

『結果を±999999に収める』も使用せずに下記のように
3つのコマンドで処理したほうが高速です。

|■変数操作: CSelf0 += 100000 + 0
|■変数操作: CSelf0 上限= 999999 + 0
|■変数操作: CSelf0 下限= -999999 + 0

ただし、オーバーフローを引き起こすような計算をする場合は『結果を±999999に収める』にチェックを入れていない場合だと±が逆転する可能性があるのでご注意ください

条件分岐を減らす工夫

条件分岐は重くなりがちなため極力減らした方が
高速に処理できます。
ここでは条件分岐を減らす方法について紹介します。

ブーリアン

変数Xが『0』か『1』かで代入する値を変える処理は
条件分岐を使わずに高速に処理することができます。

大きい方の値を求める

変数AとBの内、大きい方の値を求めるときも
条件分岐を使わずに高速に処理可能です。

小さい方の値を求める場合は
『下限』の代わりに『上限』を使えばOKです。

コモンイベントの呼び出しに条件を使わない

これは上級者向けですが
条件に応じてコモンイベントを呼び出すような実装をすることがあると思います。

以下はシーン的な変数を用意して
現在のシーン別にタイトル画面などのコモンイベントを呼び出している例です。

これは条件分岐を使わずに同じ処理を実現可能です。
以下のように組むと処理が2倍以上高速になります。

自分はこの手法をよく利用しています。
ゲーム起動時の初期化などのタイミングでコモンイベントIDを取得して
500000~の呼出値をDBに自動的に登録しています。

引数が通常渡せない問題がありますが
イベントコードを弄れば引数も渡せるようになります。

ウディタ2世代で実装した条件分岐

ウディタ2世代では条件分岐の分岐は『3つ+上記以外』でした。
ウディタ3では『4つ+上記以外』に拡張されています。

2世代で実装している条件分岐の内
上記以外の中で更に条件分岐している箇所は
4つ目の新しい分岐を使用するように改善すると
条件分岐コマンドを減らせる可能性があります。

実装済み処理に対する負荷軽減のやり方

実装済みの処理を軽くしたいときに
どのように考えて軽くできそうなところを
見つけたらいいのかについて解説します。

細かいアルゴリズムみたいな話になると
ややこしかったりケースバイケースになったりするので
簡単な部分だけの言及にとどめているのでご了承ください。

調査対象の決め方

ゲーム全体の処理を調査するに越したことはないですが
規模の大きなゲームになると細かく見てられないと思います。

その場合は以下の点を意識して
負荷軽減ができるかどうか調査対象を決めてみてください。

  • ループ処理になっていて且つ実行回数が多い箇所
    • シューティングゲームでは多くなりがちな弾の処理など
  • 呼び出し回数の多いコモンイベント
    • 色々な箇所から呼ばれる汎用的なコモンイベントなど
  • 1フレーム内の実行回数は少ないがゲーム全体を通して常に実行されるような処理
    • プレイヤーの処理など

ループ内で無駄に演算している箇所がないか

次のような無駄な処理を組んでいる可能性があります。

  • ループ外で初期化できる処理をループ内で毎回行っている
  • ループ内で1つコマンドで処理できるものを複数のコマンドで処理している
    • ただし複数のコマンドで処理したほうが高速なケースを除く

無駄な処理をしている例

以下はループ処理で『X番の変数呼出』を利用して処理している例です。


上記処理は少なくとも下記2つの無駄があります。
  • ループ外で初期化した方が良い処理がある
  • 1つのコマンドで処理できるのに2つのコマンドで処理している

改善例①

下記2点の修正を施してみました。

  • 負荷の高い『データを呼ばない』を利用した1600050をセットする処理をループ外へ移動
  • 実際の『呼出値』を計算する処理を1つにまとめる

たったこれだけですが、全体の負荷が約30%軽くなります。

改善例②

今回の例ではそもそもカウンタ変数がいらないので下記のように改善もできます。
これなら最初の改善前から35%ぐらいは改善されると思います。

コモン内でコモンを呼び出すなど階層化時の無駄について

上記でループ内に無駄がないかの話でしたが
これがコモンの中でコモンを呼び出しているパターンだと無駄が見えにくくなります。

①コモンAでループ処理
②ループ処理内でコモンBを呼ぶ
③コモンBの中でコモンCを呼ぶ

上記のような処理が組まれている場合に①で処理したものを②や③でも
同様に処理してしまうようなパターンがあった場合に見逃しやすいです。

例えば、
CDBから特定のデータをコモンAで取得して処理したが
コモンBもしくはCでも同様のデータをCDBから取得してしまう。
などですね。

取得するデータが毎回固定な場合(プレイヤーの値など)は
通常変数や予備変数にコモンA層で保存してB/C層では
そちらから取得するような軽減方法もあります。
※通常変数や予備変数に対する演算はコモンセルフ変数とほぼ同等で軽いです。

上級者以上向け

コモンイベント呼び出し負荷

コモンイベントを呼び出すときにも、
コモン内の処理とは関係なく負荷が必ず発生します。

大きく分けると呼び出し方に
『名前呼び出し』『番号呼び出し』の2パターンありますが
名前呼び出しの方が番号よりも2倍ぐらい負荷が高いです。

よってループ回数の多い箇所のコモンを番号呼び出しにすると
負荷が改善する可能性があります。

ただし、開発作業の効率を考慮すると『番号呼び出し』は問題が多いため
『名前呼び出し』のままにすることをおすすめします。
※この説明を上級者向けに置いているのも軽いからといって開発中に安易に置き換えると大変なことになる可能性があるからです。

コモンイベントの引数負荷

引数は最小限にする

コモンイベントに最大で数値引数/文字列引数がともに5個設定できますが
この引数が多ければ多いほどコモンイベントを呼び出すときの負荷が増大します。

呼び出す回数の多いコモンイベントは
なるべく引数が少ない設計を心がけましょう。

引数を減らせないパターンはたくさんありますが
1つのコモンに機能を足しすぎて、特定のモードでは
無駄に引数をセットしてしまうコモンを作ってしまっている人もいると思います。

第1引数に動作モード的なものがあり、
モードAでは第2,3引数が必要で
モードBでは第2引数以降がいらないようなものです。

コモン内の処理的に仕方がないパターンはありうると思いますが
コモンイベントをモード別に分割できるなら
複数のコモンに分割したほうが軽量且つシンプルで良いと思います。

強○的に引数を減らす

上記で説明したように引数を最小限にする設計がおすすめですが
コモンイベント側の設定を変えずに引数による負荷を減らす方法があります。

引数によって呼び出し負荷が増加する原因は
厳密には各コモンイベントに設定した引数の数ではありません。

コモンイベントを呼び出すときに設定している引数の数が原因です。
この引数の数は強○的に『コモンイベントに設定した引数の数』になるため
通常利用ではコモンイベント側の設定から引数を減らすしかありません。

ただし、コモンイベントを呼び出すイベントコードから
いらない引数を排除すれば排除した分だけ負荷が軽減されます。

もちろんダブルクリックなどで改変したコマンドを修正すれば
もとに戻ってしまいめんどくさいので、あまりおすすめはしません。

ビット演算による負荷軽減

ウディタの数値変数は32bitのInt型です。
つまり、1つの変数に最大で32個のON/OFFフラグを格納することができます。

大量のフラグデータをCDBなどから取得して
条件をチェックするような処理がある場合

それぞれフラグを1個の数値変数に格納してしまうことで
1回のCDBアクセスで32個のフラグを取得できます。

もちろんON/OFFフラグではなく使用するビット数を決めて区切ることで
複数の数値を格納することも可能です。

例えば8bitで0~255の値を表現できるので
この場合1つの32bit変数に最大4つの『0~255』の数値を格納できます。

ON/OFFフラグであれば条件分岐の『ビット積』を利用して効率よく判定できますが
それぞれの値を変数から抽出する場合は
計算コストがかかるので利用の仕方にあわせて採用するかどうかは判断したほうがよいです。
※一般的にビット演算は高速ですが、ウディタでは他の演算子と同等かそれ以上の負荷なので下手な実装をするとややこしくなったうえに重くなる可能性があるのでご注意ください。
※これはウディタでは論理積しかサポートされておらず、論理和や排他的論理和、シフト演算などは自分で演算する必要があるため効率よく活かしきれない問題があるからです。
※ウディタでビット演算フル活用したモートンオーダーとかやりたい……

ちなみに下記でビット演算系一式のコモンを公開しているので
ビット演算を利用してみたい人は参考にしてみてください。
https://silsec.sakura.ne.jp/WolfRPGEditor/CommonList/html/tdv249.html#14400752006401
※↑2015年に公開していたコモンですが先ほど一部負荷改善と4つのコモンを追加して再更新しました。

3Dゲームを実装している人向け

ウディタ3で高速化されて、
ウディタでも3Dを動かしやすくなったので
3Dゲームの実装に関する負荷軽減技術についても
ウディタに関係しそうな範囲で少し紹介しようと思います。

3D処理を作っている方は参考にしてみてください。
ちなみに自分は3D処理はウディタでずいぶん昔にやって満足しているので、3D関連の技術をウディタで深堀する気はほぼないです。

視錐台カリングによる負荷軽減

カメラの見える領域(視錐台)の外に配置されたポリゴンを
描画対象から除外する技術です。

視錐台との内外判定で除外します。

ウディタで3D描画をする場合は自由変形描画を多用するため、
可能な限り描画物を減らしたいはずです。
ウディタで3Dをやる場合は必須機能だと思います。
ただし判定負荷もウディタ上で行う場合は大きいので工夫が必要になると思います。

LOD(Level of Detail)による負荷軽減

これは一般的にカメラから近いオブジェクトはポリゴン数が多く、
遠いオブジェクトはポリゴン数を減らすようにする技術です。

3Dモデルを用意した時に近景用モデルと遠景用モデルを
用意して距離に応じて参照するモデルを切り替えます。

どれだけの段階に分けるかはゲームによりますが
一般的には3段階~5段階ぐらいあるのではないかと思います。

ウディタでは3D頂点の計算コストがとんでもなく大きいので
それを削りつつ近景では高品質を目指すLOD機能は必須だと思います。

オクルージョンカリングによる負荷軽減

遮蔽の裏に隠れたオブジェクトを判定して描画を除外する技術です。
遮蔽が多いような3Dマップを作る場合は負荷軽減に有効です。

ただし、技術としては難しい部類なのでウディタで実装するのは
厳しいイメージがあります。

モーションLOD

名前がこれでよいのかはイマイチよくわかっていませんが
モーション更新頻度をカメラから距離が遠くなると減らす仕組みです。

簡単に言えばボーンの計算コストは高いので
カメラから離れた場合は更新頻度を落としてスキップしてしまおうというものです。

パーティクルLOD

パーティクル(エフェクト)の粒子の放出数などを
カメラから離れると減らす仕組みです。

3Dモデルとビルボードの切り替え

3Dモデルは頂点数が多くウディタだと描画負荷がかなり高いです。
そこでモデルによっては1ポリゴンのビルボードで描画すると負荷を抑えられます。

ビルボードは1枚のポリゴンをカメラ方向に常に向かせる技術のことです。

例えば昨今の3Dゲームでも、近くにいると木が3Dモデルで表示されますが
かなり遠くに離れると1枚のビルボードで表現された木に
切り替わるような実装があります。

4分木や8分木による空間分割

ウディタでも2Dゲームを作る際に空間分割の機能を実装することがあります。
3Dゲームでは主に8分木や4分木という仕組みで空間分割を実装することが多いです。

3Dゲームだと配置モデルが広いフィールドの中にたくさん配置されるため
それぞれの配置物へのアクセスを効率的に行うために
8分木や4分木による空間分割が利用されます。

モートンオーダーという仕組みで各空間にアクセスしますが
この仕組みがとても優秀で一瞬で配置物が所属する空間を計算することができます。
ただし、ビット演算を利用するのでビット積しか使えないウディタでは少し荷が重いです。
※2Dゲームでも利用できる技術なので空間分割の手段として採用できます

超上級者向け

コモンイベントの自動生成orコンパイラ最適化

コモンイベントを自動生成したり、コンパイルによる最適化処理のようなものを
各コモンイベントに適用することで
無駄なコメント文等のコマンドや、開発効率上できなかったイベントコマンドの番号呼び出しへの自動変換を行い高速化することができます。

自分が開発/公開しているWoditorOptimizerがいわゆるこういう類の機能です。
ただ、WoditorOptimizerはいちいちゲーム公開時などに最適化しなおさないといけないので非常にめんどうです。

ゲームをテストプレイするときにビルドを走らせて
それで自動で全最適化してからテストプレイ実行みたいな環境を作ることができれば
処理負荷軽減はいくらでも自動でできるようになるので最高です。

実際に環境を作るとなるととんでもなく大変なので
そこまでして最適化したいのか?という話にはなってきますが
ウディタでの最適化の最終形はこれだと思ってます。

未だにβ版なので直接連絡いただいた方にしかお渡ししていない状態ですが
ウディタツール開発用ライブラリの『WodiKs(Ver0.96)』を頑張って使えば
コモンイベントの生成とか最適化とか作れるのでウディタツールの開発に興味がある方はご連絡ください。
※最新版を正式に公開する可能性はありますがいつになるかは現状不明です

さいごに

当初の予定よりもかなりボリュームが多くなりましたが
ウディタ3での処理負荷軽減に関する話をいろいろとまとめてみました。

負荷軽減の話は色々書きましたが、正直ウディタ3は爆速なので
8割以上の方は処理負荷なんて気にしなくても問題ないと思います。

K-Shin07 2023/07/29 20:33

【Wodistant】ウディタデバッガーはどうやって実現しているのか?[解説]

今回の内容は Wodistant Ver1.4.0 α版に実装された
ウディタデバッガーの仕組みについて解説する内容となっています。

どうやってウディタデバッガーのブレークポイントなどが実現できているのか
興味があればご覧いただければと思います。

技術ある人が見たらおそらく再現できるぐらいの
ボリュームで書いてるので内容がとても多いです。
目次を用意しているので、全部見なくてもいいやって方は気になる
項目だけ見てやってください。

また、Wodistantの技術解説系は前回と同様にフォロワー向けに
公開させていただきますのでご了承ください。

フォロワー以上限定無料

ウディタデバッガーの仕組みについて解説しています。

無料

K-Shin07 2023/07/26 18:12

【Wodistant】待望のウディタデバッガー機能のα版公開!

Wodistant-Ver1.4.0.0のα版を公開しました!
※まだα版なので更新手順は通常とは異なります。(後述)

デバッガー機能が実装され、
遂にウディタでブレークポイントが使えるようになりました!
※ブレークポイントが何なのかについては後述します
※本機能は現在ウディタPRO版でのみ動作します

これを使用することで
意味不明なバグが発生したときのデバッグ効率が格段に上がります!

更新手順

下記画像に更新方法をまとめています。
※α版/β版はツール内更新のみで提供します。


※パスワードコピペ用『w140a050_5Ad2

Wodistant本体をまだ持っていない方は下記ページからダウンロードできます。
https://alpha-stella.com/tool/wodistant/

ブレークポイントってなに?

プログラミングによる開発において多用するデバッグ機能の1つです。
任意の処理タイミングでプログラムを一時停止することができます。

ウディタで開発している場合、大多数の人は
『文章表示』コマンドを設置したり
『1ウェイトの無限ループ』を配置したりすることで一時的に停止して、
変数値の確認などをすることが多いと思います。

ただ『文章表示』で停止したあと、続けて別の箇所でも停止したい場合や
途中から停止してほしく無くなった際は
コモンイベントを編集して再度ゲームを起動したりF12等でリセットするしかありません。

ブレークポイントを利用することでゲーム実行中に
いつでもどこでも任意の処理タイミングでゲームを一時停止/解除することができます。
更に『停止した箇所のコモン』及び『そのコモンの呼び出し元コモン全て』のコモンセルフ変数値を確認することができます。

ウディタデバッガーの実演

サンプルゲームでウディタデバッガーを実際に使っているところを
動画にまとめてみました。
使い方の流れについては下記動画を参考にしてみてください。
https://youtu.be/QPQygWzeHwo

フィードバックについて

まだα版なので、何かしら問題が発生する可能性があります。
万が一問題があればWodistant上でフィードバックを送れるようになっているので
そちらからご報告いただけると助かります。
(ウディタデバッガーウィンドウ上のフィードバックボタンから報告できます)

もちろん要望もあればお気軽に送って頂けると助かります。

今後の予定

以下に今後の更新予定についても記載しておきます。
・β版の公開:2023年9月~10月頃
・正式版の公開:2023年11月頃
※暫定なので時期が変更される可能性はあります

現在ウディタデバッガーはウディタPRO版でのみ動作する状態です。
正式版でもPRO版での動作を予定していますが
機能制限状態で通常版ウディタでも利用できるようにするかもしれません。

どちらにしろβ版の段階では
一時的に通常版ウディタでも利用できる状態にする予定です。

またβ版で実装する可能性が高いものも下記に記載しておきます。
・データブレークポイントの実装
  ・特定の変数の値が変わった瞬間に自動的に停止するブレークポイント
・条件ブレークポイントの実装
  ・設定したブレークポイントを通過した時に
   任意の変数の値が特定の条件を満たすときのみブレークを実行する機能
・『1600000』もしくは『\cself[10]』などの文字列指定で現在の値を確認する機能
  ・現状いくつか課題があるので解決できたら実装される可能性あり

最後に

ウディタデバッガーを利用することで
とても効率よくゲームのデバッグができるので、
原因が分からないバグが発生した際は、是非試してみてくださいね。

ウディタデバッガーがどのように動作して
どのような仕組みで機能を実現しているかについては
別途フォロワー向けにまとめようと思います。
こちらはもう少々お待ちください。

« 1 2 3

記事のタグから探す

月別アーカイブ

限定特典から探す

記事を検索