VRChatワールド「Ludo」制作記
はじめに
2024年5月にVRChatのワールド「Ludo」を公開しました。
血で血を洗うボードゲーム「Ludo」をVRChatでプレイできます。
本記事は制作時に工夫したポイント等をまとめたものとなります。
備忘録に近いものになるため、ご了承ください。
同期について
Ludoは、ゲームルール自体は至ってシンプルなスゴロクゲームです。
ですがどんなにシンプルなゲームでもやはり気を使うのが同期です。
同期なしで制作するコストが100とすると同期するのに150、LateJoiner対応するのに200くらいコストが掛かります。(たいへん)
同期方式
同期の方式は大きく分けて3つあり、それぞれメリット・デメリットがあります。
EventSync - イベント同期 (SendCustomNetworkEvent)
メリット :全員に送信できる、誰でも送信できる
デメリット:引数を指定できない、LateJoiner対応が困難
ContinuousSync - 連続同期
メリット :同期変数の値を全員に共有できる
デメリット:同期変数の変更にはオーナー権限が必要
同期タイミングを指定できない
ManualSync - 手動同期
メリット :同期変数の値を全員に共有できる
任意のタイミングで同期できる
デメリット:同期変数の変更にはオーナー権限が必要
Ludoでは原則Masterで処理を行い、その結果を手動同期で共有する方法を取りたかったため、イベントメッセージ同期を採用しています。
イベントメッセージ同期
任意のパラメーターを付与したイベントメッセージを、任意のプレイヤーに送信することができる仕組みです。
この方式はオーナー権限を移譲せずに、各プレイヤーが操作を行う際に非常に優れています。
実装イメージとしては、各プレイヤーにオーナー権限を割り当てたスクリプトにて、同期変数を手動同期することでイベントメッセージの送受信を実現しています。
同期変数には DataDictionary でイベントメッセージに必要な下記情報を格納し、送信することでイベントメッセージを実現しています。
・送信元プレイヤーID
・送信先プレイヤーID
・イベント名
・ペイロード(イベント引数)
イベントメッセージの応答確認
イベントメッセージ同期は非常に便利なのですが、送信先のプレイヤーがワールドから離脱してしまった場合、イベントメッセージが処理されない可能性があります。
上記を回避するためにイベントメッセージ同期では、応答確認(ACK)を行っています。
送信後に一定時間応答確認が取れない場合、再度イベントメッセージを送信することで上記の問題を解消しています。
CPUについて
今回制作したLudoはプレイ人数が4人固定となっています。
これにより、人数不足などによってプレイする機会を消失するのを避けるために、CPUを作成しました。
ただ、常にランダムなコマを動かすだけでは面白くないため、色々な条件付をしてCPUの行動を決定しています。
相手のコマを倒せる場合は倒す(絶対殺すマン)
自分が勝利する上で相手の妨害は非常に大事です。
ここで手心を加えると敗北する確率が上昇するため、CPUは相手を倒せる場面では優先的に倒すことにしています。コマが2つ以上コースにない場合は優先して出す
Ludoはコマの選択によって戦略が生まれます。
ですが、コマが1しかコース上に出ていないと動かすコマは選べないため、戦略が生まれません。
そのため6の目が出た際、コマが2以上コースにない場合は優先的にコマを出します。より安全に進めるコマを移動する
コマごとに移動先のマスに対して安全度を求め、より安全な方へ進めるようにしています。
例. 相手のコマの前は安全度を-10、相手のコマの後ろは安全度+10など。
カスタムスキンについて
カスタムスキンは簡単に追加/削除/並び替えができるように構築しました。
下記のエディタ拡張を使い、設定することでUIとコマへの反映をビルド時に行っています。
ダイスロールの可視化について
ダイスロールの結果は毎回乱数によって決定しています。
乱数には偏りがあるため、テストプレイ中に度々不正を疑われるような目が連続で出たことがありました。
上記の不正を払拭するために導入したのがダイスロール可視化システム(タブレット)になります。
序盤は偏ることがありますが、長期で見ると均一になるため、無事身の潔白を証明することができました。
プレイヤー名について
プレイヤー名は日本語を考慮しなければならないため、レガシーテキストを今まで使用していました。
ですが、下記のヌルヲさんの記事を参考にフォールバックフォントを使うことで、TextMeshPro を採用することができました。
VRChatクライアントに内蔵されているフォールバックフォントを使用するため、ワールドデータを増やさず TextMeshPro を使えるので非常に素晴らしいですね。
まとめ
今回初めてゲームワールドを制作することで、様々な技術的なナレッジが蓄積されたのは非常に良かったと思います。
ボードゲーム「Ludo」はシンプルで非常に面白いゲームなので、ぜひプレイしてみてください。