VRC Rogue 2026/05/16

概要
マルチプレイヤー同期が実機で動作確認済み。FlatBuffer8 に起因する [UdonSynced] クラッシュを根本解決し、2クライアント間でマップ・モンスター・アイテム・プレイヤー状態の同期が完了した。あわせて Python バランスシミュレーター(Rogue_simHTML)を整備し、パラメータ調整のワークフローを確立した。
変更点
ネットワーク同期
[UdonSynced] int[]→stringへ変換(DungeonGenerator)- VRChat FlatBuffer8 シリアライザが
int[]を正しく処理できないため、モンスター・アイテムの全属性をビットパックし CSV 文字列(_syncPacked)1本で同期する方式に変更 - フォーマット:
"monCount,pos0,...,pos15,core0,...,core15,atkAlive0,...,atkAlive15,itemCount,item0,...,item11"— カンマ区切り 62 トークン
- VRChat FlatBuffer8 シリアライザが
[UdonSynced] string3本を削除(GameManager)_syncWeaponName/_syncArmorName/_syncLastMessageが同様のクラッシュを引き起こしていたため削除- 武器・防具名はローカル変数として保持(observer への転送なし)
- デバッグ切り分けフラグを解除
DEBUG_DISABLE_DUN_SERIALIZE/DEBUG_DISABLE_DUNGEON_SYNCをtrue→falseに変更
DungeonGenerator.assetの参照修復sourceCsScript: {fileID: 0}になっていた参照を正しい GUID に修正
バランスシミュレーター(Rogue_simHTML)
- Python + Flask ベースのシミュレーターを新規作成
rogue_sim.py— シミュレーター本体 + Flask API サーバーindex.html— ブラウザ上で動作するダッシュボード UIconfig.json— バランスパラメータ(UI から編集・保存可能)
- Web UI 機能
- 試行回数スライダー(100〜10,000)
- Player / Food / Monster / Dungeon / Combat 各セクションのパラメータをリアルタイム編集
- 変更値のオレンジハイライト表示
- フロア別生存率グラフ(シアン/グリーン/オレンジ/レッドの4段階色分け)
- 死因分布・武器分布・防具分布・フロア別死亡数チャート
- SSE(Server-Sent Events)によるリアルタイム進捗表示
- CSV エクスポート(summary / compare / floor / run の4セクション統合形式)
CONFIG SAVE/RESETボタンでconfig.jsonへ永続化
- CLI モード対応
python rogue_sim.py --cli -n 1000で単体実行--csv result.csvで統計 CSV を出力
- LLM 連携テンプレート
PROMPT_TEMPLATE.md— シミュレーション結果をそのまま LLM へ渡す固定テンプレートを整備
バランス調整(config.json 現行値)
食料圧力を強化し、後半フロアでの死亡分散を狙ったパラメータに調整。
| パラメータ | 変更内容 |
|---|---|
player.start_hp | 12 → 20(序盤安定化) |
player.start_food | 100 → 80(食料圧力強化) |
food.hunger_rate | 1 → 3(消費速度引き上げ) |
food.food_heal_min/max | 40〜70 → 25〜45(食料の回復量を削減) |
monster.atk_max | 3 → 4(中盤以降の脅威引き上げ) |
monster.atk_floor_div | 2 → 3(ATK スケールをなだらかに) |
exp_table | 全体的に引き上げ(レベルアップ速度の抑制) |
修正
UdonIntArray.CreateUdonIntArray/Udon.CreateUdonクラッシュ- 原因: VRChat FlatBuffer8 シリアライザが
[UdonSynced] int[]および[UdonSynced] stringを正しく処理できない。内部的に値を sbyte として書き込もうとするため、範囲外でクラッシュする - 対応:
int[]4本をstring _syncPacked(ビットパック CSV)1本に統合。string3本は同期対象から外して削除
- 原因: VRChat FlatBuffer8 シリアライザが
- 同期が届かない(デバッグフラグ残留)
- 原因: クラッシュ切り分けのために立てた
DEBUG_DISABLE_DUN_SERIALIZE = trueが残ったまま本番ビルドしていた - 対応: 両フラグを
falseに戻す
- 原因: クラッシュ切り分けのために立てた
設計メモ
同期変数の制約(FlatBuffer8)
VRChat の現行シリアライザは [UdonSynced] に以下の制約がある。
| 型 | 可否 |
|---|---|
int / float / bool | ✅ 追加可能 |
int[] / string | ❌ FlatBuffer8 クラッシュ |
武器・防具名など文字列を同期したい場合は、テーブルのインデックス(int)で同期し受信側でローカル解決するパターンを使う。
シミュレーターのゲームロジック再現仕様
プレイヤー攻撃ダメージ = max(1, rand(1, STR + atk_bonus) - monsterARM / def_divisor)
モンスター攻撃ダメージ = max(1, monsterATK - playerARM / def_divisor)
EXP報酬 = monsterMaxHP × 2
プレイヤー AI(シミュレーター内)は「HP 40% 未満でポーション即使用、フロア後にアイテム回収、上位装備のみ更新」という保守的ルールベース。実プレイヤーはより賢く動くため、実ゲームのクリア率はシミュレーターより高く出る想定。
バランス設計の方針
- Win Rate の目標帯: 10〜25%(シミュレーター AI 基準)
- 序盤(F1〜10)は生存率 90% 以上をキープし、入口ハードルを下げる
- 中盤(F11〜18)で装備更新と食料管理のジレンマが生まれる設計
- 終盤(F19〜26)が主な死のゾーン、ここで緊張感を出す
次に確認すること
- シミュレーターで現行 config の Win Rate を計測し、目標帯(10〜25%)に収まっているか検証
- 食料圧力強化後に「餓死」が死因として出現するか確認(
food.hunger_rate=3の効果測定) - 武器・防具の中間スペック(長剣・板金鎧)の採用率が低い場合、出現テーブルの調整を検討
- デバッグログ(
[REBUILD]、[GENERATE]、[GM_POSTSER_OK]等)の本番前削除 - 同期後の observer 視点でのインゲーム動作をさらに検証(階段移動・フロア遷移)