【開発[#2] 19日目】戦略SLG

■ 18〜19日目のまとめ

今回は2日分をまとめて記録する。

18日目はScene_StartからScene_Mainへのデータ受け渡し経路を確立し、メインシーンの骨格を実装した。19日目はマップの大幅強化と武将コマンドパネルの骨格実装を中心に進めた。
メインシーン制作へ本格的に着手し始めたが、設計書作成などあまり画像を出せないフェーズでの作業が多く、今は進捗立証が難しい段階です。


■ 18日目(5/10):データ受け渡し経路の確立とScene_Main骨格

データ構造の整備

GameEnums.csにGameResult.InProgress(値:-1)を追加し、従来のIsInProgress boolフラグを廃止して一本化した。あわせてカスタム武将の君主・在野登録対応としてFactionSaveDataにCustomMonarchId、WanderingOfficerSaveDataにCustomIdを追加した。

GameStartData新規作成

Scene_StartからScene_Mainへの初期データ受け渡し専用のstatic classを作成した。

ScenarioDataのマスタは一切書き換えず、全データを複製してGameSaveSlotとして渡す設計にした。NewGameDataとは独立した受け渡し口として機能する。Scene_MainのStart()で参照後にClear()を呼ぶことで使い捨てにする。

OnClickStart()本実装

以下の処理を実装した。

BuildInitialSlot()でScenarioDataを全複製し、プレイヤーの編集内容(君主・配下・勢力名)を上書き。BuildWanderingOfficers()で全武将を走査して在野登録。ResolveDisplacedFactions()でプレイヤーが他勢力から引き抜いた武将の代替を各勢力に割り当て。

引き抜きが発生した場合の処理も実装した。他勢力の君主を引き抜いた場合は配下の中から能力値合計最大の武将を格上げし、空いた枠には同レアリティの在野武将をランダム補充する。在野武将が同レアリティで見つからない場合は一段下で再抽選し、それでもなければ打ち切りとした。

Scene_Main骨格実装

GameSaveSlotからデータを受け取り地図表示を実装した。NewGame時はGameStartData.Slot、LoadGame時はManagerSaveData.GameData.Slots[index]を参照する。ScenarioDataはマスタ参照のみ(読み取り専用)。

地図は拠点図・勢力図の切替に対応した。ターン送りボタン、タイトルバック・ゲーム終了ボタンも実装した。フェーズ管理・コマンド・戦闘・AIは引き続き未実装。


■ 19日目(5/11):マップ強化・コマンドパネル・情報引き渡し対応

ボタン登録方式の統一

ManagerMain・ManagerStart・ManagerTitleの全ボタンについて、Inspector直設定からAddListener方式に統一した。

従来は一部ボタンがInspector上のOnClickリストに直接設定されており、状態遷移による一括制御ができない問題があった。RegisterButtons()を新設してStart()から呼ぶ方式に統一し、全ボタンで状態チェック(_state != Idle)が機能するようにした。コードを見れば全ボタンの挙動が把握できる状態にすることが目的で、InspectorとコードのどちらかだけでなくどちらもあわせてOnClickを確認しなければならない状態を解消した。

ワールドマップの2倍化

1920×1080のワールドマップをそのまま使用するとエリア戦で未使用エリアが広く残り見栄えが悪いため、3840×2160に拡大する方針に変更した。

単純な拡大ではピクセルが荒れるためAIアップスケーリングを採用した。Real-ESRGANのアニメ・イラスト向けモデル(RealESRGAN_x4plus_anime)をローカル環境で実行し、ディテールを保ったまま2倍化した。RTX3090 + CUDA環境で短時間で処理できた。Pythonとpipで環境を整えるだけで動作し、登録や料金は不要。

MapContainerの導入とスクロール・ズーム実装

Canvas_Main直下に3840×2160のMapContainerを新設し、Layer_Territory・Layer_Connection・Layer_Bastionを配下に移動した。

スクロール

右クリックまたは中ボタンドラッグで地図をスクロールできる。マップ外にはみ出さないようClampMapPosition()でスクロール範囲を制限している。

ゲーム開始時はプレイヤー勢力の所有拠点の重心座標を自動計算し、その位置が画面中央に来るよう初期表示位置を調整する。

ズーム

100%・75%・50%の3段階ズームに対応した。マウスホイールとズームボタン(3つ)の両方で操作できる。ズーム中心はマウスカーソル位置基準で計算している。拠点アイコンと接続ラインはRebuildPositions()でズーム倍率に追従して再配置する。ズーム時はSmoothStep補間による0.15秒のアニメーションを挟む。

GameUtility.cs新規作成

通常武将(OfficerDatabase)とカスタム武将(RecordData)からIOfficerを解決する共通ユーティリティとしてGameUtility.csを新規作成した。

Scene_Startでは用途が限定的だったため該当箇所に直書きしていたが、Scene_Mainではコマンド処理・AI処理・戦闘処理など至る所でIOfficer解決が必要になるため共通化した。今後はこのユーティリティを経由することを徹底する。

武将コマンドパネル骨格実装

メインシーン下部に武将カードを最大10枚並べるPanel_Commandsを実装した。左クリックで下からスライドイン、右クリックでIdle状態へ戻る。Panel_OfficerCommandCardが1枚のカードを担当し、顔画像(256×256・FaceSmall)と武将名を表示する。

これに合わせて256×256の切り出しスプライト(FaceSmall)を新規追加した。OfficerSpriteImporterで既存の_Faceスプライト(384×384)に加えて_FaceSmall(上部中央256×256)を一括登録できるよう拡張した。カスタム武将もImageImporter.CropFaceSmall()で生成・保存するよう対応した。

ManagerMainの状態遷移にCommandInput(コマンドパネル表示中)を追加した。

以下は、まだモックアップ実装の段階だが、マップの拡大/縮小とスクロールに対応したメイン画面。

勢力名・君主名のJp/En分離対応

従来、勢力名と君主名は1つの入力フィールドで日英共用していた。フォントアセットの言語対応の観点から、日本語・英語を独立した入力フィールドに分離した。未入力のままにすればデフォルト値がそのまま使われる。

Panel_FactionEditの入力フィールドをJp/En各2つに拡張し、Panel_FactionConfirm・ManagerStartも対応した。FactionSaveDataにMonarchNameJp・MonarchNameEnを追加してScene_Mainへの引き渡しに対応した。

また君主顔画像の差し替え情報(FaceSmallPathを含む)もGameSaveSlot経由でScene_Mainに引き渡すよう対応した。武将コマンドカードでは君主カードのみ、編集済み名前とFaceSmall画像をOverrideName/OverrideFace()で上書き表示する。

ゲーム設計書の整備(Googleドキュメント)

実装と並行してゲーム設計書をGoogleドキュメントで整備した。

今回確定・追記した内容は以下の通り。

ゲームフェーズ設計 1ターンを7フェーズで構成することを確定した。ユーザー入力が発生するのは④結果表示フェーズと⑥コマンド入力フェーズのみで、それ以外はクリックによるページ送り待ち程度に抑える設計としている。

コマンド仕様 内政・軍事・外交・人事・謀略の全コマンドについて計算式・適用特技・例外処理を確定した。武将1名につき1コマンドを入力する方式で、拠点数に応じて配下枠が最大9名まで拡張する仕様も確定している。

戦闘仕様 ベース戦力値の計算式、兵科補正テーブル、三つ巴以上の戦争処理、兵力の決算式、捕縛確率まで一通り確定した。

AI行動仕様 行動優先度を8段階で定義した。1年目は戦争しない・計略引抜は実行しないなどの制約ルール、同盟検討ロジック、難易度ボーナスの方針も記載した。

シーン内UI構成 状態遷移の定義を追記した。現時点では骨格のみで画面レイアウトは次フェーズで確定予定。

設計書は実装の進行に合わせて随時更新していく運用としている。


■ 現時点の開発状況

カテゴリ状況
データクラス全般✅ 完了
GameUtility✅ 新規完了
Scene_Initialize✅ 完了
Scene_Title✅ 完成
Scene_Start✅ 完了
Scene_Main(地図表示)✅ 完了
Scene_Main(スクロール・ズーム)✅ 完了
Scene_Main(武将コマンドパネル骨格)✅ 完了
Scene_Main(フェーズ管理・コマンド)⬜ 未実装
Scene_Main(戦闘計算・AI)⬜ 未実装
Scene_End⬜ 未着手

■ 次回の作業予定

シーン内UI構成の設計を固めてから、コマンドメニューの実装に入る。フェーズ管理の骨格を先に作り、コマンド入力→結果表示の流れを繋ぐ予定。