Pixel Balanceを一人で開発・運営している山野です。このコラムでは、小さなブラウザゲームを作って公開するまでに私が何を考え、どんな技術を選び、どこでつまずいたのかを記録しています。同じように個人開発をしている方、これから始めたい方の参考になれば嬉しいです。
最終更新: 2026年8月11日
Pixel Balanceの出発点は、「ルールの説明がいらないゲームを作りたい」という一点でした。ブラウザゲームはアプリと違ってインストールの決断がない代わりに、離脱も一瞬です。開いて3秒で遊び方が分からなければ、そのままタブを閉じられてしまいます。
「積んだものは崩れる」「傾いたら倒れる」という感覚は、誰もが積み木で身体的に知っています。物理法則そのものをルールにすれば、チュートリアルを一切作らなくても遊び始められるはずだ——これが企画の核でした。実際、本作にチュートリアル画面はありません。画面上部を往復するブロックをタップで落とす、それだけです。
物理演算を自作するか、既存エンジンを使うかは最初の分かれ道でした。長方形と重力だけなら自作も不可能ではありませんが、「積み重なった剛体が互いにめり込まず、揺れながらも安定して静止する」という挙動の実装は、衝突解決と数値安定化の知識が要求される難所です。個人開発でそこに時間を溶かすのは本末転倒だと判断し、既存エンジンを探しました。
選んだのはMatter.jsです。理由は3つあります。第一に、依存なしの純粋なJavaScriptで、scriptタグ1枚で動くこと。ビルド環境のない静的サイトでも導入できます。第二に、MITライセンスであること。第三に、公式デモとドキュメントが充実していて、「積み上げ」に必要なAPI(剛体生成、衝突イベント、静的ボディの切り替え)がすべて揃っていたことです。
導入後の作業は、ほぼパラメータ調整に費やされました。現在の値は重力1.2、ブロックの摩擦係数0.8、反発係数0.05です。重力を標準の1.0より少し強めているのは、落下の「キビキビ感」を出すためです。この数値に至る経緯は仕組み解説で詳しく書いています。
本作のブロックはピンク・紫・青・緑・黄・オレンジ・赤の7色のパステルカラーです。この「7」という数は、マッチ要素(同色3つ以上の接触で消える)の発生頻度から逆算して決めました。色数が少ないほどマッチは頻発してパズル性が薄れ、多いほどマッチがほぼ起きなくなります。試行の結果、「狙えば揃えられるが、勝手には揃わない」バランスとして7色に落ち着きました。
色選びで最優先したのは、スマートフォンの小さな画面での識別しやすさです。同系色が並んだときにマッチの成否が一目で判断できないと、パズルとして成立しません。彩度を抑えたパステル調で揃えつつ、色相はできるだけ離す。この制約の中で7色を選んでいます。
描画そのものは非常にシンプルで、角ばった長方形に細い輪郭線と、上辺のハイライト(白の半透明の帯)を載せているだけです。装飾を足すほど、傾きや接触といった「物理の情報」が読み取りにくくなるためです。バランスゲームでは、ブロックの輪郭こそが最も重要なUIだと考えています。
また、凝ったスプライトやアニメーションを用意しない判断は、個人開発の制作コストの観点でも合理的でした。ブロックの「表情」は色と物理挙動に任せる。消えるときの縮小アニメーション(300ミリ秒)だけは、マッチ成立の手応えを出すために丁寧に入れています。
物理演算ゲームの負荷対策というとまず名前が挙がるのがSleeping(静止したボディを計算から外す機能)ですが、正直に書くと、本作はSleepingを有効にしていません。Matter.jsのデフォルト(無効)のままです。
理由は、本作の構造にあります。マッチでブロックが消えると、その上に載っていたブロックは支えを失って沈み込む必要があります。もし下層のブロックがスリープしていると、この「再沈降」が正しく始まらないケースが出てきます。実際、ブロックを消した直後の処理では、ワールド内の全ブロックを明示的に起こして(wakeさせて)、塔全体を再計算させています。眠らせる最適化と、消して崩すゲーム性は相性が悪かった、というのが実情です。
その代わりに、次のような地道な工夫で負荷を抑えています。
派手なテクニックはひとつもありませんが、「重い処理を数える」「呼ぶ回数を減らす」という基本だけで、スマートフォンでも安定して動く水準になっています。
個人開発のゲームにランキングを載せるかどうかは、かなり迷いました。サーバーを持てば費用と運用責任が発生しますし、アカウント管理を自前でやるのは論外です。それでも実装したのは、「昨日の自分に勝つ」だけでなく「誰かと比べる」楽しさが、この種のスコアアタックゲームの寿命を大きく延ばすと考えたからです。
バックエンドはFirebase(Firestore + Authentication)を選びました。個人開発にとって重要だったのは、小規模なうちは無料枠で運用できること、サーバーのプロセス管理が一切不要なこと、そしてGoogleアカウントログインを数行で組み込めることです。
設計上のこだわりは2つあります。1つ目は、ログインしなくても全機能で遊べることです。ログインが必要なのはランキングへのスコア登録とプロフィール機能だけで、ゲーム自体は匿名のまま完結します。遊ぶ前にアカウントを要求するゲームにはしたくありませんでした。
2つ目は、ランキングを「今日」「今月」「全期間」の3本立てにしたことです。全期間だけでは上位が固定化して、新しく始めた人が入り込む余地がなくなります。日次ランキングなら、始めたその日でも上位に名前を載せられる可能性があります。期間の区切りは日本標準時(JST)基準で日付キー・月キーをスコアに付与して管理しています。
2026年1月に、やり込み要素としてステッカーコレクションを追加しました。特定の条件を達成するとステッカーがアンロックされ、ゲーム画面の背景を自分好みに飾れる機能です。現在23種類あり、条件は「スコア10以上」のような達成しやすいものから、「高さ9ブロック達成」「同時35個のせ」のような挑戦的なもの、「朝4時〜9時にプレイ」のような時間帯もの、「スコアぴったり22」のような遊び心のあるものまで幅を持たせています。
設計で最初に決めたのは、ステッカーをゲームプレイに一切影響させないことです。もし「取得すると有利になる」効果を付ければ、収集のモチベーションは上がるかもしれません。しかしその瞬間、ランキングは「腕前の勝負」から「やり込み量の勝負」に変質します。ランキングの公平性を守るため、ステッカーは純粋な装飾に徹しました。
条件設計の方針は「普通に遊んでいれば自然にいくつか手に入り、全部集めようとすると遊び方が変わる」です。プレイ回数系(10回・50回・100回)やログイン日数系は前者、高さ系・同時のせ系は後者の役割です。高さや同時のせ数を狙うプレイは、スコアを狙うプレイとは配置戦略が変わるので、同じゲームがもう一度新鮮になります。
Pixel BalanceにはAndroid版があります。中身はWebサイト版と同じHTML/JavaScriptで、Expo(React Native)のWebViewで包んだハイブリッド構成です。ゲーム本体を二重に保守する余力はないので、この構成は最初から決めていました。
ただし「WebViewで包んだだけ」では、操作感がどうしてもWebサイトのままです。改善の転機になったのがv1.0.7(2026年3月)で、画面下部のナビゲーションをHTMLのメニューからAndroidネイティブのボトムタブに作り直しました。タブの切り替えがOS標準の挙動になったことで、体感がはっきりアプリらしくなりました。
一方で、ネイティブタブ化は新しい不具合も連れてきました。タブごとに別々のWebViewを持つ構成にしたため、あるタブでプロフィールを変更しても他のタブに反映されない同期問題が発生し、v1.0.8で修正。さらにタブを切り替えて戻ったときに画面内のフォーカス位置が残ってしまう問題をv1.0.9で修正しました。「タブ間で状態をどう共有するか」は、ハイブリッドアプリの設計で最初に決めておくべきだった、というのが反省点です。
Web版とアプリ版でコードベースを共有しているため、Web側の更新がそのままアプリにも反映されます。この身軽さはハイブリッド構成の一番の恩恵です。
現時点で温めているアイデアを、あくまで構想段階のものとして書いておきます。三角形や円形など物理挙動の異なるブロック形状の追加、色覚多様性に配慮したカラーパレットの選択肢、キーボード操作の拡充などです。どれも「いつ」をお約束できる段階ではありませんが、実装したものはこのコラムとトップページの更新履歴で報告していきます。ご意見・ご要望はお問い合わせフォームからいただけると開発の励みになります。