SDKが自動で追加されるとき、HTMLのどこに何が入るのか:自分の作品で確かめる手順
遊びを見つける執筆にClaudeを使用しています。

アソバースにHTMLかZIPをアップロードすると、そのゲームにはSDKが自動で追加されます。SDKは、ゲームから使える小さな部品群のことです。作品専用のプレイヤーIDやクラウドセーブは、この部品を通して使います。 ここで気になるのは、自分の書いたHTMLのどこに、何が足されるのかという点です。足されるのが本当に「一行」なのか、先頭なのか末尾なのか、読み込み順は自作スクリプトの前か後か。こうした細部は、現在の案内で公開されている範囲では確認できません。そこでこの記事では、確認できている事実から「この部品はこういう役割を持つはずだ」と読み取れる範囲を整理します。そのうえで、細部は自分の作品を開いて確かめる手順を示します。
この記事の目次
確認できていることと、確認できていないこと
まず線引きをします。次の内容は、現在確認できています。
- アップロードしたゲームには、SDKが自動で追加されます。
- URLで投稿したゲームは、作者がSDKを自分で読み込んだときに、作品専用のプレイヤーIDとクラウドセーブが使えます。
- クラウドセーブは作品ごとにJSONで128KiBまでです。
- ゲームには、FirebaseのUID、認証トークン、メールアドレスを渡しません。
- アップロード作品の中のlocalStorageとsessionStorageは、一時メモリーとして働く互換処理です。
- ゲームはsandbox付きのiframeで動きます。アップロードしたコードは、メインサイトとは別のオリジンから配信されます。
- アップロードの入口は、ZIPの直下にあるindex.htmlです。
一方、次の点は確認できていないので、この記事でも断定しません。
- 追加されるコードが、本当に一行かどうか。
- 挿入位置が、<head>の中か、<body>の末尾か。
- 読み込み順が、自作スクリプトの前か後か。
- アップロードの時点でファイルに書き込まれるのか、配信の時点で足されるのか。
- SDKが公開している関数名や使い方。
最後の項目は特に注意が必要です。関数名を推測して呼び出すコードを書くと、動いたとしても仕様として保証されません。使い方は、現在の案内で確認してください。
「差し込まれる部品」の役割を、制約から読み解く
細部が分からなくても、周辺の確認済み事項を並べると、SDKに求められる役割はかなり絞れます。「設計から読み取れること」として、三つ挙げます。
ゲームと本体サイトの間にある、狭い窓口
ゲームは、sandbox付きのiframeの中で、別オリジンから配信されます。ブラウザの仕組みとして、この状態のゲームは本体サイトのページを直接触れません。本体のログイン情報にも手が届きません。
一方で、クラウドセーブやプレイヤーIDは、ログイン中のアカウントと結びつく機能です。壁で隔てられたゲームが、アカウントに紐づく機能を使うには、決められた窓口が必要になります。SDKは、その窓口として働く部品だと読み取れます。
渡さないものが明示されている
ゲームには、FirebaseのUID、認証トークン、メールアドレスを渡さないとされています。代わりに渡されるのは、作品専用のプレイヤーIDです。作品ごとに別のIDなら、別の作品のゲームと同じ人物だと結びつける手がかりになりにくいと考えられます。
つまり、ゲームの作者はプレイヤーを区別できますが、その人のメールアドレスや認証情報には届きません。遊ぶ側にも、作る側にも分かりやすい線引きです。
セーブの置き場所が、ブラウザの外にある
アップロード作品の中のlocalStorageとsessionStorageは、一時メモリーの互換処理とされています。「互換」とあるので、既存のゲームがこれらの命令を呼んでもエラーで止まらないようにしてあると読めます。ただし「一時メモリー」なので、ずっと残る保存先としては期待できません。
残したいデータは、クラウドセーブ(作品ごとにJSONで128KiBまで)に置くのが基本の考え方になります。具体的な呼び出し方は、現在の案内で確認します。
自分の作品で確かめる:スクリプト一覧を出す
ここからは、実際に挿入結果を観察する手順です。結果は環境や時期で変わりうるので、記事では書きません。自分で確かめて、答えを得る形にします。
準備するのは、次の最小のHTMLです。ページが読み終わった後に、そのページに存在するscript要素を一覧表示します。
<!doctype html>
<meta charset="utf-8">
<title>probe</title>
<body>
<h1>script 一覧</h1>
<pre id="out"></pre>
<script>
window.addEventListener('load', () => {
const rows = [...document.scripts].map((s, i) => {
const kind = s.src
? 'src=' + s.src
: 'inline ' + s.textContent.length + '文字';
const where = s.parentElement.tagName;
return (i + 1) + ': [' + where + '] ' + kind;
});
document.getElementById('out').textContent = rows.join('\n');
});
</script>
</body>これをindex.htmlという名前で保存し、ZIPにせずHTMLのまま、非公開か下書きの状態でアップロードして表示を確認します。表示された一覧を、手元のファイルと見比べます。
手順
- 手元のファイルにはscriptが1本だけあることを確認します。
- アップロード後の表示で、一覧の行数を数えます。
- 行数が増えていれば、増えた行が追加された部品の候補です。src=で始まる外部ファイルか、inlineの埋め込みかを読みます。
- 角括弧の中のタグ名(HEADかBODYか)が、挿入位置の手がかりです。
- 並び順を見ます。自作のスクリプトより上にあれば先に、下にあれば後に読み込まれています。
増えた行が一本のときに限って「一行」と呼べます。増えた行の数や形は、この手順で確かめます。
ブラウザの開発者ツールで見る
一覧表示だけでは、タグ以外の変化は分かりません。次の二つを併用すると、見落としが減ります。
配信されたHTMLと、現在のDOMを比べる
ブラウザには、見方が二つあります。
- 「ページのソースを表示」は、配信されたHTMLそのものを見る方法です。
- 開発者ツールの「要素」(Elements)パネルは、ブラウザが組み立てた現在の構造を見る方法です。
ゲームは、本体ページの中のiframeで動いています。そのため、ソース表示では外側のページしか見えない場合があります。iframe内を見るには、要素パネルでiframeの内側まで展開するか、iframeだけを別タブで開く操作が必要です。
二つを比べて差があれば、後から動的に足された要素があるということです。差がなければ、足された内容は最初のHTMLに含まれています。
コンソールで調べる
コンソールには、実行する場所(コンテキスト)を選ぶ切り替えがあります。標準では外側のページが選ばれているので、ゲームのiframeに切り替えてから、次の一行を実行します。
[...document.scripts].map(s => s.src || 'inline')先ほどの一覧表示と同じ情報が、配列で返ります。コンテキストを切り替えないと、外側のページのscriptが返るので注意します。
結果の読み方と、起こりやすい誤り
観察の結果は、次のように読みます。
- 行が増えている、読み取れること:部品が足されている。位置と形は一覧から読める
- 行が増えていない、読み取れること:script以外の方法か、読み込みのタイミングが遅い可能性がある。ソース表示との差も確認する
- ソース表示に含まれ、手元のファイルにない、読み取れること:配信されるHTMLの段階で足されている
- 要素パネルにだけ現れる、読み取れること:実行時に動的に足されている
起こりやすい誤りもあります。
- ブラウザ拡張の影響:拡張機能がscriptを足すことがあります。拡張を無効にした画面か、シークレットウィンドウでも確認します。
- キャッシュ:手元のファイルを直して再アップロードしても、古い内容が表示されることがあります。再読み込みや、キャッシュを無視した読み込みで確かめます。
- iframeの取り違え:外側のページのscriptを、ゲームのものと見間違えるケースです。コンソールのコンテキスト選択を確認します。
- 一度の観察で決めつける:非公開や下書きでの見え方と、公開後の見え方が同じとは限りません。仕様として扱う前に、現在の案内で確かめます。
作る人が気をつけること
最後に、作者の立場で押さえておくことを挙げます。
自作コードで保存を作り込みすぎないこと。 アップロード作品のlocalStorageは一時メモリーなので、「閉じても残る」前提で設計すると、期待とずれます。実際、公式作品13本のうち保存があるのは3本だけで、他の10本の記録や録音は画面を開いている間だけです。残す必要があるかどうかを、最初に決めておくと迷いません。
セーブの大きさを測っておくこと。 クラウドセーブは作品ごとにJSONで128KiB、つまり131,072バイトまでです。自作のセーブデータが収まるかは、次の一行で測れます。
new Blob([JSON.stringify(saveData)]).size返る数が131072を超えていれば、そのままでは入りません。画像データそのものを入れず、座標や番号などの小さな値にするといった工夫が必要です。
個人情報を前提にしないこと。 ゲームにはUIDや認証トークン、メールアドレスは渡されません。名前やメールアドレスで利用者を識別する作りにはできません。識別は作品専用のプレイヤーIDが前提になります。
URL投稿の場合は読み込みが自分の責任になること。 URLで投稿する作品は、作者がSDKを読み込んではじめて、プレイヤーIDやクラウドセーブが使えます。読み込み方は、現在の案内で確認します。
サーバー用コード、サービスワーカー、SharedArrayBufferを使うマルチスレッドは、アップロードの対象外です。 通信を前提にした作りより、一つのHTMLで完結する作りが向いています。
次の行動
上のprobeのHTMLを保存し、下書きか非公開でアップロードして、スクリプト一覧の行数と並びを確かめてみてください。手元のファイルとの差が、SDKが足された跡です。その差の形を見たうえで、使い方は現在の案内で確認し、自作ゲームのセーブをどこに置くかを決めてください。

