【個人ゲーム開発36日目】戦術SLG制作

「出した。」

36日目は、リリースの日でした。

BOOTH、itch.io、X。
朝から動いて、気づいたら夜になっていました。

作ったものを世界に出す、という行為がこんなに緊張するとは思っていませんでした。
反応があるかどうかより、「出した」という事実の方が、今は大きく感じています。


■ 本日やったこと

BOOTH商品ページを公開した

サムネイル選定から商品説明テキストの作成(日英中3言語)、段落構成の整備まで、一から作りました。

こだわった点はひとつ。
制作環境については何も書かなかった。

「Unity製」「フルスクラッチ開発」と書きたい気持ちはありましたが、それはプレイヤーにとって関係のない情報です。
伝えるべきはゲームの中身だけ、と判断しました。

itch.ioにも公開した

海外向けに英語ページを用意しました。

ひとつ気づいたことがあります。
紹介文に「Nectaris」と書いていたのですが、海外では「Military Madness」として知られているタイトルでした。
両方を併記する形に修正しています。

Symphony of Steel is a turn-based hex strategy game inspired by the classic tactical SLG “Nectaris” (known as Military Madness in the West).

プレイ動画(Stage 1クリアまで)もYouTubeに限定公開し、ページへ埋め込みました。
動画があるとページの説得力が全然違います。


■ 36日間を振り返る

せっかくなので、今日は開発の変遷を画像で振り返ってみます。

戦術マップの変遷

開発初期、マップは本当に殺風景でした。
色のついた四角形がヘックスを示しているだけで、「これがゲームになるのか」と自分でも半信半疑でした。

以下は3月16日頃の画像。丸や四角がユニットです。

地形チップが増えるにつれて、少しずつ「戦場らしさ」が出てきました。
草原や森、都市。仮の地形画像を作成して配置するだけでゲームっぽさもアップ。
ユニットが置かれた瞬間に、はじめてゲームに見えてくるものです。
しかし素材がAIポン出しで統一感無いですね(笑)

現在のマップです。
地形チップはまだ全14種中5種しか完成していませんが、
それでも初期と比べると隔世の感があります。
異なる地形間の接続とか作れてないですが、質感はだいぶまとまってきたかなと。

戦闘画面の変遷

戦闘画面は、最も試行錯誤した部分です。

最初期は、まずユニットを表示する。次にただ数字が表示するといった感じで見た目も全然作り込んでません(笑)
ATKとDEFとHPが表示されているだけで、演出も何もない。
常時表示されているデバッグ用ボタンがなんとも。

以下の画像は3月17日から3月18日頃に撮影していました。

その後、戦闘背景・ユニットスプライト・エフェクトと順番に追加していきました。
爆発エフェクト、ヒットエフェクト、回復エフェクト。
音も付いた。
少しづつ現在の形に近づいていきます。

この辺で大まかなイメージが固まってきた感じです。画像は3月23日に撮影。

そして36日目の時点では、補正表示まで追加されています。
地形ボーナス、支援ボーナス、包囲ペナルティが色分けされてフェードインする。

「数字が並んでいた画面」が、ここまで来ました。

UIの変遷

UIはおそらく、最も変化が激しかった部分です。

初期のUIは仮置きの白いパネルばかりでした。
フォントも暫定、色も暫定、レイアウトも暫定。
「動けばいい」という段階です。

タイトル画面もテキスト直書きしてるだけのシュールさ。
3月19日のスクリーンショットですね。見た目はともかく動けばいいという感じ(笑)

戦術画面も早期に下部パネルは作りだしていますが、右側はすっかすかでターン終了のボタンだけ配置してただ動かせますといった状態。
以下の画像は3月25日に撮影してます。この辺の作業の2~3日で劇的にゲーム画面が変化しました。

現在のUIです。
タイトル画面は大幅に改修し、戦術画面もユニット情報パネル、フェーズ表示、各種ボタンなど賑やかになりました。
まだ統一感に課題はありますが、「ゲームのUI」として機能するものになりました。


■ 36日間でできたこと・できなかったこと

できたこと

  • ヘックスグリッドの戦術マップ
  • ターン制の戦闘システム
  • 地形効果・支援ボーナス・包囲補正
  • 熟練度システム(0〜20・星表示)
  • セーブスロット3つ
  • 日英中3言語対応
  • BGM・SE
  • 勝敗ファンファーレ
  • バトル画面補正表示
  • セーブデータバージョン管理基盤
  • DEMOビルド完成・公開

できなかったこと(正式版へ先送り)

  • 解像度1920×1080対応
  • ピクセルアートの統一感
  • 自動ターン終了
  • 画像系素材の準備(一部、DEMO完成優先で先送りなど。)

「できなかったこと」は、意図的に先送りにしたものがほとんどです。
完璧を目指してリリースしないより、動くものを出してフィードバックをもらう方が正しいと判断しました。


■ これから

Steam版の公開を5月17日以降に目指しています。

まずはSteamworks SDKの導入。
そしてストアページの素材準備。

DEMOへの反応を見ながら、正式版の完成度を上げていきます。

無料で遊べるDEMO版はこちらです。

BOOTH:https://atelier-ksg.booth.pm/items/8223410
itch.io:https://hakubyousai.itch.io/symphony-of-steel-demo


執筆後記

リリース日の記事を書くのは、思ったより難しかった。

「やったこと」より「感じたこと」の方が多い日でした。
出してしまえばこっちのもの、と思っていたのですが、出した後の方が静かで、少し怖い。

反応がくれば嬉しいし、こなくても続ける。
それだけです。

【個人ゲーム開発35日目】戦術SLG制作

「リリースの形が、ようやく見えてきた」日

35日目は、開発系の実装とリリース準備を同時に進めた一日でした。

バトル画面への補正表示追加。
セーブデータのバージョン管理基盤の導入。
ビルド作成、アイコン・カーソルの設定、README作成。

やることが多かったですが、気づいたら全部終わっていました。


■ バトル画面に補正表示を追加した

何が変わったか

戦闘前の準備フェーズに、発生した補正をパネルの下部へ積み上げ表示する演出を追加しました。

表示される補正は以下の4種類です。

  • 地形防御補正(EFFECT DEF+XX% / DEF-XX%):プラスは緑、マイナスは赤
  • 支援攻撃ボーナス(SUPPORT ATK +):シアン
  • ジャミング制圧ボーナス(SUPPORT DEF +):シアン
  • 包囲成立(FLANKED ATK/DEF -50%):オレンジ

補正が発生しない場合は表示されません。詰めて表示します。

演出のこだわり

ただテキストを出すだけでは面白くないので、出現時に少し工夫しました。

白くフラッシュしながら大きいサイズで出現し、指定の色・通常サイズへ収縮する。
0.2秒程度の短い演出ですが、「補正が乗った」感が出ていい感じです。

InspectorでフラッシュのdurationとスケールのStart倍率をチューニングできるようにしてあります。

包囲表示の文言について

包囲成立の表示に「×½」という表記を使おうとしたのですが、
使用フォントで「×」「½」の両方を表示できず断念しました。

ASCII文字のみで構成した「FLANKED ATK/DEF -50%」に落ち着いています。
英語圏のプレイヤーにも伝わる表現なので、結果的にこちらの方が良かったかもしれません。

最初は雑にTextオブジェクトにとりあえず正しく動いてるか確認できるレベルで実装テストします。


最終的には以下のようになりました。

■ ターンチェンジ回復SEを追加した

回復エフェクト(緑の+N表示)は実装済みでしたが、音が鳴っていませんでした。

HealEffectRoutine()の冒頭にSE再生を1行追加するだけで完了です。
既存の爆発SEと同じパターンなので、影響範囲はUnitController.csのみ。シンプルな修正でした。


■ セーブデータのバージョン管理基盤を作った

なぜ今やるのか

開発中にセーブデータの構造は頻繁に変わります。
フィールドを追加したり、削除したり、型を変えたり。

そのたびにユーザーに「セーブデータを削除してください」と伝えるわけにはいきません。
DEMO版のうちに仕組みを入れておくべき、と判断しました。

