一人用ゲームをマルチプレイにするには?作者とプラットフォームの役割
遊びをつくる執筆にClaudeを使用しています。

「アソバースに投稿すれば、自動でオンライン対戦できるようになりますか?」という質問をよく受けます。答えは「なりません」ですが、それだけでは何も前に進みません。この記事では、アソバースが今どこまで担っていて、作者が何を設計しなければならないのかを分けて説明します。
この記事の目次
今のアソバースで動くオンライン対戦はどれか
アソバースで共通の招待制オンライン対戦に対応しているのは、2026年10月時点で「潮目のオセロ」と「灯りのチェス」の2作品のみです。この2作品は招待リンクを共有するだけで遠隔の対局が始まり、合法手の確認・勝敗判定・接続が切れたあとの再接続をプラットフォーム側が担っています。
投稿されたゲームをオンライン対戦に自動変換する機能は存在しません。汎用の対戦SDK、自動マッチング、観戦、チャット、リアルタイムのレース同期も現時点では提供範囲外です。内部ドキュメントにも「投稿作品にこの内部APIの直接使用を案内しない」と記載されています。
すでに独自サーバーでオンライン対応しているゲームは、URLまたはファイルで投稿できます。その場合の通信・招待・勝敗処理は引き続き作者の実装です。
プラットフォームが引き受けている範囲
「潮目のオセロ」と「灯りのチェス」のオンライン対局では、アソバースが次の処理を担っています。
- 認証:メール確認済みのアカウントによる部屋作成・参加。参加者だけが盤面を読み取れるようFirestoreのセキュリティルールを設定します。
- 合法手の検証:着手はサーバー側のFunctionsがトランザクション内で確認します。クライアントの勝利申告は採用しません。
- 状態同期:確認済みの盤面を両者へ配信します。クライアントは新しいrevision(版数)の購読結果を受け取るまで次の着手を保留します。
- 勝敗・終局処理:チェスは標準終局判定(最大600着手で引き分け)、オセロは合法手なしで自動パス・石の数で決着します。
- 対戦履歴と再接続:部屋は作成から24時間有効で、ページを再読み込みしても同じ対局へ戻れます。
ゲームのiframe内にはアカウント情報(Firebase UID・メールアドレス・JWTなど)は渡しません。マルチプレイ画面からゲームiframeへ伝えるのは「ゲームID・対局状態・手番・結果・自分の席番号」に限られています。プラットフォームとゲームのやり取りはこの設計で分離されています。
作者が担う範囲:状態・合法手・認証のどれも省けない
公式2作品の内部実装は一般の投稿者に開放されていません。そのため、投稿ゲームに独自のオンライン対戦を加えるとしたら、作者が次のすべてを設計する必要があります。
1. 状態同期
どのプレイヤーが何を操作したか、その結果のゲーム状態を全員が同じ形で持つ仕組みが必要です。WebSocketやFirebase Realtimeなど通信手段はさまざまありますが、「誰が正しい状態を持つか」を決める設計(サーバー正本かクライアント予測かなど)は作者が選びます。
2. 合法手・入力の検証
チェスやオセロのように「特定の手だけ有効」なゲームは、クライアント側の検証だけでは不正操作を防げません。サーバー側のトランザクションで着手を確認する設計が安全です。アソバースの公式実装も、クライアントの勝利申告を採用せずFunctionsが判定しています。
3. 認証と通信の責任
アソバースのSDK(Asoverse.ready())が返すplayer.idは、ゲームスコープのIDです。公開クリエイターガイドには「ゲームに渡るのは作品専用のプレイヤーIDと、その作品のセーブデータ」と記載されており、メールアドレス・パスワード・Firebase認証トークンはゲームiframeへ渡らない設計です。player.idはゲームスコープのIDであり、プラットフォームがFirebase UID・認証トークンを外部ゲームに渡さない設計のため、このIDを外部バックエンドの身元確認の根拠として使うことは想定されていません。独自のオンライン対戦を運営するなら、独自のFirebaseプロジェクトや認証基盤を作者が整備します。
4. 通信費・運用・規約の維持
独自サーバーの費用、DoS対策、プレイヤー間のトラブル対応は、独自のオンライン機能を提供する作者が負います。アソバースの共通対戦枠(部屋作成1人1日10部屋・全体1日200部屋など)は公式ゲーム専用であり、投稿作品には適用されません。
今すぐできること:playModesの申告
独自のオンライン対戦をすでに実装している作品は、投稿フォームの任意項目でプレイモードを申告できます。
- playModes:solo(1人)、local(同じ端末でのふたり対局)、online(オンライン対戦)、coop(オンライン協力)の配列から選びます。
- maxPlayers:online/local/coopを含む場合は2〜1,000の整数、または未指定(null)を入力します。
この申告は作品詳細ページに「作者申告」として表示されます。申告しても共通部屋は有効になりませんが、プレイヤーに対して「このゲームはオンライン対戦に対応している」と伝える手段として機能します。独自の招待・通信・勝敗処理を作者が実装している前提での申告です。
小規模な独自実装を考える:ターン制ゲームの最小構成
「友達とだけ遊べれば十分」というターン制ゲームなら、独自サーバーの構成は比較的シンプルです。以下は設計を考えるときの出発点で、動作確認済みのコードではありません。
最小限の責任分担
- 部屋IDと招待URLの生成:自前のFirestoreやRealtime DatabaseにroomIdをキーとした部屋ドキュメントを作る。
- 参加者の確認:自分のFirebase AuthのUIDで参加者を管理。招待URLを知る2人目だけ参加できる設計にする。
- 着手の検証:Functionsのトランザクション内でゲームのルールエンジンを実行し、不正手を拒否してから盤面を更新する。
- 盤面の配信:Firestoreのリアルタイム購読(onSnapshot)で両者に最新状態を届ける。
- 終局処理:サーバー側で勝敗を確定し、statusをfinishedにしてから両者へ通知する。
この構成でもFirestoreのセキュリティルール設計・再接続の処理・タイムアウト設定を省略すると運用上の問題が起きます。アソバースの公式実装が「クライアントの勝利申告を採用しない」「revision(版数)を使って着手の競合を防ぐ」という設計を採っている理由は、ここにあります。
// 説明用の骨格。動作確認済みではありません。
// Functions側の着手受付(概念例)
exports.playMove = onCall(async (req) => {
const { roomId, revision, move } = req.data;
const uid = req.auth?.uid;
if (!uid) throw new HttpsError('unauthenticated', '要ログイン');
return db.runTransaction(async (tx) => {
const room = (await tx.get(db.doc(`rooms/${roomId}`))).data();
// 版数が古い、自分の手番ではない、不正手はすべて拒否
if (room.revision !== revision) throw new HttpsError('aborted', '版数ミスマッチ');
if (room.players[room.turn] !== uid) throw new HttpsError('permission-denied', '相手の手番');
if (!isLegal(room.state, move)) throw new HttpsError('invalid-argument', '不正手');
const nextState = applyMove(room.state, move);
const result = checkResult(nextState);
tx.update(db.doc(`rooms/${roomId}`), {
state: nextState,
turn: result ? null : 1 - room.turn,
result: result ?? null,
revision: room.revision + 1,
});
return { revision: room.revision + 1 };
});
});上のコードは設計の考え方を示す説明用です。isLegal・applyMove・checkResultはゲームごとに実装します。Firebase Functionsの料金・クォータ・デプロイ手順はFirebaseの公式ドキュメントで確認してください。
作者が確認しておくべき判断軸
独自のオンライン対戦を投稿ゲームに加えるとき、技術的な実装の前に決めておくことがあります。
- 誰と遊ぶか:招待制(知り合い限定)か、不特定多数のマッチングかで設計の複雑さが大きく変わります。招待制のほうが管理コストが小さく、スパム対策の負担も少ない。
- ゲームの状態量はどのくらいか:盤面が64マス程度(オセロ相当)か、数千オブジェクトが動くアクションゲームかで、Firestoreのコストと遅延許容度が変わります。
- リアルタイム性が必要か:ターン制パズルなら数百ミリ秒の遅延は問題にならない。アクションゲームやレースのリアルタイム同期は別の通信設計が必要です(現在アソバース共通機能では対応外)。
- 運営を続けられるか:作者がプロジェクトを終了した場合、オンライン対戦も終わります。プレイヤーへの周知方法と終了手順を最初から考えておくことを勧めます。
アソバースのSDKを使うだけではマルチプレイ対応にはならない点は、設計上の基本として押さえておきましょう。SDKはクラウドセーブとプレイ履歴の記録が目的であり、オンライン対戦の通信基盤ではありません。
将来的に一般投稿へ共通対戦を広げる際は、作者のルールを安全に実行する方式・対応確認・料金と通信枠・互換性の維持を改めて設計するとドキュメントに記載されています。現時点ではその仕様は公開されていません。




