128KiBはどのくらいか:文字数・盤面・録音で換算する
遊びを見つける執筆にClaudeを使用しています。

アソバースでは、アップロードしたゲームにSDKが自動で追加され、作品ごとにJSONで128KiBまでのクラウドセーブを使えます。ところが「128KiB」と言われても、多いのか少ないのか見当がつきません。ゲームの進行を保存するには十分なのか、プレイの記録を全部残すには足りないのか、感覚がつかめないままでは設計の判断もできません。 そこで、この記事では128KiBを文字数、盤面、録音という身近な単位に置き換えます。計算は読者が手元で確かめられるもので、結果の数字はすべて算数の見積もりです。実際に作品がどう保存しているかは、確認済みの範囲では分からないため、「仮にこう書いたとすると」という置き方をします。最後に、自分のセーブデータを測る短いコードも用意しました。
この記事の目次
まず128KiBを文字数にする
128KiBは128×1,024で、131,072バイトです。KiBは1,024バイトを単位とする表記で、キロバイト(1,000バイト)よりわずかに大きい値です。
日本語のJSONは一般にUTF-8という文字コードで書かれます。UTF-8ではおおよそ次のように、文字の種類でバイト数が変わります。
- 半角英数字・記号、1文字のバイト数:1、131,072バイトに入る数:約13万文字
- ひらがな・カタカナ・漢字、1文字のバイト数:3、131,072バイトに入る数:約43,000文字
- 多くの絵文字、1文字のバイト数:4、131,072バイトに入る数:約32,000文字
日本語だけなら、約43,000字です。400字詰め原稿用紙に直すと100枚強です。ただし実際のJSONには、項目名、引用符、カンマ、波かっこが混ざります。文章だけを保存するわけではないので、使える文字数はこれより小さくなります。
なお、上限を「シリアライズ後のUTF-8のバイト数」で数えるのか、別の数え方なのかは、確認済み事項には書かれていません。ここでの換算は目安であり、正確な数え方は現在の案内で確認してください。
盤面で換算する:オセロとチェスの場合
盤面を保存する場面を考えてみます。オセロは8×8の64マスです。各マスを「空・黒・白」の1文字で表し、64文字の文字列にすると、引用符を含めて66バイトです。131,072÷66で、約1,900盤面が入る計算になります。
対局の記録なら、手を「d3」のように2文字で書き、JSONの配列にします。引用符とカンマを含めて1手が約5バイトです。オセロは最大でも60手前後なので、1局は約300バイトです。131,072÷300で、約430局分になります。
チェスは、局面を表す標準の書き方(FEN)で1局面が最大で約90文字です。引用符込みで約92バイトとすると、約1,400局面です。手の列で持つなら、1手を引用符とカンマ込みで約8バイトと見積もります。白黒合わせて80手の対局で約640バイトなので、約200局が入ります。
ここで確認済みの事実を整理します。
- 「灯りのチェス」は取った駒と全棋譜を表示します。
- 「かたちのあいだ」は4×4でも16個の数字の並びで済みます。数十バイトです。
- この3作品のうち、保存があるのは「かたちのあいだ」だけです。
- 「潮目のオセロ」と「灯りのチェス」の記録は、画面を開いている間だけ残ります。
- 保存があるのは、余白の庭、WAVE / WAVE、かたちのあいだの3作品です。
これらの保存の中身が実際にどんな形式か、またクラウドセーブを使っているかは、確認済みの範囲では分かりません。盤面の保存が上限に対していかに小さいか、という算数の確認として読んでください。
録音で換算する:音そのものか、操作の記録か
次は録音です。「雨音のピアノ」は30秒・128音まで録音してその場で再生できます。この録音を保存することを考えます。分かれ道は二つあります。
一つ目は、音そのものを保存する方法です。CD品質(1秒に44,100回、1回2バイト、モノラル)で30秒を数えると、44,100×30×2で約2,646,000バイトです。128KiBの約20倍にあたり、JSONに文字として埋め込む形式(Base64)にすると、さらに約1.33倍に膨らみます。音そのものの保存は、この上限には収まりません。
二つ目は、鍵盤を弾いた操作を記録する方法です。1音を {"n":"C4","t":1234} のように、音名と開始時刻(ミリ秒)で書くと、約22バイトです。128音でも約2,816バイト、つまり約2.75KiBです。上限の約2%で、同じ長さの録音が約46本入ります。
ここから読み取れる設計の考え方は、「再現に必要な操作だけを保存し、音は再生時に作り直す」というものです。「WAVE / WAVE」も、4つの音を16ステップに並べる作りです。64個のオン・オフと、テンポ、スウィングなどの数値を保存するだけで済みます。保存の中身を実際にどう持っているかは、作品を開いて確かめるしかありませんが、この構造なら小さく収まる、とは言えます。
画像も同じです。64×64ピクセルの絵をRGBA(1画素4バイト)で持つと16,384バイトです。Base64にすると約21,800バイトになります。128×128ならその4倍の約87,000バイトで、上限の7割近くに達します。画像を文字として保存するのは、重い選択です。
庭のような「置いたもの」を保存するとどうなるか
数が増えていく種類のデータも考えてみます。「余白の庭」には最大80個まで置けます。1個を {"t":"tree","x":120,"y":340,"s":1.2} のように、種類、座標、大きさで書くと約45バイトです。80個で約3,600バイト、約3.5KiBです。季節や昼夜の設定を足しても、上限に対してほとんど余裕が減りません。
つまり、80個という制限は、見た目や動作の都合だけでなく、保存の大きさを予測しやすくする働きもあると読めます。これは「設計から読み取れること」であり、開発の経緯を述べるものではありません。
危ないのは、制限のないものを保存する場合です。たとえば次のような作りは、気づかないうちに上限へ近づきます。
- 一手ごとの盤面を、対局のたびに足し続ける
- 毎フレームの位置を記録し続ける
- 全プレイの履歴を一つの配列に溜め続ける
- 整形(インデント付きの出力)のまま保存して、空白や改行を増やす
配列は件数に上限を設け、古いものから捨てるか、要約だけ残す、という設計が安全です。
自分のセーブを測る
保存したいデータが決まったら、実際のバイト数を測ります。次の最小構成のHTMLをファイルに保存してブラウザで開き、テキスト欄にセーブ用のJSONを貼ってください。整形を取り除いた状態と、元の状態の両方を表示します。
<!doctype html>
<meta charset="utf-8">
<textarea id="t" rows="10" cols="50">{"stage":3,"memo":"こんにちは"}</textarea>
<br><button id="b">測る</button>
<pre id="o"></pre>
<script>
const LIMIT = 128 * 1024;
const enc = new TextEncoder();
document.getElementById("b").onclick = () => {
const out = document.getElementById("o");
const raw = document.getElementById("t").value;
let data;
try { data = JSON.parse(raw); }
catch (e) { out.textContent = "JSONとして読めません"; return; }
const rawBytes = enc.encode(raw).length;
const minBytes = enc.encode(JSON.stringify(data)).length;
out.textContent =
"貼った文字列: " + rawBytes + " バイト\n" +
"整形なし : " + minBytes + " バイト\n" +
"上限に対する割合: " + (minBytes / LIMIT * 100).toFixed(2) + " %";
};
</script>結果の読み方は次のとおりです。
- 割合が10%未満なら、通常の使い方では余裕があります。
- 30〜50%を超えるなら、増え続ける配列がないか見直します。
- 100%に近いなら、中身を要約するか、保存する項目を絞ります。
記録は、最小のデータ、普通に遊んだデータ、長く遊んだデータの3種類で測ってください。長く遊んだデータで増え方を見ると、いつ上限へ近づくかが分かります。注意すべき誤りは、一度の測定だけで安心することと、日本語のメモ欄を考慮しないことです。1文字3バイトなので、長いメモ欄は意外に重くなります。
128KiBの外側にあるもの
最後に、混同しやすい数字を整理します。128KiBはクラウドセーブの上限で、作品ごとにJSONで持てる量のことです。アップロードの上限とは別の話です。ゲーム本体は20MiB以内、ZIP展開後は合計100MiB・1,000ファイル以内、1ファイル30MiB以内と決まっています。画像や音声などの素材は、このアップロード側に入れる前提で設計します。128KiBに入れるのは、進行、設定、記録といった小さなデータです。
アップロード作品内のlocalStorageとsessionStorageは、一時メモリー向けの互換処理にとどまります。長く残したい進行は、クラウドセーブに入れる設計にします。また、ゲストの履歴や進行は端末内に保存され、ログイン後のアカウントへ自動では混ざりません。上限を超えたときの扱いなど、確認済み事項にない挙動は、現在の案内で確認してください。
次の行動
自分の作品、または今作ろうとしている作品で、保存したい項目を紙に書き出し、1項目ずつ上の見積もりで概算してみてください。次に、上のHTMLで実際のJSONを測り、「長く遊んだ状態」でも半分に収まるかを確かめてください。収まらない項目は、画像や音そのものを保存していないか、増え続ける配列がないかを見直してください。
参考資料
- アソバース 投稿ガイド(保存とアップロード上限の案内)
- MDN Web Docs「TextEncoder」「JSON」