設計の方針

基本思想は「読めたら移行、読めなければ削除して初期化」の2段構えです。

起動時
 └─ SaveDataMigrator.Migrate()
      ├─ バージョン確認
      ├─ 旧バージョン → 移行処理(フィールド補完)
      ├─ 破損 → 削除して初期化
      └─ ダウングレード → 削除して初期化

各JSONファイルに saveVersion フィールドを追加し、アプリ側に現行バージョン定数を持たせます。

public static class SaveDataVersion
{
    public const int SAVE_DATA   = 1;
    public const int SYSTEM_DATA = 1;
}

将来の運用

構造を変えるたびに SaveDataVersion を +1 し、MigrateSaveDataFrom() に移行処理を追記するだけです。

累積適用パターン(if (oldVersion <= N))で書いておけば、v0のデータが来てもv1→v2→v3と順番に全部適用されます。
離れたバージョン間の移行を個別に考える必要がありません。

ちなみに今回、JsonUtility はフィールドが増えても減ってもデフォルト値で黙って読んでくれることを改めて確認しました。
つまりフィールドの追加・削除だけなら「バージョンアップして上書き保存」するだけで十分です。
本当に困るのは型が変わった場合や、JSONとして物理的に壊れた場合だけです。


■ ビルド作成と各種設定

Company Name / Product Name を英数字に統一した

ビルドを作る前に、Player Settingsを整理しました。

日本語のCompany Name・Product Nameをそのまま使うと、
中国語環境のWindowsで文字化けや起動失敗のリスクがあります。

設定項目変更前変更後
Company Nameスタジオ白猫斎・くそげ工房StudioHakubyousai
Product Name鋼鉄の交響曲 -Symphony of Steel-SymphonyOfSteel

Company Nameを変えるとpersistentDataPath(セーブデータの保存先)も変わります。
DEMO版初回リリースのこのタイミングで変えておかないと、
正式版リリース後に変えた場合、既存ユーザーのセーブデータが消えます。
今変えておいて正解でした。

アイコンとカーソルを設定した

どちらもChatGPTで生成しました。

アイコンは512×512のピクセルアート風戦車画像。
ヘックスグリッドの背景に戦車のシルエット、という構成で、ゲームの雰囲気が伝わりやすいデザインになっています。

カーソルは64×64のシェブロン(階級章)モチーフの矢印。
ミリタリー感があってゲームに合っています。

カーソルはPlayer SettingsだけではなくコードでもCursor.SetCursor()を呼ぶ必要がありました。
Unityあるあるですね。

以下はアイコン画像です。

ビルドサイズについて

ビルドフォルダの解凍後サイズは約679MB。
思ったより大きいと感じましたが、中国語フォントが130MB超あることが判明しました。

これはFont Assetの文字セットを使用文字だけに絞れば大幅削減できます。
ただしDEMO版はレイアウトが完成しており今から変更するのは手間なので、正式版で対応する予定です。

ZIP圧縮後は約254MBまで減りました。予想より圧縮が効いて良かったです。

README.txtを作成した

日本語・英語・中国語の3言語を1ファイルに収録しました。

記載内容は以下の通りです。

  • ゲーム概要・動作環境・起動方法
  • 操作説明(マウスオンリー、左クリック決定・右クリックキャンセルが基本)
  • 注意事項・免責事項
  • クレジット(BGM:PeriTune様、SE:効果音ラボ様、フォント、AI開発支援)

AI開発支援については Claude・ChatGPT・Gemini の3つを記載しています。
今やAIなしでの個人開発は考えられないので、きちんとクレジットしておきたいと思いました。


■ 現在の残タスク(35日目時点)

カテゴリ項目状況
配布準備BOOTH商品ページ作成未対応←次回最優先
SteamKYC審査審査中(〜7営業日)
Steam30日待機進行中(〜5/17)
配布準備エンディング告知差し替え公開直前でOK
正式版中国語フォント最適化5/17以降

執筆後記

今日は「実装」と「リリース準備」を同時に走らせた一日でした。

バトル画面の補正表示は、ずっと「余力があれば」と先送りにしていた機能です。
やってみたら思ったより工数がかからず、演出もいい感じに仕上がりました。
先送りにしていた自分を少し反省しています。

セーブデータのバージョン管理は、地味ですがリリース前に必ず入れておくべき仕組みでした。
ユーザーに「フォルダのファイルを消してください」と伝える未来を回避できました。

ビルドも出来た。READMEも書いた。
次はBOOTH商品ページを作れば、DEMO版のリリースが現実になります。
もう少しです。

【個人ゲーム開発34日目】戦術SLG制作

「配布準備が、全部動き出した」日

34日目は、リリースに向けた実務を一気に片付けた一日でした。

BOOTHショップの公開。Steamworksへの開発者登録。
どちらも「やらないといけないのはわかってるけど後回しにしてた」作業です。

気づいたら両方終わっていました。


■ BOOTHショップ公開

ショップのコンセプトを整理した

今回のBOOTHショップは、鋼鉄の交響曲専用ではなく「スタジオ白猫斎のくそげ工房」として設計しています。

将来的に複数のゲームを出す想定のため、特定タイトルに依存しない構成にしました。
親ブランド「くそげ工房」・子ブランド「スタジオ白猫斎」という関係で、ヘッダー画像にも両方のロゴを配置しています。

ショップ名:白猫斎のくそげ工房 / Studio Hakubyousai (Atelier-KSG)
URL:https://atelier-ksg.booth.pm/

特定商取引法に基づく表記を整備した

無料配布でも、特定商取引法の表記は整備しておくべきと判断しました。

個人・無料配布のみという条件では義務対象外ですが、表記があることで閲覧者への信頼感が上がります。
また将来有料販売を始めた際の対応コストを下げる意味でも、今のうちに整えておく方が合理的です。

特に重要だと感じたのが免責事項です。

フリーウェアを配布する以上、
「このゲームを使って生じた損害には責任を負わない」
という旨を明記しておかないと、万が一のクレームへの対応が難しくなります。

今回の表記には以下を含めています。

・本ソフトウェアの使用により生じたいかなる損害についても開発者は責任を負わない
・動作を完全に保証するものではない
・ご自身の責任においてご使用ください

無料で配って責任を取らされる事態は避けたいので、ここは慎重に対応しました。


■ Steamworks開発者登録

思ったより手続きが多かった

Steamでゲームを販売するためには、Steamworksへの開発者登録が必要です。
登録自体は無料ですが、ゲームを1本登録するたびに$100(Steam Direct料金)の支払いが必要になります。

今回の手続きの流れは以下の通りです。

  1. Steamworksアカウント登録
  2. NDA(秘密保持契約)署名
  3. SDA(Steam配信契約)署名
  4. $100支払い
  5. 銀行口座情報入力
  6. 税金情報(W-8BEN)提出
  7. 本人確認書類(KYC)アップロード

一日でここまで終わらせるつもりはなかったのですが、一つ終わるたびに次のステップが見えてくるので、結果的に全部やりきりました。

税金情報でつまずきそうなポイント

海外販売では米国の税務申告に対応したフォーム(W-8BEN)の提出が必要です。
日本在住の個人であれば、日米租税条約が適用されます。

マイナンバー(個人番号)を外国TINとして提供することで、源泉徴収税率0%が適用されました。

つまり、Steamの売上から米国税が引かれない状態になっています。
これは日本と米国が租税条約を結んでいるためで、日本在住の開発者には有利な条件です。

30日待機がスタートした

$100を支払った日から、ゲームをリリースできるようになるまで30日間の待機期間があります。
これはValveが取引相手の情報を確認するための期間です。

4月17日に支払いを完了したため、5月17日以降にストアページの公開(「近日登場」)が可能になります。
実際の販売開始はそこからさらに最低2週間後となるため、最短でも6月上旬の見込みです。

この待機期間中にストアページの作成・審査・「近日登場」ページの公開を進めることができるため、
実質的に準備を並行して進めることになります。

とりあえず$100払ったから後戻りはできないですね(笑)
絶対に何かは販売します。売れるかはわからないですが…。


