Skip to content
Developer Docs

SDK

Use the SDK for player identity, analytics, Buncha Credits, wallet/IAP, entitlements, ads, and sandbox testing.

What the SDK gives you

  • Player identity and display names through the Buncha Games wrapper.
  • Lifecycle calls such as ready, game start, pause, resume, and game end.
  • Standard and custom analytics events for levels, areas, bosses, modes, tutorials, purchases, and other in-game moments.
  • Buncha Credits balance display and wallet update events.
  • Wallet/IAP purchase requests where Buncha Games owns checkout, receipts, and balance changes.
  • Entitlement validation so games can unlock content only after the platform confirms ownership.
  • Approved ad placement and reward callbacks through Buncha Games-controlled ad flows.
  • Sandbox wallet, IAP, entitlement, and ad test methods for approved builds.

Minimum useful setup

You can add the SDK gradually. Start with identity, lifecycle, and analytics. Add Buncha Credits, wallet/IAP, entitlements, and ads only when your game design needs those features.

  • Use player.getProfile() for Buncha Games display names and signed-in player ids.
  • Use ready, game.start, pause, resume, and game.end for lifecycle analytics.
  • Use analytics.event(name, payload) for a small number of important in-game moments.
  • Guard every SDK call so local builds and non-Buncha previews still run.

Installable package

Browser games can install @bunchagames/sdk for TypeScript types, a safe facade, local mocks, and engine adapter files. The package delegates to the hosted window.buncha bridge when the game runs on Buncha Games.

The package does not contain secrets, provider credentials, or wallet authority. Your game asks for SDK actions; Buncha Games verifies wallet, receipt, ad callback, and entitlement results.

npm install @bunchagames/sdk

import { buncha, installLocalBunchaMock } from "@bunchagames/sdk";

if (import.meta.env.DEV && !window.buncha) {
  installLocalBunchaMock();
}

buncha.ready();
buncha.game.start({ mode: "arcade" });
buncha.analytics.event("boss_defeated", { bossId: "forest_king" });

Unity and Godot downloads

Unity WebGL projects should use the Buncha Games Unity Package Manager tarball. In Unity, open Package Manager, choose Add package from tarball, and select the downloaded .tgz. This is the preferred Unity path.

Godot Web projects should download the Buncha Games Godot addon ZIP, add the addons/buncha_games_sdk folder to the project, then enable Buncha Games SDK in Project Settings > Plugins. This is the preferred Godot path.

Both engine packages no-op in editors and non-web exports. They expose Buncha Games SDK calls when the game runs inside the platform runtime, but they do not contain secrets or provider-side payment/ad integrations.

Unity UPM tarball:
https://bunchagames.com/sdk/downloads/buncha-games-unity-sdk-0.1.0.tgz

Godot addon ZIP:
https://bunchagames.com/sdk/downloads/buncha-games-godot-sdk-0.1.0.zip

Unity C# example

After installing the Unity package, call the SDK from WebGL builds only. The package no-ops in the Unity Editor and non-WebGL builds.

using BunchaGames;
using UnityEngine;

public class BunchaSdkExample : MonoBehaviour
{
    public void Start()
    {
        BunchaGamesSdk.Ready();
    }

    public void StartRun()
    {
        BunchaGamesSdk.GameStart("{"mode":"arcade"}");
    }

    public void DefeatBoss()
    {
        BunchaGamesSdk.AnalyticsEvent(
            "boss_defeated",
            "{"bossId":"forest_king"}"
        );
    }

    public void FinishRun(int score)
    {
        BunchaGamesSdk.GameEnd("{"score":" + score + "}");
    }
}

Godot example

After enabling the Godot addon, use the BunchaGamesSdk autoload from web exports. It no-ops outside Buncha Games.

func _ready() -> void:
    BunchaGamesSdk.ready()

func start_run() -> void:
    BunchaGamesSdk.game_start({ "mode": "arcade" })

func defeat_boss() -> void:
    BunchaGamesSdk.analytics_event("boss_defeated", {
        "bossId": "forest_king"
    })

func finish_run(score: int) -> void:
    BunchaGamesSdk.game_end({ "score": score })

Lifecycle calls

Use lifecycle calls for game-level moments the wrapper cannot see directly. Successful calls appear in the Developer Analytics SDK Events section.

const buncha = window.buncha ?? window.galaxy;

