マガジン

スプレッドシートでゲームのデータを管理する方法

遊びをつくる

執筆にClaudeを使用しています。

一つのボールと短い足場だけで作られた小さなゲーム模型。
記事のテーマをもとに制作したAI生成イメージ。実際のゲーム画面ではありません。

ゲームを作り始めると、キャラクターのステータス、アイテムの効果、ステージの構成パラメーターなど、コードの外側で管理したい数値や文字列が増えてきます。そのたびにJavaScriptのオブジェクトや配列を直接書き換えると、変更のたびにコードをデプロイし直す必要があり、バランス調整が何度も繰り返されるゲーム開発ではすぐに手間になります。 スプレッドシートはその問題を解消する現実的な選択肢です。Google スプレッドシートなら、ブラウザから数値を変えるだけでゲームに反映できる仕組みを比較的短い手順で作れます。コードの知識がある人が「データとロジックを分ける」設計を最初から意識すると、後からの仕様変更やデバッグがずっと楽になります。 この記事では、スプレッドシートをゲームのデータソースとして使うときの設計の考え方、実際にブラウザゲームへ読み込む手順、そして運用中に陥りやすい失敗点を順に説明します。

この記事の目次
  1. なぜデータをコードの外に出すのか
  2. どのデータをスプレッドシートに移すべきか
  3. Google スプレッドシートからデータを読み込む手順
  4. 運用中に起きやすい問題と対処
  5. JSONファイルとスプレッドシートのどちらを選ぶか
  6. 次の行動
  7. 参考資料

なぜデータをコードの外に出すのか

ゲームのデータをコードに直接書く方法(ハードコードとも呼ばれます)は、小さなプロトタイプでは素早く動かせる利点があります。しかし開発が進むにつれ、次のような問題が出てきます。

  • 敵の強さを少し変えるだけでもコードファイルを開いて数値を探す必要がある
  • データの変更履歴がコードのバージョン管理と混ざり、何を変えたかがわかりにくくなる
  • 複数人で作るとき、コードを書けない人がデータを触れない

スプレッドシートにデータを移すと、ゲームのロジック(処理の流れ)とゲームのデータ(数値・文字列・フラグ)が分離されます。ロジックはコードで管理し、データはスプレッドシートで管理するという分業ができます。この分離は「データ駆動設計(data-driven design)」と呼ばれ、ゲーム開発では広く使われている考え方です。

どのデータをスプレッドシートに移すべきか

すべてのデータをスプレッドシートに置けばいいわけではありません。移動に向くものと向かないものがあります。

向くもの

  • キャラクターや敵のステータス(HP、攻撃力、移動速度など)
  • アイテムや装備の種類・効果・レアリティ
  • ステージのパラメーター(敵の出現数、制限時間、BGM IDなど)
  • セリフや説明文などのテキスト
  • バランス調整の対象になる数値全般

向かないもの

  • ゲームのコアロジック(当たり判定の計算式、物理演算)
  • UI の描画処理や入力処理
  • セキュリティ上の理由から隠したい数値(有料コンテンツのアンロック条件など)

判断の基準は「この数値を変えるのはプログラマーか、それとも企画担当や自分自身か」です。後から繰り返し変える可能性があるものを優先的に外出しします。

Google スプレッドシートからデータを読み込む手順

Google スプレッドシートをブラウザゲームのデータソースとして使うには、シートをCSV形式またはJSON形式で公開し、JavaScriptで取得する方法が実用的です。

1. シートを公開形式で用意する

スプレッドシートに1行目を「列ヘッダー」として使い、2行目以降にデータを入力します。たとえば敵のデータなら、id・name・hp・attack・speed といった列を作ります。名前は半角英数で統一すると後でコードから参照しやすくなります。

シートの公開は「ファイル → 共有 → ウェブに公開」から行います。形式は「カンマ区切りの値(.csv)」を選ぶとシンプルです。公開後に発行されるURLをコピーしておきます。

2. JavaScriptでCSVを取得してオブジェクトに変換する