■ 現在の残タスク(34日目時点)

カテゴリ項目状況
配布準備BOOTHショップ公開完了✅
配布準備Steamworks登録・$100支払い完了✅
配布準備KYC審査審査中(2〜7営業日)
配布準備BOOTH商品ページ作成未対応
Steam30日待機進行中(〜5/17)
Steamストアページ作成・素材準備未対応
判断待ちバトル画面補正表示(DEF+/ATK+等)余力次第

執筆後記

今日は「やらなきゃいけないけど面倒くさそう」な作業を全部片付けた日でした。

BOOTHショップは思ったよりシンプルに整えられました。
Steamworksは思ったより手順が多かったです。

ただ、どちらも「やり始めれば終わる」作業でした。
後回しにしている間の精神的負荷の方が、実際の作業コストより高かったかもしれません。

次の作業はBOOTH商品ページの作成です。
ビルドを作り、READMEを書き、説明文を用意する。
ここまで来たら、あとは手を動かすだけです。

【個人ゲーム開発33日目】戦術SLG制作

「DEMO版の中身が揃った」日

33日目は、積み残していたコンテンツ制作を一気に片付けた一日でした。

ステージストーリーテキスト、ブリーフィングイメージアート、AIバグ修正。
それぞれ個別には小さな作業に見えますが、これで「DEMO版として出せる中身」が揃いました。
残るは配布準備だけです。


■ ステージストーリーテキスト:全4ステージ完了

攻略ヒントを命令口調に溶け込ませる、という方針を継続

前回、ステージ1「初級演習」のテキストが完成していました。
33日目では残る3ステージ分を一気に作成し、全4ステージが完了しました。

各ステージのテーマは以下の通りです。

ステージタイトルテーマ
1初級演習包囲戦術・数的優勢・深追い禁止
2中級演習二方向対応・有利地形確保・防衛布陣
3上級演習三正面対応・自走砲活用・戦力1.5倍の不利
4卒業試験戦力2倍・指導教官車両ギミック・占領勝利

難易度が上がるにつれて、テキストの締めくくりも変化させています。

  • ステージ1:「速やかに敵を掃討せよ」(基礎の確認)
  • ステージ2:「それが今回の演習で問われる判断力だ」(応用)
  • ステージ3:「判断の質だ」(戦略的思考)
  • ステージ4:「卒業してみせろ」(総仕上げ)

単なる状況説明ではなく、指揮官としての成長を示す流れになっています。
日本語・英語・中国語の3言語で作成しています。


■ ブリーフィングイメージアート:全4枚確定

ChatGPTを使ったピクセルアート生成

ブリーフィング画面に表示するイメージアートを、ChatGPTで生成しました。

方針として「ゲーム本体のドット絵と世界観を合わせる」ことを優先し、
ピクセルアート調・俯瞰視点・くすんだ色調で統一しています。

ステージ構図・テーマ
1将校3人が地図テーブルを囲む・草原(新米指揮官の初演習)
2荒野・敵が分散して二方向から迫るイメージ
3制作済み素材を採用
4森林・圧倒的な敵戦力との対峙

試行錯誤のポイントとして、画像参照よりもテキストプロンプトで
スタイルを言語化する方が安定した結果になりました。
また矢印やUIっぽい要素が混入しやすいため、
「no arrows, no UI elements」の明示が必須でした。

DEMO版のクオリティとして十分と判断し、全4枚を確定としました。


■ 敵AIバグ修正:StationaryとDefensive

Stationary:射程内でも攻撃しない問題

待機型AI(Stationary)が、攻撃範囲内にプレイヤーユニットがいるにもかかわらず攻撃しない場合がある、というバグを修正しました。

原因はターゲット選択のスコア計算にありました。
ダメージ期待値が低いユニットに対してスコアが不安定になるケースがあり、結果として攻撃対象が選ばれないまま行動終了していました。

特に防御力の高い超重戦車に対して顕著で、経験値が上がって攻撃力が増すと攻撃し始めるという、意図しない挙動になっていました。

修正方針として、Stationaryは「射程内の最初のターゲットを即採用」する専用ロジックに変更しました。
「動かない砲台は射程内なら必ず撃つ」という直感的な挙動になっています。

影響範囲はTurnManager.csのEnemyRoutine内のみです。

Defensive:移動後射程での攻撃判定漏れ

防御型AI(Defensive)が、移動すれば攻撃可能な範囲にプレイヤーユニットが入っても攻撃してこない問題を修正しました。

判定が「現在地からの攻撃射程」のみで、「移動後に攻撃可能か」を見ていなかったことが原因です。

修正後は意図した挙動で動作することを確認しています。


■ X運用続報:フォロワー整理の結果

前回の推論を実行に移した

前回の記事で「無反応フォロワーの増加が初動インプレッションを下げる」という推論を書きました。

4月15日、急増したフォロワーの約10%を整理しました。
整理の基準は「フォロワー数の増加・インプレッション・収益化のみを目的とした発信しかしていないアカウント」です。

結果:インプレッションが明確に改善した

4月15日・16日のインプレッションが、直前の数日と比較して明確に改善しました。

グラフを見ると、4月9日の#ブルバ100実施後にフォロワーが急増し、数日後にインプレッションが落ち込む流れがはっきり確認できます。
フォロワー整理後の4月15〜16日は、この落ち込みから回復しています。

考察

今回の結果から言えることを整理します。

フォロワー整理はマイナスを減らす作業

フォロワー整理によってインプレッションが回復したのは、自分の投稿に関心を持つアクティブフォロワーの割合が増えたためと考えています。
Xは投稿直後の初期反応でリーチを決める構造のため、無反応フォロワーの割合が高いほど投稿が広がりにくくなります。

ただし、これはあくまで「マイナスを減らした」に過ぎません。
フォロワーを整理しても、反応してくれる層が増えるわけではないからです。

ブルバ100が悪いわけではない

念のために書いておくと、#ブルバ100という手法自体が良い・悪いという話ではありません。

フォロワー増加・インプレッション拡大・収益化を目的とした発信であれば、ブルバで集まる層とコンテンツのテーマが一致するため、非常に強い拡散力を持つ手法です。

私の場合、個人ゲーム開発が主なテーマのため、増えたフォロワーとのニーズにミスマッチが生じました。
それが今回の結果の原因です。

本質は地道な積み上げ

結論として、インプレッションを安定させるには「自分のコンテンツに関心を持つフォロワーを地道に増やす」以外に近道はないという考えに至っています。

数を追うのではなく、反応する層を丁寧に作っていく。
宣伝フェーズに向けて、この方針で運用を続けます。


■ 現在の残タスク(33日目時点)

カテゴリ項目状況
コンテンツステージストーリーテキスト(4ステージ)完了
コンテンツステージイメージアート(4枚)完了
コンテンツエンディングスクロールテキスト実質完了(告知部分のみ差し替え待ち)
配布準備BOOTHヘッダー画像未対応
配布準備特定商取引法に基づく表示未対応(公開前必須)

執筆後記

DEMO版の中身が揃いました。
33日間かけて積み上げてきたものが、ゲームとして形になっています。

残るは配布準備だけです。
BOOTHヘッダー画像と特定商取引法の表示を片付ければ、4月下旬のリリースが現実的な射程に入ってきました。

X運用の話は、ゲーム開発とは少し離れたテーマですが、宣伝フェーズで同じ失敗をしないための記録として残しています。
個人開発者がSNSで発信する場合、数より質という話は理屈ではわかっていても、実際にデータで確認すると改めて実感します。

リリースに向けて、最後の準備を進めます。

【個人ゲーム開発32日目】戦術SLG制作

「ゲームを組み上げる」作業に入った日

32日目は、目に見える成果物が少ない一日でした。

マップを組んで、ユニットを配置して、テストプレイをして、「なんか違う」と感じて直す。
その繰り返しです。
コードもアセットも増えていないのに、時間だけが溶けていく感覚があります。

ただ、これは「進んでいない」のではありません。
ゲームとしての面白さを直接作っている作業です。
素材を揃えてきた31日間の答え合わせが、ここから始まっています。


