mcpField
C
crazy-games-js-sdk

crazy-games-js-sdk

github.com/hungify開発016 回インストール1 週間前に更新
リポジトリ

crazy-games-js-sdk について

ゲーム開発者向けの CrazyGames JavaScript SDK 統合スキルです。初期化、ゲームのライフサイクルフック、広告、プレイヤー情報、ストレージ、オプションの Xsolla 決済を扱います。

主な機能

  1. 01SDK の読み込みと初期化ガイド
  2. 02ゲームと読み込みのライフサイクルフック
  3. 03インタースティシャル広告とリワード広告
  4. 04プレイヤー認証とプロフィールへのアクセス
  5. 05キーと値のストレージ連携
  6. 06オプションの Xsolla 決済フロー

活用シーン

  1. 01ゲームへの CrazyGames SDK 導入
  2. 02ゲーム状態とライフサイクル呼び出しの対応付け
  3. 03インタースティシャル広告やリワード広告の表示
  4. 04SDK ストレージによるプレイヤーデータ保存

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/hungify/playables-skills --skill crazy-games-js-sdk

インストール後、Claude Code で/crazy-games-js-sdkを入力して読み込まれたか確認します。

詳細

CrazyGames JavaScript SDK

統合チェックリスト

ゲームに SDK を統合する際は、次の順序で進めてください。

  1. SDK の読み込み — ゲームの初期化前に CDN の <script> タグを追加します
  2. 初期化 — SDK.init() を呼び出し、解決されるまで待ってから SDK のモジュールを使用します
  3. ライフサイクルフック — ゲームループ全体で loadingStart/Stop と gameplayStart/Stop を接続します
  4. 広告 — 自然な区切りにインタースティシャル広告および/またはリワード広告の呼び出しを追加します
  5. 任意:認証とストレージ — 必要に応じて、サインインと永続的なキー/値ストレージを追加します
  6. 任意:決済 — Xsolla Pay Station の統合(別途対応が必要です。該当しない場合は省略してください)

インストール

ゲームの初期化前に、公式 CDN から SDK を読み込みます。

<script src="https://sdk.crazygames.com/crazygames-sdk-v3.js"></script>

動的に読み込む場合は、呼び出す前に window.CrazyGames.SDK.init が定義されるまで待ってください。スクリプトがブロックされている場合(CSP など)、window.CrazyGames グローバルは未定義になります。script-src ディレクティブに sdk.crazygames.com を追加してください。

初期化

SDK.init() は一度だけ呼び出してください。SDK の準備が整うと解決されます。解決後に限り、SDK.user、SDK.data、SDK.ad、SDK.banner、SDK.game、SDK.analytics を安全に使用できます。

async function initCrazyGames() {
    if (!window.CrazyGames?.SDK) {
        throw new Error('CrazyGames SDK script not loaded');
    }
    const sdk = window.CrazyGames.SDK;
    try {
        await sdk.init();
    } catch (err) {
        throw new Error(`CrazyGames SDK init failed: ${err.message}`);
    }

    const isUserAccountAvailable = sdk.user.isUserAccountAvailable;

    if (isUserAccountAvailable) {
        const language = sdk.user.systemInfo.countryCode.toLowerCase();
        const deviceType = sdk.user.systemInfo.device.type.toLowerCase(); // 'desktop' | 'mobile' | 'tablet'
        console.log('lang/device', language, deviceType);
    }

    return sdk;
}

動作確認

initCrazyGames() の呼び出し後、先に進む前に SDK が動作していることを確認してください。

  • コンソールの確認 — CrazyGames SDK init failed エラーが表示されないことを確認します。sdk.user.isUserAccountAvailable が例外を発生させずにブール値を返すことを確認します。
  • ライフサイクルフック — ゲームの CrazyGames サンドボックス URL を開き、loadingStart / loadingStop / gameplayStart / gameplayStop の呼び出しが CrazyGames の開発者ダッシュボードのイベントログに表示されることを確認します。
  • 広告コールバック — CrazyGames のサンドボックス環境を使用し(URL に ?crazygames_sandbox=1 を追加)、テスト広告を表示して adStarted と adFinished が正しく発火することを確認します。
  • 広告ブロッカー — 広告ブロッカーを有効にした状態で sdk.ad.hasAdblock() を呼び出し、true に解決されることを確認します。

プレイヤー/認証

showAuthPrompt() を使ってプレイヤーにサインインを促し、続いて getUser() でプロフィールデータを読み取ります。必要に応じて getUserToken() で署名済み JWT を取得し、バックエンドで検証できます。

async function authorizePlayer(sdk, { useUserToken = false } = {}) {
    if (!sdk.user.isUserAccountAvailable) {
        // Guest session — no auth possible on this domain
        return null;
    }

    await sdk.user.showAuthPrompt();

    const user = await sdk.user.getUser();
    if (!user) {
        return null;
    }

    const profile = {
        name: user.username || null,
        photo: user.profilePictureUrl || null,
        extra: user
    };

    if (useUserToken) {
        profile.extra.jwt = await sdk.user.getUserToken();
    }

    return profile;
}

ストレージ

CrazyGames は SDK.data を介して同期的なキー/値ストレージを提供します。値は文字列です。JSON のシリアライズはご自身で行ってください。

