yandex-js-sdk について
Yandex Gamesで公開するゲーム開発者向けのJavaScript SDK連携スキルです。プレイヤーデータ、ストレージ、収益化、ランキング、ライフサイクルイベントなどを扱います。
主な機能
- 01SDKの初期化とライフサイクル処理
- 02プレイヤー認証とクラウドストレージ
- 03インタースティシャル・リワード・バナー広告
- 04アプリ内購入
- 05ランキングとリモート設定
- 06レビュー依頼とゲーム検索
活用シーン
- 01Yandexのプレイヤープロフィールとセーブデータの導入
- 02ゲーム中の広告管理
- 03ゲーム内購入の提供
- 04スコア送信とリモートフラグの取得
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hungify/ playables-skills --skill yandex-js-sdkインストール後、Claude Code で/yandex-js-sdkを入力して読み込まれたか確認します。
詳細
Yandex Games JavaScript SDK
概要
Yandex Games は、yandex.<tld>/games 上のフレーム内でゲームを読み込みます。SDK スクリプトが読み込まれると、ホストによって YaGames グローバルが挿入されます。主な機能領域は次のとおりです。
- ライフサイクルと環境:初期化、
LoadingAPI.ready()、GameplayAPI.start/stop、一時停止/再開イベント、デバイス情報、言語/TLD - プレイヤーとストレージ:認証、プロフィールデータ、プレイヤーごとのキー/値クラウドストレージ
- 収益化:全画面インタースティシャル、リワード動画、固定バナー広告、アプリ内購入
- エンゲージメント:リーダーボード、リモート設定フラグ、レビューのプロンプト、ホーム画面へのショートカット追加、サーバー時刻、クリップボードへの書き込み、
GamesAPIによる相互プロモーション
SDK はソーシャル共有、友達の招待、コミュニティへの参加、お気に入りへの追加、実績、統計カウンターには対応していません。
インストール
<script src="https://yandex.ru/games/sdk/v2"></script>
動的に読み込む場合は、init() を呼び出す前に window.YaGames && window.YaGames.init が定義されるまでポーリングしてください。
クイックスタート/統合ワークフロー
SDK を初めて組み込むときは、次の手順に従ってください。次の手順に進む前に、各手順を確認してください。
async function bootstrap() {
// 1. Ensure SDK script has loaded
if (!window.YaGames?.init) {
throw new Error('YaGames SDK not available — check that the script tag loaded');
}
// 2. Initialize — all subsequent SDK calls require ysdk
const ysdk = await window.YaGames.init();
// 3. Bind host-driven pause / resume before anything else
ysdk.on('game_api_pause', () => {
/* mute audio, pause gameplay */
});
ysdk.on('game_api_resume', () => {
/* unmute, resume */
});
// 4. Signal that the loading screen is gone
ysdk.features.LoadingAPI?.ready();
// 5. Read environment (language, device type)
const env = readEnvironment(ysdk);
// 6. Fetch player — fall back to guest mode if not authorized
let player = null;
let storageCache = {};
try {
const info = await getPlayer(ysdk);
player = info.raw;
if (info.isAuthorized) {
storageCache = await loadStorage(player);
}
} catch (err) {
console.warn('Player init failed, continuing as guest:', err);
}
// 7. Start gameplay tracking
onGameplayStarted(ysdk);
return { ysdk, player, storageCache, env };
}
function readEnvironment(ysdk) {
return {
language: ysdk.environment.i18n.lang.toLowerCase(),
tld: ysdk.environment.i18n.tld.toLowerCase(),
deviceType: ysdk.deviceInfo.type // 'desktop' | 'mobile' | 'tablet' | 'tv'
};
}
プレイヤー/認証
async function getPlayer(ysdk, { useSignedData = false } = {}) {
const player = await ysdk.getPlayer({ signed: useSignedData });
return {
raw: player,
id: player.getUniqueID(),
name: player.getName() || null,
photos: ['small', 'medium', 'large'].map((size) => player.getPhoto(size)).filter(Boolean),
isAuthorized: player.isAuthorized(),
payingStatus: player.getPayingStatus(),
signature: useSignedData ? player.signature : null
};
}
async function authorizePlayer(ysdk, options) {
const current = await getPlayer(ysdk, options);
if (current.isAuthorized) {
return current;
}
await ysdk.auth.openAuthDialog();
return getPlayer(ysdk, options);
}
ストレージ
呼び出しのたびにドキュメント全体が書き込まれます。キー単位の API はありません。クライアント側で最新のスナップショットをキャッシュし、保存する前にマージしてください。ゲストの場合は localStorage にフォールバックしてください。
async function loadStorage(player) {
return player.getData();
}
async function setStorage(player, cache, key, value) {
const data = { ...(cache || {}) };
if (Array.isArray(key)) {
for (let i = 0; i < key.length; i++) {
data[key[i]] = value[i];
}
} else {
data[key] = value;
}
await player.setData(data);
return data;
}
async function deleteStorage(player, cache, key) {
const data = { ...(cache || {}) };
if (Array.isArray(key)) {
for (let i = 0; i < key.length; i++) {
delete data[key[i]];
}
} else {
delete data[key];
}
await player.setData(data);
return data;
}
function getCached(cache, key) {
if (Array.isArray(key)) {
return key.map((k) => (typeof cache?.[k] === 'undefined' ? null : cache[k]));
}
return typeof cache?.[key] === 'undefined' ? null : cache[key];
}
広告
全画面インタースティシャル
onClose(wasShown) は、通常の閉じる操作と SDK によって広告がスキップされた場合の両方で呼び出されます。wasShown === false は失敗として扱ってください。
function showInterstitial(ysdk, handlers = {}) {
ysdk.adv.showFullscreenAdv({
callbacks: {
onOpen: () => handlers.onOpen?.(),
onClose: (wasShown) => handlers.onClose?.(wasShown),
onError: (err) => handlers.onError?.(err)
}
});
}
リワード動画
報酬は onRewarded 内で付与してください。onClose は広告 UI が閉じられた後に呼び出されます。
function showRewarded(ysdk, handlers = {}) {
ysdk.adv.showRewardedVideo({
callbacks: {
onOpen: () => handlers.onOpen?.(),
onRewarded: () => handlers.onRewarded?.(),
onClose: () => handlers.onClose?.(),
onError: (err) => handlers.onError?.(err)
}
});
}
固定バナー
async function getBannerStatus(ysdk) {
return ysdk.adv.getBannerAdvStatus(); // { stickyAdvIsShowing: boolean, reason?: string }
}
async function showBanner(ysdk) {
const data = await ysdk.adv.showBannerAdv();
return data.stickyAdvIsShowing === true;
}
async function hideBanner(ysdk) {
const data = await ysdk.adv.hideBannerAdv();
return data.stickyAdvIsShowing === false;
}
決済/IAP
初期化後に決済オブジェクトを一度取得してください。バックエンドで署名を検証する場合は signed: true を渡します。
async function initPayments(ysdk, { signed = true } = {}) {
return ysdk.getPayments({ signed });
}
カタログ
async function getCatalog(payments) {
const products = await payments.getCatalog();
return products.map((p) => ({
id: p.id,
title: p.title,
description: p.description,
imageURI: p.imageURI,
price: p.price,
priceValue: p.priceValue,
priceCurrencyCode: p.priceCurrencyCode,
priceCurrencyImage: p.getPriceCurrencyImage?.('medium')
}));
}
購入
async function purchase(payments, productId, payload) {
const result = await payments.purchase({ id: productId, developerPayload: payload });
if (!result?.purchaseData?.purchaseToken) {
throw new Error(
`Purchase succeeded but returned no purchaseToken for product ${productId}`
);
}
return { id: productId, ...result.purchaseData };
}
所有している購入
async function getPurchases(payments) {
const list = await payments.getPurchases();
return list.map((purchase) => ({ id: purchase.productID, ...purchase.purchaseData }));
}
消費
消費する前に、アイテムが付与されたことを確認してください。消費に失敗した場合、トークンは再試行できるよう保持されます。
async function consumePurchase(payments, purchaseToken) {
if (!purchaseToken) {
throw new Error('consumePurchase: purchaseToken is required');
}
await payments.consumePurchase(purchaseToken);
}
リーダーボード
ボードは開発者コンソールで設定し、文字列 ID で参照します。スコアを設定するには、プレイヤーが認証済みである必要があります。
async function setLeaderboardScore(ysdk, leaderboardId, score) {
const lb = await ysdk.getLeaderboards();
await lb.setLeaderboardScore(leaderboardId, score);
}
async function getLeaderboardEntries(ysdk, leaderboardId, { isPlayerAuthorized = false } = {}) {
const lb = await ysdk.getLeaderboards();
const options = { quantityTop: 20 };
if (isPlayerAuthorized) {
options.includeUser = true;
options.quantityAround = 3;
}
const result = await lb.getLeaderboardEntries(leaderboardId, options);
if (!result || result.entries.length === 0) {
return [];
}
return result.entries.map((e) => ({
id: e.player.uniqueID,
name: e.player.publicName,
score: e.score,
rank: e.rank,
photo: e.player.getAvatarSrc('large')
}));
}
リモート設定
ysdk.getFlags(options) は、フラットな { key: stringValue } マップを返します。
async function getRemoteConfig(ysdk, options = {}) {
const params = { clientFeatures: [], ...options };
return ysdk.getFlags(params);
}
サーバー時刻
function getServerTime(ysdk) {
// Returns Unix timestamp in milliseconds
return ysdk.serverTime();
}
ソーシャル
レビューのプロンプト
async function requestReview(ysdk) {
const can = await ysdk.feedback.canReview();
if (!can.value) {
throw new Error(can.reason || 'review not available');
}
const { feedbackSent } = await ysdk.feedback.requestReview();
return feedbackSent;
}
ホーム画面に追加(ショートカット)
async function canAddToHomeScreen(ysdk) {
const prompt = await ysdk.shortcut.canShowPrompt();
return prompt.canShow === true;
}
async function addToHomeScreen(ysdk) {
const result = await ysdk.shortcut.showPrompt();
return result.outcome === 'accepted';
}
クリップボード
async function clipboardWrite(ysdk, text) {
await ysdk.clipboard.writeText(text);
}
ゲームプレイのライフサイクル、一時停止、オーディオ
広告のペース調整と分析のため、アクティブなゲームプレイセッションは GameplayAPI.start() / GameplayAPI.stop() で開始・終了してください。
function onGameplayStarted(ysdk) {
ysdk.features.GameplayAPI?.start();
}
function onGameplayStopped(ysdk) {
ysdk.features.GameplayAPI?.stop();
}
function bindPauseHandlers(ysdk, { onPause, onResume }) {
ysdk.on('game_api_pause', () => onPause?.());
ysdk.on('game_api_resume', () => onResume?.());
}
Yandex から通知されない表示状態やフォーカスの変更も、これらの SDK コールバックと併せて document.visibilitychange、window.blur、window.focus で処理してください。
他の Yandex Games のカタログ(任意)
features.GamesAPI はゲームごとに利用可否が異なります。呼び出す前に名前空間が存在するか確認してください。
async function getAllGames(ysdk) {
const { games } = await ysdk.features.GamesAPI.getAllGames();
return games;
}
async function getGameById(ysdk, gameId) {
const { game, isAvailable } = await ysdk.features.GamesAPI.getGameByID(gameId);
return { ...game, isAvailable };
}