■ ステージデータ作成:マップ・ユニット配置 4本完了

まず「箱」を全部作った

DEMO版4ステージ分のマップデザインとユニット配置が完了しました。

項目進捗
マップデザイン4/4 完了
ユニット配置4/4 完了
ストーリーテキスト1/4(ステージ1完了)
イメージアート方向性検討中

マップとユニット配置が終わったことで、各ステージの「骨格」は揃いました。
ここからストーリーテキストとイメージアートを乗せていく作業になります。

地形チップで道路ができたので早速ステージ1に配置。他に防壁や都市なども配置してステージ1のDEMO版マップが完成しました。


■ ステージ1「初級演習」ストーリーテキスト確定

攻略ヒントを命令口調に溶け込ませる

ブリーフィング画面に表示するストーリーテキストの方針として、
単なる世界観の説明ではなく「攻略に繋がるヒントを命令口調で伝える」という形を取っています。

ステージ1で盛り込んだ要素は次の通りです。

  • 包囲戦術のレクチャー(複数方向から囲む)
  • 数的優勢・分散禁止の指針
  • 道路沿い進軍への対処(有利地形への布陣)
  • 深追い禁止(逆撃リスクの示唆)
  • 評価基準の示唆(犠牲最小・速やかな掃討)

確定テキストは以下の通りです。


新米指揮官に告ぐ。これより初級軍事演習を開始する。
 現状の戦力分析では我が軍が優勢だ。しかし敵の一部はすでに自陣深くまで浸透している。複数方向から包囲して各個撃破せよ。孤立した敵を囲み、確実に仕留めろ。
 撃破後は速やかに前線を構築せよ。敵は道路沿いに進軍してくる――周囲の地形を把握し、有利な地形に布陣せよ。部隊は分散させず、常にこちらが数的優勢となるよう展開して迎え撃て。単身での深追いは禁物だ。敵に逆撃の好機を与えることになる。
 貴官の采配で犠牲を最小限に抑え、速やかに敵を掃討せよ。


日本語・英語・中国語の3言語版を作成・確定しました。


■ X(Twitter)運用:フォロワーの質とアルゴリズムを整理した

「フォロワーが増えたのにインプレッションが落ちた」を解剖する

ブルーバッヂ取得後、フォロワーが急増しました。
しかしそれに比例して、インプレッションが伸びているわけではありません。
むしろ投稿の初動が以前より鈍くなった感覚があります。

宣伝フェーズに備えて、3種の生成AIを使ってこの現象の原因を整理しました。

※以下はAI複数ツールを使って整理した考察です。正確性は保証できませんが、自分なりに納得感のある仮説として記録しておきます。

Xのアルゴリズムの仕組み

Xは投稿直後、まずフォロワーとその周辺層に表示します。
ここでの反応(いいね・滞在時間など)が良ければ拡散され、悪ければそこで止まります。

つまり、フォロワーが反応しなければ「面白くない投稿」と判定される仕組みです。
フォロワーの数より、フォロワーの質(反応するかどうか)の方が重要です。

ブルバ100で「一時的に爆発する」仕組み

「#ブルバ100」などのタグを使ったフォロワー増加は、状況によって効果がまったく異なります。

ブルバ系タグで集まるユーザーは、フォロワーを増やしたい・インプレッションを伸ばしたいという共通の目的を持っています。
そのため、フォローし合い・いいねし合い・リポストし合うという行動が自然に発生します。
結果として、短期間で相互に評価を押し上げる相乗効果が生まれます。
これが「ブルバで伸びた」と感じる正体です。

なぜその後に失速するのか

問題はここからです。

ブルバで増えたフォロワーは、基本的にあなたのコンテンツに興味があってフォローしているわけではありません。
ゲーム開発アカウントであっても、増えるのはゲーム開発に興味のない層です。

その結果、投稿がタイムラインに流れても反応しない・滞在時間が短い・いいねが発生しない、という状態になります。
投稿直後の初期評価が下がり、拡散されないまま終わります。

よくある誤解として「フォロワーが増えればインプレッションも増えるはず」というものがあります。
しかし実際は、反応するフォロワーが増えない限り意味がありません。
無反応フォロワーが増えることで、フォロワー増加がむしろマイナスに働くケースすらあります。

ブルバが「効く」ケースとの違い

ブルバでも効果が出るケースは存在します。

それは、投稿内容自体がブルバ層に最適化されている場合です。
フォロワーを増やすノウハウ・インプレッションの話題・収益化情報といった、ブルバ参加者が興味を持つ内容を投稿している場合は、フォロワー増加・投稿内容・反応する層が一致するため、非常に強い拡散力を持ちます。

ゲーム開発アカウントとして、インディーゲーム開発クラスタ以外の層を増やしても効果が薄いのはこの構造が原因です。

整理した対策

フォロワーを整理する場合は「ブロ解(ブロック→解除)」が基本です。
フォロー解除では相手のフォロー関係は変わらず、ブロック維持は完全遮断になるため、フォロー関係をリセットしたいだけならブロ解が適切です。
一気にやらず、1日10〜30人程度を目安に、投稿と並行して行います。

ただし、フォロワー整理はあくまで「マイナスを減らす作業」です。
本質的に重要なのは、反応してくれる層を作ることです。

具体的には、投稿を完成品・制作途中・比較(before→after)の3パターンで出し、反応率(いいね÷インプレッション)を見ながら刺さるコンテンツを特定する方法が有効です。
反応が良い投稿に反応しない層を少しずつ整理していく、という進め方になります。


■ 現在の残タスク(32日目時点)

カテゴリ項目状況
コンテンツステージストーリーテキスト(4ステージ)1/4
コンテンツステージイメージアート(4枚)方向性検討中
コンテンツエンディングスクロールテキスト未対応
配布準備BOOTHヘッダー画像未対応
配布準備特定商取引法に基づく表示未対応(公開前必須)

執筆後記

マップとユニット配置が4本揃ったのは、地味に大きな節目です。
「ゲームが4本ある」状態になったわけで、あとは中身を整えるだけです。

X運用の整理は、ゲーム開発とは少し離れた話ですが、
宣伝フェーズで失敗しないための準備として必要な作業だと思っています。
ブルバで数を増やしても、コンテンツと層が一致していなければ逆効果になる。
この構造を理解しているかどうかで、宣伝フェーズの効率がかなり変わってくると思います。

ストーリーテキストとイメージアートの制作を進めます。
ゲームの顔を作る作業です。

【個人ゲーム開発31日目】戦術SLG制作

「素材が終わった日」と「コードを直した日」

31日目は、素材制作とプログラム改修が混在した一日になりました。

地形チップの最後の1種を仕上げながら、並行していくつかの機能改善とバグ修正を進めました。
量でいえば多くはありません。
ただ、地形チップが全種完了したことで、ステージデータ設定に着手できる状態になりました。
残タスクの性質が「素材を作る」から「ゲームを組み上げる」へ、確実に移っています。


■ 地形チップ 14/14 完了

道路チップで手こずったが、完走した

31日目の最後の素材作業は道路チップです。

道路は直線・斜め・カーブと形状のバリエーションがあり、
さらに背景となる地形(草地・荒れ地・泥地・砂漠)との組み合わせで枚数が一気に増えます。
T字路・十字路まで対応しようとすると、それだけで30枚超になる計算です。

DEMO版では割り切りました。
直線・斜め・カーブのみ対応し、T字路・十字路はDEMO対象外とします。
「ゲームに必要な分だけ揃える」という判断は、この開発を通じて何度も繰り返してきた判断です。

これにより、地形チップ14/14が完了しました。
ステージデータ設定のブロッカーがなくなりました。

道路はとにかくパターンが多くて(笑)


■ サイズ回避補正の数値調整

「計算通りに展開できない」を直す

本作の戦闘計算には、ユニットサイズによる回避補正があります。
小型ユニットほど被弾しにくく、大型ユニットほど当たりやすいという設計です。