fetch('公開URL')
  .then(res => res.text())
  .then(csv => {
    const lines = csv.trim().split('\n');
    const headers = lines[0].split(',');
    const data = lines.slice(1).map(line => {
      const values = line.split(',');
      return Object.fromEntries(headers.map((h, i) => [h.trim(), values[i]?.trim()]));
    });
    // data を使ってゲームを初期化する
    initGame(data);
  });

このコードはヘッダー行をキーとして各行をオブジェクトに変換します。数値として使う列は Number(row.hp) のように明示的に変換してください。CSVのすべての値は文字列で届くため、型変換を忘れると計算が意図通りに動きません。

3. キャッシュとロードタイミングを意識する

fetch は非同期処理です。データが届く前にゲームの初期化が走るとエラーになります。then の中でゲームを起動するか、async/await を使って順序を保証してください。

また、Google スプレッドシートの公開URLはブラウザやCDNにキャッシュされることがあります。開発中はキャッシュが邪魔になる場合があるため、URLにタイムスタンプのクエリパラメーターを付けて毎回新鮮なデータを取得する方法がよく使われます(例:url + '?t=' + Date.now())。

運用中に起きやすい問題と対処

セルに余分なスペースや改行が入る

スプレッドシートをコピー&ペーストで編集すると、セルの末尾に空白が入ることがあります。.trim() を各値に適用することで大半のケースを防げます。

カンマを含む文字列が壊れる

CSVはカンマで列を区切るため、テキストデータにカンマが含まれるとパースが崩れます。セリフや説明文など自由記述の列がある場合は、シートの公開形式を「TSV(タブ区切り)」に変えて split('\t') で処理するか、Google Sheets APIを使ってJSON形式で取得するほうが安全です。

シートの構造を途中で変えてしまう

列を追加・削除・並び替えるとコード側のマッピングが壊れます。シートの構造が安定したら、列の順序は変えずに末尾に追加する運用ルールを決めておくと事故が減ります。列に番号を振るより名前(ヘッダー)でアクセスする設計にしておくと、順序変更に対して多少強くなります。

データが増えてシートが肥大化する

一枚のシートにすべてのデータを詰め込むと見通しが悪くなります。「敵」「アイテム」「ステージ」のようにシートを分けて管理し、コード側でもデータの種類ごとに取得処理を分けると保守しやすくなります。

JSONファイルとスプレッドシートのどちらを選ぶか

小さなゲームや個人開発では、JSONファイルをリポジトリに置いて直接 fetch する方法も有力です。スプレッドシートとJSONファイルの使い分けは次の観点で判断できます。

  • データの更新しやすさ、スプレッドシート:ブラウザから即時変更可能、JSONファイル:テキストエディタでの編集が必要
  • 複数人での作業、スプレッドシート:非エンジニアでも触れる、JSONファイル:コードの知識が必要になりやすい
  • オフライン・独立性、スプレッドシート:ネット接続とGoogleアカウントに依存、JSONファイル:リポジトリ内で完結
  • 型の厳密さ、スプレッドシート:文字列で届くため変換が必要、JSONファイル:数値・真偽値をそのまま使える

チームに企画担当やバランス調整を担う人がいる場合はスプレッドシート、一人で開発していてデータ量が少ない場合はJSONファイルが手軽です。どちらも「データとロジックを分ける」という目的は同じなので、プロジェクトの規模と体制で選んでください。

次の行動

まず手元のゲームから「今後も変えそうな数値はどれか」を書き出し、その列だけスプレッドシートに移してみてください。最初はキャラクター1体分の3〜5列から始めると、読み込み処理の確認がしやすくなります。データをスプレッドシートで管理できるようになったら、アソバースへZIPファイルとして投稿するときも、HTMLとスクリプトだけをまとめれば済むためパッケージがすっきりします。

参考資料

  • Google スプレッドシート ヘルプ(ウェブへの公開)
  • MDN Web Docs — Fetch API
  • MDN Web Docs — async function