Comptes et traduction
Commencez par les capacités et erreurs du SDK. Ces exemples utilisent l’objet global injecté ; le jeu ne demande jamais les identifiants d’authentification du compte.
Connexion à l’initiative du joueur
Appelez checkSession() juste avant une action nécessitant un compte. Si le résultat est false, appelez login() à la suite d’une action explicite du joueur. L’hôte gère l’interface de connexion. cancelled est un choix normal ; les échecs de transport, de fenêtre de connexion ou de synchronisation du compte rejettent la Promise.
Après success, poursuivez directement l’action. Aucun rechargement, sondage ou second contrôle de session n’est nécessaire pour cette même action. Vérifiez à nouveau pour une action indépendante ultérieure. Désactivez le bouton pendant la requête.
<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;
}
});Les boutons et messages sont des exemples d’interface à adapter aux langues du jeu. La fonction renvoie null si la capacité manque ou si la connexion est annulée ; le gestionnaire de clic intercepte les véritables erreurs.
Lire le profil du joueur
getUserInfo() n’accepte aucun argument. Appelez-le après vérification de session ou connexion réussie. Sans connexion, la requête est rejetée avec session_required.
| Champ | Signification |
|---|---|
appId | Identité de l’application du jeu actuel |
openId | Identité du joueur dans cette application |
nickName | Nom affiché, éventuellement vide |
avatarUrl | URL de l’avatar, éventuellement vide |
locale | Langue publique enregistrée du joueur, par exemple en ou zh-CN ; langue actuelle du produit sinon |
Prévoyez des valeurs d’affichage de remplacement. Respectez la portée de l’application pour cette identité ; ce résultat d’affichage n’est ni un justificatif d’authentification ni une preuve d’autorisation pour votre backend. Il ne contient ni identifiant utilisateur de la plateforme, ni e-mail, ni session Cloud Ability.
Traduire les textes déjà affichés
Affichez d’abord les textes source, puis demandez leur traduction. sourceLocale désigne leur langue, pas la langue cible souhaitée. L’hôte choisit la langue actuelle du produit. sourceTexts contient les chaînes ou modèles source exacts, également utilisés comme clés du résultat.
<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();Le résultat est { needed: false } ou { needed: true, locale, translations }. Gardez la source si la traduction est ignorée, si une clé manque, si l’hôte est incompatible ou en cas d’échec. Les résultats SDK invalides deviennent aussi needed: false. Insérez les traductions comme texte, jamais comme HTML brut. Traduisez les modèles stables avant d’insérer les valeurs dynamiques ; modifiez sourceLocale si vous changez les textes anglais de l’exemple.
Référence Cloud Ability facultative
L’hôte Web actuel n’annonce pas ces quatre méthodes. Utilisez-les uniquement si init().methods les contient explicitement. Ce contrat n’active pas l’IA par la simple publication d’un jeu.
type Authorization = {
decision: "AUTHORIZATION_DECISION_GRANTED" | "AUTHORIZATION_DECISION_DENIED";
decidedAtMs: number;
};
type AuthSetting = Partial<Record<"ai_model", Authorization>>;
type CloudAbilitySession = { session: string; expiresAtMs: number };| Méthode | Paramètres et résultat |
|---|---|
getSetting() | Sans argument ; renvoie AuthSetting. Une portée absente n’a jamais été demandée |
authorize({ scope: "ai_model" }) | L’hôte gère la demande d’autorisation et renvoie Authorization |
openSetting() | Sans argument ; ouvre les paramètres de l’hôte et renvoie AuthSetting |
getCloudAbilitySession() | Sans argument ; renvoie une CloudAbilitySession de courte durée |
AUTHORIZATION_DECISION_DENIED est une décision normale, pas une erreur de transport. N’écrivez pas la valeur zéro UNSPECIFIED. Les temps sont en millisecondes. Ne transmettez aucun identifiant d’utilisateur, d’appareil ou de jeu. Conservez la session uniquement en mémoire, respectez expiresAtMs, supprimez-la à la fin de la partie et ne la placez jamais dans le stockage, les journaux ou une URL.