以前実装した数値では、サイズ2〜3(中型ユニット)の回避率が過剰で、
乱数による撃ち漏らしが頻発していました。
「戦力差があるはずなのに思った通りに削れない」という展開が続き、調整することにしました。

変更後の補正値は以下の通りです。

ユニットサイズ命中率補正
5(最大)補正なし
4-2%
3-5%
2-10%
1(最小)-20%

サイズ1は「小さくて当てにくい」感覚を残したいため、-20%のままにしています。
サイズ3〜4は「ほぼ当たる」レベルに寄せました。
テストプレイの感触はかなり改善されています。


■ ターン開始時の回復演出

大戦略系の定番演出を実装した

ターン開始時に回復地形(拠点・都市など)の上にいるユニットがHPを回復する処理は
以前から実装済みでした。
今回はそこに演出を追加しました。

実装した内容は次の通りです。

  • 回復が発生するユニットへ、1体ずつカメラがフォーカスする
  • ユニットの頭上に緑の「+N」テキストが上昇・フェードアウトする
  • HP満タンのユニットは演出・カメラフォーカスともスキップする
  • 表示される回復量は実際の回復量(MAX超えなし)に合わせる
  • プレイヤーターン・敵ターンどちらも演出あり

「回復が起きていることが一目でわかる」という大戦略・ファミコンウォーズ系の定番演出です。
カメラが順番に飛んでいくことで、ターン開始のリズムが生まれます。

また、地形情報パネル(画面下部)にも回復情報を追加しました。

DEF: +20%
HEAL: +2~3

回復量の定義はTileDataに一元管理しています。
表示と実計算で同じ値を参照する設計にしたため、
数値を変更したい場合はTileData側の1箇所を直すだけで済みます。


■ バグ修正 4件

ユニットの白点滅が残り続ける問題を根本から直した

今日修正したバグのうち、最も影響範囲が大きかったのはユニットの白点滅残留です。

本作では、選択中のユニットや敵ユニットホバー時に白点滅(フラッシュ)エフェクトが出ます。
ターン終了時やウィンドウ操作後にこの点滅が消えず、敵ターン中も白く光り続けるという
見た目上の不具合が複数のパターンで発生していました。

修正した内容は4件です。

① ターン終了時に移動範囲ハイライトが残る
ターン終了ボタンを押した際に選択状態の解除処理が走っていなかった問題。
ターン終了処理の冒頭で強制解除メソッドを呼ぶように修正しました。

② 敵ホバー・自軍選択の点滅が敵ターン中も残る
強制解除メソッドが選択ユニットの点滅しか止めておらず、
敵ホバー中のユニットの点滅が残り続けていた問題。
強制解除時に全敵ユニットの点滅も一括停止するよう修正しました。

③ 敵詳細ウィンドウを閉じた後に点滅が残る
詳細ウィンドウが開いている間はカーソル処理が止まるため、
ウィンドウを閉じた後に古いホバー状態の点滅が残る問題。
ウィンドウを閉じる処理にホバー状態のリセットを追加しました。

④ 複数の隣接敵ユニットを順にホバーすると全員点滅し続ける
ホバーが素早く切り替わった際に、途中で通過したユニットの点滅停止処理が
呼ばれないケースがあった問題。
ホバー切り替え時に全敵ユニットの点滅を一括停止してからリセットする方式に変更しました。

原因はいずれも「点滅開始の管理は各所でやっているが、停止の管理が漏れやすい構造」でした。
根本対処として、全敵ユニットを一括停止するメソッドを用意して、
解除が必要な場面で確実に呼ぶ設計にしています。


■ 現在の残タスク(31日目時点)

カテゴリ項目状況
コンテンツステージデータ設定(4ステージ)0/4・着手可能になった
コンテンツエンディングスクロールテキスト未対応
配布準備BOOTHヘッダー画像未対応
配布準備特定商取引法に基づく表示未対応(公開前に必須)

素材作業は全完了です。
次の主戦場はステージデータ設定4本です。


執筆後記

地形チップが終わった瞬間、正直ほっとしました。
道路は「最後にこれが来るか」という作業量でしたが、
T字路・十字路を切る判断ができたのは、以前の自分より少し賢くなった気がします。

バグ修正4件は、「なぜ消えないのか」の原因を順番に掘っていく作業でした。
ユニットの白点滅が残り続ける問題は、再現条件がいくつかあって、
1件直したと思ったら別のパターンで再現して、という繰り返しでした。
最終的に「全敵ユニットを一括停止する」という単純な解決策に落ち着いたのが、
やや拍子抜けでもあり、プログラムらしい結末でもあります。

ステージデータ設定に入ります。
ここからはゲームとしての「面白さ」を作る作業です。
素材を揃え

【個人ゲーム開発30日目】戦術SLG制作

この2日間は「素材を終わらせる」と決めた日々だった

29日目・30日目は、2日間まとめての記録になります。

この2日間のテーマは一言で言えば「素材の完走」です。

ユニットマップ画像・戦闘用スプライト・戦闘背景。
プログラムの実装は既に完了していて、あとは素材さえ揃えばDEMO版が出せる状態でした。
「ここを乗り越えれば見える」という感覚のまま、ひたすら画像作業を進めた2日間です。

結果的に、主要な素材がほぼ出揃いました。
いよいよDEMOリリースが、現実的な射程圏内に入ってきました。


■ ユニットマップ画像 全25種完了

ついに全車種が本素材に

前回(28日目)の時点で25種中14種が完了していたユニットマップ画像。
駆逐戦車・自走砲・野砲系が残っていました。

砲身系のユニットはピクセル変換で白飛びしやすく、手修正が多い車種です。
特に野砲は車輪・砲架・砲身と直線パーツが多いため、
Clip Studio Paintでの手引き直し作業が他の車種より多めになりました。

それでも1種1種、削れすぎたドットを復帰させ、はみ出しを削り、白飛びを直していくと
最終的に全25種が出揃いました。

加工フローは前回と同じです。

  1. AI生成元絵を2×2に拡大
  2. 濃い色バイアス強めで4ドット中最多色を採用(ドット感を強調)
  3. Clip Studio Paintで手修正
  4. 縦方向に引き延ばしてデフォルメ(マップ上での視認性向上)

「並べたときに一目で区別できる」ことを最優先にしたデフォルメは変わっていません。
野砲と自走砲が横並びになったときに、ちゃんと別の兵器に見える。それだけを意識しました。


■ 戦闘用スプライト 全25種アングル見直し完了

基準アングルを決めて全種を統一

戦闘画面で左右に並ぶ戦闘用スプライト(各ユニット左向き・右向きの2枚セット)。
こちらも25種すべてのアングル見直しが完了しました。

今回、基準となるアングルとして採用したのは UnitBattle_010(IV号戦車)です。
真横に近い弱俯瞰・サイドビューのアングルで、
砲身が水平に伸びて見え、車体側面のシルエットがはっきり出る構図です。

戦闘画面は左右対称に並べる構図なので、
側面シルエットの明確さが「映え」の決め手になります。
俯瞰が強くなるほど車体上面が見えすぎて、シルエットが潰れる傾向があります。

全25種をこの基準に合わせて見直した結果、
一部のユニット(自走砲・駆逐戦車系)で俯瞰角度のわずかなばらつきが残りました。
微妙な角度調整は相当難航したため、DEMO版では妥協する判断をしました。
正式版でのリテイク候補として記録しておきます。

また四号戦車H型(PZ-IV-K)については、
マップアイコン(UnitMap_010)との整合性を重視し、
俯瞰やや強めのアングルを採用しました。
マップ画像の上面図に近いシルエットと揃えることで、
同じ車両だと認識しやすくなります。


■ 戦闘背景 DEMO版完了

「全種別に用意する」から「使い回し前提で絞る」へ

当初、戦闘背景は地形種別ごとに全種類用意する想定でした。
しかし現実的に考えると、DEMOの4ステージに登場しない地形(雪原・水域・砂浜など)まで
対応するのは時間的にも効率的でもありません。

方針を切り替えました。

  • DEMOで使用する地形に絞る
  • ある程度の地形は共通背景で使い回す
  • 雪原・水域・砂浜等はDEMO対象外として未対応