function storageSet(sdk, key, value) {
    const data = typeof value === 'string' ? value : JSON.stringify(value);
    sdk.data.setItem(key, data);
}

function storageGet(sdk, key, tryParseJson = true) {
    const raw = sdk.data.getItem(key);
    if (!tryParseJson || raw == null) {
        return raw;
    }
    try {
        return JSON.parse(raw);
    } catch (_) {
        return raw;
    }
}

function storageRemove(sdk, key) {
    sdk.data.removeItem(key);
}

// Batch helpers — just iterate, the SDK has no native multi-key API
function storageSetMany(sdk, keys, values) {
    for (let i = 0; i < keys.length; i++) {
        storageSet(sdk, keys[i], values[i]);
    }
}

広告

インタースティシャル広告(midgame)

SDK.ad.requestAd('midgame', callbacks) を呼び出します。広告のライフサイクルの進行に応じて、コールバックが同期的に発火します。

function showInterstitial(sdk) {
    sdk.ad.requestAd('midgame', {
        adStarted: () => {
            // Mute audio and pause the game here
        },
        adFinished: () => {
            // Resume audio and gameplay here
        },
        adError: (error) => {
            console.warn('interstitial failed', error);
        }
    });
}
リワード広告

同じ API を使用し、タイプとして 'rewarded' を渡します。adFinished はユーザーが最後まで視聴したことを意味し、報酬を付与する必要があります。

function showRewarded(sdk, onReward) {
    sdk.ad.requestAd('rewarded', {
        adStarted: () => {
            // Pause the game
        },
        adFinished: () => {
            onReward();
        },
        adError: (error) => {
            console.warn('rewarded failed', error);
        }
    });
}
広告ブロッカーの検出
async function isAdblockActive(sdk) {
    return sdk.ad.hasAdblock();
}
レスポンシブバナー

バナーは、既存の DOM コンテナーに ID で紐付けられます。CrazyGames がその中に描画し、適切なサイズを選択します。

async function showBanner(sdk, containerId) {
    // The container must already be in the DOM and visible
    try {
        await sdk.banner.requestResponsiveBanner([containerId]);
    } catch (e) {
        console.warn('banner failed', e);
    }
}

async function showAdvancedBanners(sdk, containerIds) {
    // Request several banners in parallel
    await Promise.all(containerIds.map((id) => sdk.banner.requestResponsiveBanner(id)));
}

function hideBanners(sdk) {
    sdk.banner.clearAllBanners();
}

ライフサイクル/ゲームプレイイベント

CrazyGames では、ホストゲームが適切なタイミングでゲームプレイと読み込みのフックを呼び出す必要があります。これらのフックは、広告の表示タイミング、ゲーム内 UI の暗転、分析情報を制御します。

一般的なゲームのライフサイクルイベントを、次のように SDK の呼び出しに対応付けます。

ゲームイベントSDK 呼び出し
level_started、level_resumed、gameplay_startedsdk.game.gameplayStart()
level_paused、level_completed、level_failed、gameplay_stoppedsdk.game.gameplayStop()
in_game_loading_startedsdk.game.loadingStart()
in_game_loading_stoppedsdk.game.loadingStop()
player_got_achievementsdk.game.happytime()

CrazyGames SDK には、個別の audio / pause / visibility コールバックはありません。広告コールバック(adStarted / adFinished)と標準の document.visibilitychange イベントを使って、音声と一時停止の状態を制御してください。


Payments (optional, via Xsolla Pay Station)

Xsolla のプロジェクト ID がない場合は、このセクション全体をスキップしてください。 CrazyGames 自体は IAP を販売しません。この統合では、CrazyGames が発行した Xsolla ユーザートークンを Xsolla Pay Station ウィジェットおよび Xsolla Store API とともに使用します。

主な定数:

const XSOLLA_PAYSTATION_EMBED_URL =
    'https://cdn.xsolla.net/payments-bucket-prod/embed/1.5.0/widget.min.js';
const XSOLLA_SDK_URL = 'https://store.xsolla.com/api/v2/project';

sdk.user.getXsollaUserToken() を使用して Xsolla ユーザートークンを取得します。すべての Xsolla Store API リクエスト(カタログ、購入、インベントリ、消費)で、これを Bearer トークンとして使用します。

カタログ — GET /{projectId}/items?limit=50

購入フロー:

  1. POST /{projectId}/payment/item/{sku} → { token, order_id } が返されます
  2. まだ読み込まれていない場合は、XSOLLA_PAYSTATION_EMBED_URL を動的に読み込みます
  3. XPayStationWidget.init({ access_token: token, sandbox: isSandbox }) を実行し、その後 .open() を呼び出します
  4. XPayStationWidget.eventTypes.STATUS を監視します。paymentInfo.status が /done|charged|success/i に一致したら、GET /{projectId}/order/{orderId} を取得し、sdk.analytics.trackOrder('xsolla', order) を呼び出して購入を記録します
  5. キャンセルを処理するため、'close' イベントを監視します

インベントリ — GET /{projectId}/user/inventory/items

消費 — { sku, quantity } を指定して POST /{projectId}/user/inventory/item/consume を呼び出します

すべての fetch 呼び出しには、Authorization: Bearer <xsollaToken> を含める必要があります。成功以外のレスポンスでは例外をスローします。開発中は isSandbox: true を使用してください。

コメント