buncha?.ready?.();
buncha?.game?.start?.({ mode: "arcade" });
buncha?.level?.complete?.("forest_1", { timeSeconds: 84 });
buncha?.analytics?.event?.("boss_defeated", {
  bossId: "forest_king",
  phase: 2
});
buncha?.game?.end?.({ score: 1200 });

Event naming guidance

Use stable, descriptive custom event names such as boss_defeated, area_entered, puzzle_solved, tutorial_step_completed, or item_crafted.

Keep payloads small and use stable keys such as levelId, areaId, mode, bossId, phase, timeSeconds, or attempt.

Do not send names, emails, chat text, secrets, raw save files, auth tokens, precise location, or other personal/private data through SDK analytics.

The developer dashboard summarizes safe low-cardinality payload fields and hides high-cardinality or unsupported fields.

Wrapper launch params

For public share links and read-only deep links, use Buncha Games wrapper URLs as the canonical player-facing links: /play/<game-slug>?tour=<id> or /play/<game-slug>?room=<id>.

Buncha Games forwards only approved launch params from the wrapper URL into the isolated game iframe. The current approved params are tour, room, invite, seed, and mode.

Games should read these values from window.location.search inside the game runtime. Do not rely on arbitrary wrapper query params; auth, debug, tracking, and unrelated page params are intentionally not forwarded.

Hash params are not canonical for shared wrapper links because URL fragments are not sent to the server when the page is requested. Prefer query params for launch state that must be present before the game boots.

// Player-facing share link:
https://bunchagames.com/play/my-game?tour=snapshot-123

// Inside the game runtime:
const params = new URLSearchParams(window.location.search);
const tourId = params.get("tour");

if (tourId) {
  openReadOnlyTour(tourId);
}

Player profile

Games can request the signed-in player's Buncha Games display name through window.buncha.player.getProfile(). The response includes signed-in state, player id, display name, and avatar URL only.

Use the returned display name and player id as the authoritative in-game identity for signed-in players. For signed-out players, keep a local fallback such as a name-entry field.

Never block the first playable moment indefinitely while waiting for the SDK. Show normal local UI while the call is pending, then continue with a guest or unavailable fallback if the SDK does not answer.

Email, auth ids, developer/admin status, private account fields, legal status, monetization eligibility, and payment data are not exposed to games.

const player = await window.buncha?.player?.getProfile?.();
if (player?.signedIn) {
  showPlayerName(player.profile.displayName);
}

Profile integration pattern

Call getProfile before the player starts a run, match, save, or existing game-owned leaderboard submission that needs identity. If the player is signed in, lock the displayed name to the Buncha Games display name so the game does not submit a stale local name.

If the player is signed out or the SDK is unavailable, keep the game playable and use the game's normal local name-entry or guest flow.

This Alpha SDK page does not define a public Buncha Games cloud-save or leaderboard API. Use player profile as SDK-provided signed-in identity for flows your game already owns or that Buncha Games has separately approved.

async function resolveBunchaGamesPlayer() {
  const fallback = { playerId: null, playerName: getLocalPlayerName() };
  const result = await window.buncha?.player?.getProfile?.();

  if (!result?.signedIn || !result.profile) {
    return fallback;
  }

  return {
    playerId: result.profile.id,
    playerName: result.profile.displayName
  };
}

const player = await resolveBunchaGamesPlayer();
startRun({
  playerId: player.playerId,
  playerName: player.playerName
});

submitScore({
  playerId: player.playerId,
  playerName: player.playerName,
  score
});

Unity and engine bridges

Unity, Godot, and other engine builds can deploy on Buncha Games without SDK hooks. Add the engine adapter when you want Buncha Games identity, analytics, Buncha Credits, wallet/IAP, entitlement, or ad features inside the game.

Advanced monetization features

SDK-integrated games can request Buncha Credits wallet summaries, in-game Buncha Credits purchases, receipt and entitlement validation, and approved ad placements when those flows are enabled for the build/account.

Buncha Games owns checkout, wallet state, receipt validation, ad callback validation, and entitlement state. Your game should not infer success from local state, local storage, cookies, or unsigned messages.

Commercial terms are shown during approved monetization onboarding.

Sandbox SDK test mode

When Buncha Games explicitly enables sandbox test mode for an approved build, games can call test-only wallet, IAP, entitlement, and ad SDK methods.