結果、9種を新規制作・1種を既存と統合し、DEMO版の戦闘背景が完了しました。
残り2種はDEMO対象外の地形のため、正式版対応に先送りします。

「完璧を目指してリリースが遠のく」より「割り切ってDEMOを出す」。
個人開発における実用主義的な判断です。


■ X(旧Twitter)への初投稿

ネクタリスへのリスペクトを前面に出して発信

開発開始から30日目、ついにX(旧Twitter)への初投稿を実施しました。

本作「鋼鉄の交響曲」はNectaris(Military Madness)へのオマージュ作品です。
「あのゲームへの愛から作った」ということを、正直に、堂々と発信することにしました。

投稿文はこちらです。


⚙️ Day 28 of solo dev — Military Madness never left my head.
So I built my own tribute.

“Symphony of Steel” — hex strategy, turn-based tactics.
Title to mission complete, full playthrough in the video.

Free DEMO — April 2026
Steam release — 2026

スーパーゲ制デー


動画はタイトル画面からステージクリアまでの通しプレイ映像です。
実際のゲームプレイの流れをそのまま見せるのが、一番誠実なアピールだと思っています。

投稿に際して2026年現在のXのアルゴリズム事情も調べました。

  • タグは1個まで(複数タグは大幅なリーチ減)
  • 外部リンクは本文に入れない(無料アカウントはほぼゼロエンゲージメント)
  • 動画はXにネイティブアップロード(YouTubeリンクはNG)

フォロワー実数は現在90〜100人規模なので、初期インプレッションは限定的です。
ただ「種まき期間」として割り切り、継続的に発信していくつもりです。


■ 地形チップ 対応範囲を確定

DEMOに必要な14種に絞って進行中

地形チップについても方針を確定しました。
DEMOで登場する地形に絞り、14種を対応予定とします。
現在5/14が完了しています。

茂み・林・森林の3種については、遠目での視認性・シルエットの差別化を確認しました。
林と森林はズームアウト時にやや近く見えますが、
下部パネルに地形名が表示されるため、ゲーム上は問題ないと判断しています。


■ 現在の残タスク(30日目時点)

カテゴリ項目状況
素材地形チップ5/14完了、残9種
コンテンツステージデータ設定(4ステージ)0/4・地形チップ後に着手
コンテンツエンディングスクロールテキスト未対応
配布準備BOOTHヘッダー画像未対応
配布準備特定商取引法に基づく表示未対応(公開前に必須)

プログラム実装は全完了。主要素材もほぼ完了。
残件はコンテンツ設定と配布準備に集約されてきました。


執筆後記

2日間、ひたすら画像作業でした。
コードを書くわけでも、設計を考えるわけでもなく、
ドットを直して、アングルを確認して、背景を描いて。
地味と言えば地味ですが、こういう作業の積み重ねがゲームになっていく感覚があります。

戦闘背景を「絞って使い回す」と決めたのは、
自分の中でちょっとした転換点でした。
「全種揃えなきゃ」という完璧主義から、「DEMOに必要なものを出す」という現実主義へ。
個人開発は、この切り替えができるかどうかがリリースできるかどうかに直結すると思っています。

X投稿は正直、緊張しました。
「Military Madness never left my head. So I built my own.」
この一文に、作り始めた理由が全部詰まっている気がします。
反応がどうであれ、作ってきたものへの誇りは変わりません。

地形チップ残9種。ステージデータ設定4ステージ。
ゴールは見えています。

【個人ゲーム開発28日目】戦術SLG制作

今日は「見やすさ・わかりやすさ」を追求する日

今日は実装面とグラフィック面、両方を進めた日になりました。

実装は主にUI操作性の向上です。
「今何が起きているのか」がプレイヤーに伝わるかどうか。
それを意識しながら、下部パネルの動作・カーソル追従・ユニットの視認性を整えていきました。

後半は素材作業に移り、ユニットのマップ画像を本格的にドット絵化する作業を進めました。
気づいたら25種中14種まで完了していました。


■ 下部パネル・グリッドカーソルの動作仕様を確定

「最後に表示した情報が張り付く」問題を解消した

これまで下部の情報パネルは、状況が変わっても最後に表示した情報がそのまま残る仕様でした。
戦闘中に敵ユニットの情報が表示されたままになったり、
敵ターンが終わっても敵の情報が残り続けたりと、情報の鮮度が保てていませんでした。

今回、以下の仕様として確定・実装しました。

状態下部パネルグリッドカーソル
カーソル移動中地形・ユニット情報を表示プレイヤー操作
戦闘中(プレイヤー攻撃)情報をクリア現位置固定
敵ターン・移動中行動中の敵ユニット情報を表示敵ユニットに追従
敵ターン・攻撃中情報をクリア敵ユニット位置固定
戦闘終了後カーソル位置の情報に戻す元の挙動に戻す

実装上はシンプルで、戦闘開始時にClearInfoAll()を呼び、
終了後にOnCursorMove()でカーソル位置の情報を再取得するだけです。
プレイヤーターン側はCursorManager.cs、敵ターン側はTurnManager.csEnemyRoutine()内でそれぞれ対応しています。


■ 敵ターン中のカーソル・カメラ追従

「敵がどこに移動したか見えない」問題を解消した

これまで敵ターン中、グリッドカーソルはプレイヤーが最後に置いた位置に固定されたままでした。
敵ユニットにカメラが追従しても、カーソルだけが別の場所に残るため、
ズームインしているときに「敵がどこに消えたのか」わからなくなることがありました。

今回の対応は2点です。

① 行動開始時にカーソルを敵ユニット位置へ移動

FocusCameraOn()でカメラを追従させた直後に、
CursorManager.ForceMoveCursorTo()でカーソルも同じ座標へ飛ばします。
これでカーソルと情報パネルが常に行動中の敵ユニットを指すようになりました。

② 移動完了時にカメラを移動先へ再フォーカス

移動アニメーション中のリアルタイム追従は対応コストが高いため、
移動完了(while (e.State == UnitState.Moving) yield return null;の直後)に
もう一度FocusCameraOn()を呼ぶ方式にしました。

移動アニメーション中は見えなくても、完了時点で正しい場所にカメラが飛ぶことで
プレイヤーの混乱を防ぐことができます。ズームインしているときの体験が大幅に改善しました。


■ ユニット選択時の視認性向上

「自分が何を選んでいるか」が一目でわかるようになった

移動範囲ハイライトが選択ユニット自身のマスに重なるため、
「どのユニットを選んでいるか」が視覚的にわかりにくい問題がありました。

2点の改善を行いました。

① 選択ユニット自身のマスをハイライト除外

reachableからShowMoveRange()に渡す際、
moveHighlightというコピーを作成し、そこからユニット自身の座標をRemove()して渡します。
reachable自体は経路探索・攻撃範囲計算に使うため、元のSetは変更しません。
味方選択時・敵ホバー時の両方に適用しています。

② 点滅フラッシュ演出

選択中・ホバー中のユニットが元の色と指定色の間でグラデーション点滅するようになりました。

UnitControllerStartFlash()StopFlash()を追加し、
コルーチンでMathf.Sin()を使ったなめらかな色補間を実装しています。

private IEnumerator FlashRoutine()
{
    Color origin = (State == UnitState.ActionWait) ? actionWaitColor :
                   (State == UnitState.Done) ? doneColorMultiplier : baseColor;
    while (true)
    {
        float t = (Mathf.Sin(Time.time * flashSpeed * Mathf.PI) + 1f) * 0.5f;
        if (spriteRenderer != null)
            spriteRenderer.color = Color.Lerp(origin, flashColor, t);
        yield return null;
    }
}

flashColorflashSpeedはInspectorで調整可能です。
flashSpeedの数値が小さいとゆっくり、大きいとチカチカした点滅になります。

既存のUpdateUnitAppearance()spriteRenderer.colorを上書きする設計だったため、
_isFlashingフラグを追加してフラッシュ中は色の上書きをスキップする処理も加えています。

実装後の画面です。選択・ホバー対象のユニットが光っているので一目でわかります。


