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.
- Bounded Runtime Wrapper requests documented for the approved build.
- First-party World launch-context methods when Buncha Games separately authorizes that integration.
Minimum useful setup
You can add the SDK gradually. Start with identity, lifecycle, and a small number of useful analytics events. Approved testers receive separate protected instructions for any additional non-payable Sandbox QA.
- 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.zipUnity 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 creation, tour, coaster, 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.
Approved Buncha Worlds must not trust the forwarded creation value for revision or ownership decisions. Use buncha.world.getLaunchContext() and require the provider revision to match its signed immutableRevisionId.
// 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 closed-beta 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
});Buncha World runtime bridge
Approved Buncha Worlds use player.getAssertion() for audience-scoped account-backed provider actions and world.getLaunchContext() for direct child-creation launches. A neutral Launch World entry returns unavailable launch context and should open the normal World menu.
After the exact provider-resolved immutable creation is ready, call world.creationLoaded(). Use world.openContentHub() only for an explicit exit to Buncha Games discovery; game-owned Back to World, editor, resume, and remix actions stay inside the game.
The optional openContentHub creatorPublicId is a privacy-safe provider ID. Buncha Games validates it and constructs the destination; games cannot supply an arbitrary parent URL.
const launch = await window.buncha?.world?.getLaunchContext?.();
if (launch?.status === "available" && launch.context) {
await openApprovedCreation(
launch.context.publicCreationId,
launch.context.immutableRevisionId
);
window.buncha?.world?.creationLoaded?.();
} else {
openWorldMenu();
}
function exitToBunchaGames() {
window.buncha?.world?.openContentHub?.();
}Unity and engine bridges
Unity, Godot, and other engine builds can deploy on Buncha Games without SDK hooks. Add the engine adapter for approved identity, lifecycle, analytics, or bounded platform integration.
Commercial boundaries
- The SDK does not make commercial systems available.
- There is no current public Credits, wallet, IAP, ad-revenue, developer earnings, revenue-share, or payout program.
- No SDK event triggers automatic publishing, promotion, monetization, earnings, or payout eligibility.