Approved Buncha Games sandbox previews expose the SDK from the platform runtime. Standalone local builds should keep the same guarded window.buncha setup and fail-soft checks described above.

Sandbox methods let approved builds test the same platform-owned wallet, IAP, entitlement, and ad event shapes without creating payable revenue, production entitlements, or payout eligibility.

For in-game balance display, use the label Buncha Credits and render only the SDK wallet summary value. Do not infer balances from receipts, local storage, cookies, or game-owned state.

The game asks; Buncha Games decides. Do not mark purchases, ads, or entitlements successful until the SDK response confirms the platform-owned result.

The game cannot top up Buncha Credits or open checkout itself unless Buncha Games later documents an overlay API for that action. On insufficient credits, show a message, wait for wallet change events, and require the player to click the purchase button again after top-up.

Sandbox entitlements are test-only. Do not persist them as production ownership. On reload, hide locked content unless a Buncha Games sandbox entitlement check returns valid for the expected SKU or receipt.

const buncha = window.buncha ?? window.galaxy;
const sku = "reaction.boost.001";

const wallet = await buncha?.wallet?.getSandboxSummary?.();
if (wallet?.status === "available" && wallet.summary) {
  renderCreditsBadge("Buncha Credits", wallet.summary.totalCredits);
}

const unsubscribe = buncha?.wallet?.onSandboxSummaryChanged?.((walletUpdate) => {
  if (walletUpdate?.status === "available" && walletUpdate.summary) {
    renderCreditsBadge("Buncha Credits", walletUpdate.summary.totalCredits);
    showPurchaseMessage(walletUpdate.message ?? "Buncha Credits available.");
  }
});

const catalog = await buncha?.iap?.getSandboxCatalog?.();
const product = catalog?.products?.find((item) => item.sku === sku);

if (product) {
  const purchase = await buncha?.iap?.requestSandboxPurchase?.({
    sku,
    idempotencyKey: crypto.randomUUID()
  });

  if (purchase?.status === "insufficient_credits") {
    showPurchaseMessage("Add Buncha Credits to continue.");
  } else if (purchase?.status === "committed" && purchase.receipt?.receiptId) {
    const entitlement = await buncha?.iap?.validateSandboxEntitlement?.({
      receiptId: purchase.receipt.receiptId
    });

    if (entitlement?.status === "valid") {
      unlockSandboxItem();
    }
  }
}

const adResult = await buncha?.ads?.requestSandboxPlacement?.({
  placementId: "rewarded_boost_test",
  status: "rewarded"
});
if (adResult?.status === "rewarded") {
  grantTestOnlyAdReward();
}

Sandbox QA checklist

  • Open the approved Buncha Games Sandbox preview for the build while signed in to the right developer or admin account.
  • Confirm the game hides its sandbox test UI when wallet, IAP, or ad sandbox methods are unavailable.
  • Trigger wallet.getSandboxSummary() and confirm the game renders Buncha Credits from the SDK summary only.
  • Trigger an IAP test with a low test balance and confirm the game reports insufficient credits without auto-running the purchase after the player adds Buncha Credits.
  • Add Buncha Credits through the Buncha Games overlay, then confirm wallet.onSandboxSummaryChanged(handler) updates the same in-game balance or status line.
  • Click the purchase button again, validate the receipt with iap.validateSandboxEntitlement(payload), and unlock only after the entitlement response is valid.
  • If the build tests ads, trigger ads.requestSandboxPlacement(payload) and handle rewarded, completed, skipped, unavailable, and error as fake QA statuses only. In sandbox, a requested status is a test scenario selector, not proof of real ad delivery.
  • Compare the in-game status, the sandbox preview event panel, and the admin monetization sandbox log. Counts and statuses should match for the tested wallet, IAP, entitlement, and ad events.

Agent implementation prompt

If you are asking a coding agent to add sandbox wallet, IAP, entitlement, and ad test mode to a game, use /developers/docs/sdk-sandbox-test-prompt. The main SDK page is the human-readable contract; the prompt is a copy-paste implementation checklist that should not require Buncha Games repo context.

Commercial boundaries

  • Wallet, IAP, ad, and Buncha Credits flows require Buncha Games approval for the build/account.
  • Sandbox tests do not create payable revenue, production entitlements, or payout eligibility.
  • Developer commercial terms are shown during approved monetization onboarding.
  • No SDK event triggers automatic promotion, payout, or monetization eligibility.