
見ようとしているものしか見れない世界
LimiTを作ろうと思ったきっかけは、モノクロ写真だった。
写真にはレンズの視野角の中、影と光しか存在しない。しかし、影と光ですべてを表現できる。そういう世界なのだ。見える世界と見えない世界が明確に区別されている。
これがLimiTのグラフィックの根本的な思想だ。敵のデザインは基本的に黒と白、アクセントのエラーピンク。この3色のみに絞り、攻撃のエフェクトはエラーピンクのみで構成する。
モノクロの世界でのアクセントカラーというのは大きな力をもつ。視界が制限されている世界だと尚更。
見ようとしているものしか見れない世界では、敵が次の瞬間に何をしようとしているのかを知る方法が制限されているため、敵の一挙手一投足を瞬時に見ないといけない。
敵の動きをわかりやすく表現するためにはプレイヤーの視点を誘導しなくてはいけない。
そこで役に立つのがアクセントカラーの力だ。
攻撃のエフェクトにプレイヤーの視点が一気に向く。これが狙いだ。
「見ようとしているものしか見れない世界での視点誘導の方法」
このテーマがLimiTという作品を貫いた。
Godot Engine を選んだ理由
これまで Unity / C# でゲームを作ってきたが、LimiT では Godot Engine を選んだ。
きっかけは Unity の経営問題だった。2023年後半、Unity が突然ランタイムフィーの方針を発表して業界がざわついた。「特定エンジンに依存するリスク」を初めてリアルに感じた瞬間だった。ちょうど新しい作品に取りかかるタイミングだったので、この機会に別のエンジンを触ってみようと決めた。
Godot を選んだ理由は3つある。オープンソースで将来的なリスクが低いこと、2Dゲームに特化した機能が充実していること、そして GDScript が Python に近い書き心地で学習コストが低かったことである。
前作で迷子になった話
前作のProject-KAKUGE!!では、初めに世界観だけ軽く決めて企画段階を終え、あとはその場で仕様を書き換えて実装してしまった。
ゲームにおいて重要な「プレイヤーにさせたいこと」がはっきりしていなかったのである。
その結果、体験の核に必要のないものまで盛り込んでしまった。美麗だが超高コストのピクセルグラフィックや、リソースが足りず中途半端な実装にとどまったストーリーがそれだ。
そこでLimiTではテーマを先に決めて、それに必要のない要素はそぎ落とす選択をした。
「見ようとしているものしか見れない世界での視点誘導の方法」には、ピクセルグラフィックもストーリーも必要ない。
このゲームは色数は数色でよく、グラフィックは光っているのがわかる程度でよい(されど爽快感を失ってはならぬ)。ストーリーなんて地下から脱出する程度のものでよいのである。
結果としてLimiTのグラフィックは、数種類の単純な図形のみで構成されている。各図形が動くことでキャラクターの動きを表現する。敵側の攻撃判定にはすべてエラーピンクを設定して、攻撃がどのタイミングで当たるのかが一目でわかるようにした。
視界制限の実装
シェーダーでマスクをかける方法、いくつかのアプローチを考えたが、Godot には「ライト側とシャドウ側でレンダリングを分ける」仕組みが標準で用意されていた。ライトが当たっている範囲はスプライトをそのままレンダリングし、シャドウ側(ライトが届かない範囲)は透明にレンダリングする。
この機能を使うことで、比較的シンプルに視界制限を実現できた。
実装そのものより大変だったのは、「どのくらいの視野範囲が一番楽しいか」の調整だった。広すぎると緊張感がなくなる。狭すぎるとストレスになる。テストプレイを繰り返した結果、広い状態と狭い状態を選択肢として与える、マウスの距離に応じて視野角を変えるという手段をとった。
コードの設計:VisualController を分離した話
プレイヤーの実装で、意識的に設計したことがある。PlayerControllerBase.gd と
PlayerVisualController.gd を完全に分離した。
PlayerControllerBaseはプレイヤーの状態管理と入力処理に専念する。速度、HP、スキルのクールダウンといった「状態」をもつ。PlayerVisualController はその変数を監視して、アニメーションやエフェクトに反映させるだけ。見た目の責任を完全に分離した形だ。
こうした理由は明確だ。「ロジックをいじったら見た目が壊れた」「見た目を直したらロジックにバグが出た」という以前のゲーム制作で頻発した状況を避けたかった。
単独開発で全部自分でメンテするからこそ、コードの責務を明確に分けておくことが重要だと感じていた。
スキルも同様に、各スキルを独立したスクリプトで管理する設計にした。新しいスキルを追加するときに既存のコードを触らなくていい。スキルを増やすたびにバグが生まれるリスクを減らした。
敵AIの設計:ステートパターン
敵AIにはステートパターンを採用した。各敵は「待機・索敵・追跡・攻撃・撤退」といった状態を持ち、条件に応じてステートが切り替わる。
ステートパターンを選んだ最大の理由は、敵の種類が増えても基盤を使い回せるからだ。ステートの中身を差し替えるだけで、同じ骨格から全然違う動きをする敵が作れる。視界制限のゲームでは、敵の動きのバリエーションが緊張感に直結する。多様な敵を効率よく作れる設計は必須だった。
マルチプレイに挑んで、諦めた話
LimiT は当初、マルチプレイを想定して設計を始めた。「他のプレイヤーと競い合う視界制限バトル」——自分がやりたいゲームのイメージがあった。
実際に実装を進めてみると、同期の難しさに直面した。座標を同期するだけじゃダメだった。エフェクトの状態、HPの数値、最大HP、スキルのクールダウン——プレイヤーに関わるほぼ全ての変数を同期しなければならない。しかも「毎フレーム全部送る」という素朴な実装では同期遅れが起きる。どの変数を優先して送るか、優先度の設計が必要になる。
「同期させる情報に優先度をつける」という概念を、それまで一度も考えたことがなかった。Unity のチュートリアルを読んでも、個人ブログを漁っても、自分のゲームに合う答えがすぐには見つからなかった。
2人プレイでスキルを打ち合うところまでは実現できた。でも気づいてしまった——マルチプレイは相手がいないと成立しない。ゲームを公開してもプレイヤーがいなければ誰とも対戦できない。
結果として方針を転換した。まずシングルプレイのゲームとして完成させてプレイヤーを集める。その後にマルチプレイへ移行する。急がば回れ、というやつだ。今のLimiTはシングルプレイの作品として仕上がっているが、マルチプレイへの道は残してある。
ボスの難易度調整で学んだこと
単独開発の罠として有名なのが、「作った本人が上手くなりすぎて難易度がおかしくなる」問題だ。自分も思いっきりハマった。
最終ボスを友人にテストプレイしてもらったとき、「はめ技が多すぎる」と言われた。自分では気づけなかった。毎日プレイしていると、攻撃パターンを無意識に覚えてしまって、普通のプレイヤーにとっての難しさが分からなくなる。
対策として2つやった。ひとつは、はめ技をプレイヤー自身が対策できる仕様に変えた。理不尽に死ぬのではなく、「対策できるが難しい」という状態を目指した。もうひとつは、予備動作を大きくした。敵がこれから何をするか分かれば、プレイヤーは対応できる。「難しいけど対策の余地はある」——これがLimiTのボス戦で意識したデザインの軸になった。
素材を全部自分で作った理由
グラフィックも、SE も、全部自分で作った。
ひとつは世界観の統一。
他のアセットを組み合わせると、どうしてもちぐはぐな見た目になりやすい。自分で全部作れば、テイストが統一できる。
もうひとつは、チーム開発を意識した経験として。
前作の Project-KAKUGE!! でスプライト作成に苦戦した反省から、LimiT のキャラクターは単純な図形で構成する方針にした。複雑な形を避けることでアニメーション制作のコストを大きく下げられた。「どうすればタスクを進めやすいか」を考えながら素材を作るのは、チーム開発でタスクを振る立場になったときの予行練習でもあった。
結果:GC甲子園2025 総合大賞ノミネート
873チーム中150チームのノミネートに入ることができた。
正直なところ、ノミネートよりも「8ヶ月間、一人で最後まで作り切った」という事実の方が自分の中では大きい。途中でマルチプレイを諦めて、ボスの難易度を何度も直して、それでも公開できる形に仕上げた。
LimiT はまだ完成していない。第2ステージの改善も、マルチプレイへの移行も、やりたいことは残っている。でも「一度公開して、フィードバックをもらいながら改善する」という開発スタイルが、自分には合っていると思っている。