アカウントと多言語対応
先に SDK の対応機能とエラーを確認してください。以下の例は注入されたグローバルを使い、ゲームからアカウントの認証情報を要求しません。
プレイヤーの操作を起点にログインする
アカウントが必要な操作の直前に checkSession() を呼びます。false なら、プレイヤーの明示的な操作から login() を呼んでください。ログイン UI はホストが管理します。cancelled は通常の選択です。通信、ポップアップ、アカウント同期の失敗では Promise が拒否されます。
success の後はそのまま現在の操作を続けます。同じ操作のために再読み込み、ポーリング、再度のセッション確認は不要です。後で別の操作を行う際は再確認します。処理中は起点となるボタンを無効にしてください。
<button id="player-button">Show player</button>
<output id="player-info" aria-live="polite"></output>async function readPlayerAfterClick() {
const sdk = window.combos;
if (!sdk) return null;
const { methods } = await sdk.init();
if (!methods.includes("getUserInfo")) return null;
if (!(await sdk.checkSession())) {
const result = await sdk.login();
if (result.status !== "success") return null;
}
return sdk.getUserInfo();
}
const button = document.querySelector<HTMLButtonElement>("#player-button");
const output = document.querySelector<HTMLOutputElement>("#player-info");
button?.addEventListener("click", async () => {
if (!output) return;
button.disabled = true;
try {
const player = await readPlayerAfterClick();
output.textContent = player
? player.nickName || "Player"
: "Player information is unavailable.";
} catch {
output.textContent = "Unable to read player information. Please try again.";
} finally {
button.disabled = false;
}
});ボタンとメッセージはゲーム UI のサンプルなので、ゲームの言語に合わせて変更してください。ヘルパーは機能がない場合とログイン取消時に null を返し、実際の失敗はクリックハンドラーが捕捉します。
プレイヤー情報を読む
getUserInfo() に引数はありません。セッション確認またはログイン成功後に呼びます。未ログインなら session_required で拒否されます。
| フィールド | 意味 |
|---|---|
appId | 現在のゲームのアプリ識別子 |
openId | そのアプリ内でのプレイヤー識別子 |
nickName | 表示名。空文字列の場合あり |
avatarUrl | アバター URL。空文字列の場合あり |
locale | プレイヤーが保存した公開言語(例: en、zh-CN)。未保存なら現在の製品言語 |
表示情報がない場合の代替を用意してください。アプリ内の識別子はそのアプリの範囲で扱い、この表示用応答を自分のバックエンドの認証情報や権限の証明に使わないでください。プラットフォームのユーザー ID、メールアドレス、Cloud Ability セッションは含まれません。
表示済みのゲーム文言を翻訳する
まず原文を表示してから翻訳を要求します。sourceLocale は原文の言語であり、希望する翻訳先ではありません。翻訳先はホストの現在の製品言語です。sourceTexts には完全な原文やテンプレートを渡し、結果のキーにも同じ原文が使われます。
<button data-source-text="Play"></button>
<button data-source-text="Pause"></button>async function localizeLabels() {
const nodes = [...document.querySelectorAll<HTMLElement>("[data-source-text]")];
const sourceTexts = nodes.map(node => node.dataset.sourceText ?? "");
nodes.forEach((node, index) => { node.textContent = sourceTexts[index]; });
const sdk = window.combos;
if (!sdk) return;
try {
const { methods } = await sdk.init();
if (!methods.includes("requestI18n")) return;
const result = await sdk.requestI18n({ sourceLocale: "en", sourceTexts });
if (!result.needed) return;
nodes.forEach((node, index) => {
const source = sourceTexts[index];
node.textContent = result.translations[source] || source;
});
} catch {
// Keep the source copy on screen.
}
}
void localizeLabels();結果は { needed: false } または { needed: true, locale, translations } です。翻訳不要、キー欠落、未対応、失敗時には原文を残します。不正な SDK 応答も needed: false になります。訳文は HTML としてではなくテキストとして表示してください。固定テンプレートを翻訳してから動的な値を入れ、例の英語原文を変更したら sourceLocale も更新します。
オプションの Cloud Ability API
現在の Web ホストは次の 4 メソッドへの対応を表明していません。 init().methods に明示的に含まれる場合だけ使用してください。ゲームを公開するだけで AI 機能が有効になる契約ではありません。
type Authorization = {
decision: "AUTHORIZATION_DECISION_GRANTED" | "AUTHORIZATION_DECISION_DENIED";
decidedAtMs: number;
};
type AuthSetting = Partial<Record<"ai_model", Authorization>>;
type CloudAbilitySession = { session: string; expiresAtMs: number };| メソッド | 引数と結果 |
|---|---|
getSetting() | 引数なし。AuthSetting を返す。スコープがない場合は未確認 |
authorize({ scope: "ai_model" }) | ホストが許可 UI を管理し、Authorization を返す |
openSetting() | 引数なし。ホスト設定を開き、AuthSetting を返す |
getCloudAbilitySession() | 引数なし。短期の CloudAbilitySession を返す |
AUTHORIZATION_DECISION_DENIED は通常の許可判断であり、通信失敗ではありません。ゼロ値 UNSPECIFIED を書き込まないでください。時刻の単位はミリ秒です。ユーザー・端末・ゲーム ID をこれらのメソッドへ送らないでください。受け取ったセッションはメモリー内だけに保持し、expiresAtMs を守り、プレイ終了時に破棄します。ストレージ、ログ、URL に含めないでください。