■ ユニットマップ画像の本素材化(14/25種完了)

AIで用意した仮素材をドット絵風に全面改修

これまでのユニットマップ画像はAI画像生成で用意した仮素材でした。
描き込みの細かさや粒度にばらつきがあり、ゲーム画面上での統一感に欠けていたので、
全25種を本格的にドット絵スタイルへ改修する作業を開始しました。

加工フロー

  1. AI生成元絵を2×2に拡大
  2. 濃い色バイアスを強めにして4ドット中の最多色を採用(ドット感を強調)
  3. Clip Studio Paintで手修正(削れすぎたドットの復帰・はみ出し削除・白飛び修正)
  4. 縦方向に引き延ばしてデフォルメ(マップ上の視認性向上)

戦車・砲身系は直線部分がピクセル変換で白飛びしやすく、手修正が多めになりましたが、
ティガーⅠとティガーⅡはフォルムの差をしっかりつけることができました。
「並べた時に一目で区別できる」ことを優先したデフォルメを意識しています。

本日は25種中14種が完了。残り11種は駆逐戦車・自走砲・野砲系です。
少しズングリしたフォルムになってドット感強めに調整しました。


■ シーン完成状況

シーン状況
タイトル✅ 完成
ブリーフィング✅ 完成
戦術(メインゲームプレイ)🔧 素材対応継続中
結果✅ 完成
エンディング✅ ほぼ完成

執筆後記
今日は「実装のための実装」ではなく、「プレイヤーが感じる体験」を起点にした改善が多かったです。
下部パネルの情報張り付き、カーソルが迷子になる問題、選択ユニットの見づらさ。
どれも「動いてはいるけど、なんかおかしい」という感覚から始まった改善です。

特にズームイン時に敵の移動先が見えなくなる問題は、自分がテストプレイして地味にストレスを感じていた箇所でした。移動完了時にカメラを飛ばすだけで体験がここまで変わるというのは、改めて「カメラ演出の重要性」を実感しました。

素材作業はひたすら地道です。戦車の砲身が白飛びするたびに手で引き直す作業を繰り返しています。
でもティガーⅠとⅡが並んだ時に「あ、ちゃんと違う車両に見える」となった瞬間は素直に嬉しかったです。
残り11種、明日には完走したいところです。

【個人ゲーム開発27日目】戦術SLG制作

今日は「戦闘の深み」を追求する日

今日は実装量が多かった。
ユニットの詳細表示拡充から始まり、戦闘バランス調整、そして経験値システムの設計・実装まで。
気づいたら夜になっていました。

「敵ユニットをクリックしたら詳細が見たい」「育てたユニットが強くなる実感が欲しい」
プレイヤーとして当然感じる欲求を、ひとつひとつ形にしていく日でした。


■ ユニット詳細表示の拡充

敵ユニットも、自ユニットも、クリックで詳細が見えるようになった

これまで詳細ウィンドウはユニットリストウィンドウ経由でしか開けませんでした。
マップ上のユニットを直接クリックして確認する手段がなかったのです。

本日、以下の2パターンを追加しました。

  • 敵ユニットを左クリック → 詳細ウィンドウを表示
  • 味方ユニット選択中(移動範囲表示中)に自ユニットを左クリック → 詳細ウィンドウを表示

閉じ方は閉じるボタンか右クリックです。

実装上の課題として、右クリックによる閉じる処理の競合がありました。
UnitDetailWindowManagerCursorManagerの両方が右クリックを監視していたため、
「ウィンドウを閉じた直後に未行動ユニットへのフォーカスが発火する」という現象が起きました。

解決策は右クリック処理の一本化です。
CursorManager.Update()の冒頭で詳細ウィンドウの開放を確認し、
開いていれば閉じてそのままreturnする構造にしました。
右クリックの監視は一箇所に限る、という昨日の教訓をまた活かすことになりました。


■ 戦闘バランス調整

射程と機体サイズが命中率に影響するようになった

テストプレイ中に「攻撃側支援あり・防御側包囲済みの圧倒的優勢なのに攻撃側の方が被害が大きい」という
理不尽な結果が出ることがありました。乱数の振れ幅が大きすぎた問題もありましたが、
今回は以下の2つの補正を追加しました。

射程距離による命中下方補正

  • 距離1〜3:補正なし
  • 距離4:-5%
  • 距離5:-10%
  • 距離6:-15%
  • 距離7:-20%
  • 距離8以上:-25%(下限)

長距離砲が万能にならないよう、距離に応じた命中ペナルティを設けました。
最初は10%刻みで実装しましたが、長距離ユニットが全然撃破できなくなったので5%刻みに調整しています。

ユニットサイズによる回避補正

  • サイズ5(最大):補正なし
  • サイズ4:相手命中率-5%
  • サイズ3:相手命中率-10%
  • サイズ2:相手命中率-15%
  • サイズ1(最小):相手命中率-20%

小型ユニットは当てにくい。シンプルですが戦術の幅が広がります。
歩兵や偵察車両の生存性が上がりました。


■ 経験値システムの実装

戦い続けたユニットが強くなる

今回最も大きな実装です。
ネクタリスオマージュとして戦術的深度を高めるため、経験値システムを設計・実装しました。

基本仕様

  • 経験値範囲:0〜20(ステージ開始時は全員0)
  • 攻撃力・防御力が経験値1につき5%向上(最大で基礎値の2倍)

取得ルール

  • 攻撃側:ダメージを与えたら1、撃破したら2
  • 防御側:攻撃されたら1(距離・ダメージ問わず確定)、反撃で撃破したら2

防御側は「攻撃されるだけで経験になる」設計です。
遠距離から一方的に撃たれ続けるユニットが経験値ゼロのままというのは理不尽なので、
攻撃された時点で1獲得するルールにしました。

設計上のポイント

経験値の計算はCalculateCombat()内で戦闘結果と同時に確定させています。
HPと同じく「戦闘前の値」と「戦闘後の値」をCombatResultに格納し、
実際の付与はApplyExp()で行う設計です。

これにより戦闘画面が開いている時点で「この戦闘後の経験値がいくつになるか」がわかっており、
演出タイミングを自由に制御できます。

表示箇所

経験値は勲章画像で表現しています。味方は青、敵は赤のバナーデザインで、
0〜20の21段階、敵味方合わせて42枚の画像を用意しました。
表示箇所は戦闘画面・詳細ウィンドウ・下部パネルの3箇所です。

画像の管理はExpSpriteDataというScriptableObjectに一元化しています。
3箇所で使うたびに42枚をアサインするのは苦行なので、1つのアセットを共有参照する形にしました。

経験値の画像です。星の数と大きさで段階を表現しています。
ここまで育てるには相当な激戦をくぐり抜ける必要があります。実際のプレイでそうそう見られる段階ではないですが、
育てたプレイヤーへのご褒美として用意しました。

以下のように戦闘画面では表示されます。


■ 戦闘画面の数値精度向上

経験値による能力向上が正確に反映されるようになった

経験値システムの実装に伴い、攻撃力・防御力の内部型をintからfloatに変更しました。

経験値1、基礎ATK30のユニットの攻撃力は30 × 1.05 = 31.5です。
これをintで持つと32に丸められ、HP10のユニットの戦闘画面表示は320になります。
正しくは315のはずです。

計算過程は全てfloatで保持し、表示時のみMathf.RoundToInt()で整数化する設計に統一しました。
地味な修正ですが、数値表示の精度はゲームの信頼感に直結します。


■ その他・UI整理

ConfirmDialog(確認ダイアログ)をSystemWindowCanvas配下から独立したCanvasに移動しました。
Sort Orderを50に設定し、どの画面が開いていても最前面に表示されるよう整理しています。
あわせて全CanvasのSort Orderを整理し、描画順序の競合を解消しました。


■ シーン完成状況

シーン状況
タイトル✅ 完成
ブリーフィング✅ 完成
戦術(メインゲームプレイ)🔧 実装中
結果✅ 完成
エンディング✅ ほぼ完成

執筆後記
今日は実装量が多かったです。特に経験値システムは設計から始めたので時間がかかりました。
「戦闘結果をCombatResultで一元管理する」という既存の設計思想を経験値にも適用できたのは良かったです。HPと同じパターンで実装できると、コードの一貫性が保てます。

苦労したのは戦闘演出のタイミング制御です。「経験値付与」「画面更新」「撃破演出」の順序が噛み合わず、戦闘画面が閉じた後に経験値が更新されたり、撃破演出と戦闘画面が重複したりと、しばらく格闘しました。
最終的にIsPlayingをfalseにするタイミングを調整し、Coroutineで適切に待機を挟むことで解決しています。

デモ版リリースまで残りタスクは着実に減っています。素材制作が本丸ですが、実装面はだいぶ形になってきました。

【個人ゲーム開発26日目】戦術SLG制作

今日は「操作していて気持ちいい」を追求する日

午前中は、美容院へ行ってきました。
そろそろヘアドネーションできるくらいに髪が伸びまくってます(笑)
色入れてポニテにして帰宅してからの作業となるので午後から開発再開。

今日は戦術シーンの操作性向上を中心に、UI改善・敵AI調整・バグ修正と、 地味だけど確実にゲームの完成度を上げるタスクを集中的に片付けました。

派手な新機能ではないですが、「これがないと遊びにくい」という部分です。 実際に触ってみると操作感が全然違う。こういう積み重ねがゲームの質を決めると思っています。


■ 敵AI行動順の改善

移動力が高いユニットが先に動くようになった

これまで敵ユニットの行動順は移動力の低い順(昇順)でした。 鈍重なユニットが先に動いてしまい、後から高機動ユニットが動こうとしても 道が塞がれている、という状況が発生していました。

本日、行動順を以下のルールに変更しました。

  1. 行動優先度(aiPriority)の高い順
  2. 移動力の高い順
  3. ステージデータのリスト順(SpawnIndex順)

これにより高機動ユニットが先に展開して道を空けてから、 鈍重なユニットが続く、という自然な動きになりました。

StageDataEnemySpawnInfoaiPriorityフィールドを追加したので、 ステージデザイン時に特定のユニットを優先的に動かす制御もできます。 デフォルト値は0で既存ステージへの影響はありません。

基本的に0にして特に先に動かしたいといった戦術的な意味が出た時に使用する予定。


■ ユニット表示順の統一

リスト順・巡回順・表示順がすべて一致するようになった

これまでユニットリストウィンドウの表示順はモデル番号順でした。 後述する右クリックフォーカス巡回を実装するにあたり、 「ステージデータのリスト順」と「ユニットリスト表示順」が一致していないと 直感的に使いにくいと判断して統一しました。

敵・味方ともに生成時にSpawnIndexを連番付与するようにして、 ユニットリストウィンドウの並び順もSpawnIndex順に変更しています。

結果として以下の3つが完全に一致するようになりました。

  • ステージデータ(Inspector)のリスト順
  • ユニットリストウィンドウの表示順
  • 右クリックフォーカスの巡回順

■ 右クリックで未行動ユニットへフォーカス

ユニットを探し回らなくてよくなった

ターン制SLGで地味にストレスなのが、「あれ、まだ動いてないユニットどこだっけ」です。 マップをスクロールして探すのは手間です。

本日、右クリックの短押しで未行動ユニットへ自動フォーカスする機能を実装しました。

仕様は以下の通りです。

  • 短押し判定:押下から0.2秒以内、かつマウス移動量5px以下
  • 初回:現在のカメラ位置に最も近い未行動ユニットへ
  • 2回目以降:SpawnIndex順に巡回(末尾まで行ったら先頭に戻る)
  • 左クリックするとインデックスがリセットされ、次の右クリックで近いユニットから再スタート

カメラ移動は瞬間移動にしています。 なめらかなスクロール移動は敵AIの行動確認には便利ですが、 自分でユニットを探す際はテンポが悪い。用途で使い分けています。

また画面内に十分収まっているユニットへのフォーカスはカメラを動かさず、 グリッドカーソルだけを飛ばす仕様にしました。 マップ表示エリアの10%マージン内に収まっていればカメラ移動なしです。


■ 右クリックでターン終了(確認ダイアログ)

全ユニット行動済みなら右クリックでターンを終える

右クリックフォーカスの自然な拡張として、 未行動ユニットがゼロになった状態で右クリックするとターン終了確認ダイアログが表示されるようにしました。

「巡回するユニットがなくなった=全員行動済み=ターン終了の意思」という流れが 右クリックだけで完結します。

あわせてターン終了ボタンも確認ダイアログを経由するように変更しました。 未行動ユニットの有無でメッセージが分岐します。

  • 未行動ユニットあり:「未行動のユニットがいます。ターンを終了しますか?」
  • 未行動ユニットなし:「ターンを終了しますか?」

テスト中に「うっかりターン終了ボタンを押してしまう」ことが何度かあったので、 この確認ステップは実用上かなり助かります。 3言語対応済みです。

とりあえず英語版です。


■ 敵ユニットホバーで移動・攻撃範囲表示

敵の脅威範囲が一目でわかるようになった

敵ユニットにマウスを0.3秒ホバーすると、移動範囲と攻撃範囲がハイライト表示される機能を実装しました。

表示内容はユニットの特性によって変わります。

  • 移動後攻撃可能なユニット(戦車・装甲車など):移動範囲(青)+移動範囲外の攻撃範囲(赤)
  • 移動後攻撃不可のユニット(野砲・自走砲・駆逐戦車など):現在地からの攻撃範囲(赤)+移動範囲(青)

野砲など射程の長いユニットの脅威範囲は広く、 「ここに入ると即攻撃される」という判断をプレイヤーが事前にできるようになりました。 特に高機動・長射程ユニットの把握が格段に楽になっています。

0.3秒の遅延を入れているのはカーソルを動かすたびに表示が切り替わる 「うるさい」状態を避けるためです。

これないと高機動ユニットや長距離砲の範囲がわかりにくいので慌てて実装という感じです。詰将棋的なマップをいずれ作る予定なのでちまちまマス目数えてらんないかなと。


■ ズームボタン・倍率表示のデザイン更新

長年の「芋ボタン」がついに卒業

ずっと仮置きのプレーンなボタンだったズームボタンと倍率表示をデザインしました。

「+」「-」ボタンはメタル感のある画像に差し替え、 倍率表示は7セグメント風のデジタルフォントスタイルに変更しています。 サイドパネルの世界観と統一感が出ました。


■ グリッドカーソル消失バグの修正

地味だけど気になっていた問題が解消

ランダム配置される特定の地形チップ上でグリッドカーソルが見えなくなる現象がありました。 条件が不定で再現性が低く、ずっと原因不明でした。

調査した結果、GridCursorObjectのレイヤー順序が0になっており、 特定のタイルチップの下に隠れてしまっていたことが原因でした。

レイヤー順序を0から4に変更して解消しています。 ユニット(1〜3)より前面、UIウィンドウ(4〜10)と同レベルに設定しました。


また動画を作成したのでここで公開しておきます。
前回からブリーフィングや結果画面など強化されているので是非ご覧ください。

■ シーン完成状況

シーン状況
タイトル✅ 完成
ブリーフィング✅ 完成
戦術(メインゲームプレイ)🔧 実装中
結果✅ 完成
エンディング✅ ほぼ完成

執筆後記
今日は地味な日でした。でも地味な改善が一番大事だと思っています。
特に右クリックフォーカス→巡回→ターン終了という一連の流れが繋がったのは大きいです。 キーボードに手を伸ばさず、右クリックだけでターン管理ができる。 操作の流れがスムーズになると、ゲームに集中できます。
実装中に「右クリック処理を複数のスクリプトで監視してはいけない」という教訓を得ました。 CameraControllerCursorManagerの両方が右クリックを監視していたせいで、 しばらくバグに苦しめられました。入力の一元管理は徹底します。
また本日Xの青バッジを取得しました。 今後は開発進捗の発信も積極的にやっていきます。 完成度が上がってきたので、プレイ動画などもそろそろ出せるかなと思っています。