@bunchagames/sdk
v0.9.0
Published
Buncha Games browser SDK facade, types, mocks, and engine adapters.
Readme
Buncha Games SDK
@bunchagames/sdk is a small facade for approved browser games running on Buncha Games.
In Buncha Games Sandbox and public play, the platform runtime exposes window.buncha. This package gives web games typed helpers, local mocks, and engine adapter files for development. It does not contain secrets and does not grant production monetization access.
Web usage
Putts publication (0.9.0 candidate; not yet released)
buncha.world.publications.uploadMedia accepts exact provider snapshot references,
the expected signed-in player, base MIME, SHA-256 and an ArrayBuffer. It uploads
one bounded image or orbit video without exposing credentials or provider URLs.
submit uses the same identity plus a persisted request UUID and returns a
pending-moderation receipt, never a public-success claim. Retry uncertain requests
with identical IDs/bytes. Do not run these methods during ordinary gameplay.
Keep local drafts on failure; missing hosted support and local mocks fail unavailable.
See the issued Putts publication handoff for the complete capture/retry sequence.
Putts immutable sharing (0.8.0)
Package availability does not enable the hosted service. Version 0.8.0 adds
optional leaderboards.ingestHoleSnapshot,
getPublishedHoleSnapshot, getShareChallengeContext, getCurrentShareChallenge,
createOrReplaceShareChallenge, getShareChallengeBoard,
getOwnShareChallengeRank, and submitShareChallengeResult.
Ingest only on an explicit save-for-sharing/publishing action, not autosave.
Use the provider's returned hole/snapshot IDs, never locally invented public IDs.
Creating/replacing a Friends challenge is an explicit creator action; replacement
revokes its previous link and starts a new all-time board. The platform handles
the private link capability outside the iframe. Recipients use the exact snapshot
returned by getShareChallengeContext; no draft/latest fallback is permitted.
Submit only completed holes in the background, preserving the same request UUID, account, challenge and evidence for bounded retries. Pending local presentation is not a confirmed rank. Guests may play/read but not submit account scores. Friends access never grants publication or weekly Global eligibility. Missing or disabled hosted support returns unavailable; local mock receipts do not prove hosted acceptance. Follow the issued platform handoff before uploading a build.
Putts weekly Global boards (0.7.0)
Optional leaderboards.getHoleLeaderboardCapabilities, getHoleBoard,
getOwnHoleRank, and submitHoleResult use a canonical Published-hole ID.
Global boards are weekly (Monday 00:00 UTC), ranked by strokes then client-measured
elapsed milliseconds. Send one completed result in the background; never wait
before gameplay or send per-shot updates. Unpublished/Friends holes are excluded.
Both server gates remain disabled until the approved provider and hosted release
are ready. Missing capability is unavailable, not a successful mock submission.
The exact candidate/release status is in platform documentation:
docs/development/PUTTS_GLOBAL_IMPLEMENTATION.md.
Existing facade
import { buncha, installLocalBunchaMock } from "@bunchagames/sdk";
if (import.meta.env?.DEV && !globalThis.window?.buncha) {
installLocalBunchaMock();
}
buncha.ready();
buncha.game.start({ mode: "arcade" });
buncha.analytics.event("boss_defeated", { bossId: "forest_king" });
buncha.game.end({ score: 1200 });Initial loading (GLD-001, 0.4.0)
Participating builds put data-buncha-loading="1" on their root <html> and
use module/deferred scripts or body script placement. Runtime installs the
shared loading surface before game initialization. Builds without opt-in keep
their existing presentation. A compressed entry HTML is not eligible; compressed
game assets remain supported.
const loading = buncha.loading; // undefined without supporting Runtime hooks
if (loading) {
hideGameOwnedInitialLoader(); // keep its real asset/readiness work
loading.start({ stages: [
{ key: "downloading", weight: 70 },
{ key: "preparing", weight: 30 }
] });
}
// Feed actual byte/item counts. Unknown totals hold; never advance with a timer.
loading?.update({ stage: "downloading", completed: bytesRead, total: knownBytes });
loading?.completeStage("preparing");
// Only when essential content, scene/menu and input are usable:
loading?.ready();completeStage, update, and ready are separate from the existing
buncha.ready() analytics signal. Subsequent theme/level transitions keep their
game-owned presentation. Supported failure codes for loading.fail({code}) are
network, graphics, content, and initialization. Platform owns thumbnails,
appearance and contextual Retry; no credentials, title or image URL belong in
progress messages. Local mocks share the same progress rules but do not prove
hosted readiness. Verify progress and usable input on the exact hosted Sandbox
build before requesting the existing human review and promotion.
Player profile
import { buncha } from "@bunchagames/sdk";
const player = await buncha.player.getProfile();
if (player.signedIn) {
showPlayerName(player.profile.displayName);
}Sandbox test mode
Sandbox wallet, IAP, entitlement, and ad test methods are optional and fake/non-payable. Check that the method exists before showing test UI.
const wallet = await buncha.wallet?.getSandboxSummary?.();
const catalog = await buncha.iap?.getSandboxCatalog?.();Engine packages
- Unity WebGL: use the Buncha Games Unity Package Manager tarball from the public SDK docs.
- Godot Web: use the Buncha Games Godot addon ZIP from the public SDK docs.
The engine packages no-op outside web exports. The adapter files in this npm package are kept as reference copies for agents and advanced users, but the engine-native downloads are the recommended path.
Private immutable Share Drafts (World Provider Contract V1.2)
V1.2 Worlds can ask the parent wrapper to construct a canonical private link after their provider has created an immutable snapshot. Games provide only the one-time capability; they cannot choose a platform origin or destination.
const result = await buncha.world.createPrivateDraftShareUrl({ capability });Recipients inspect getLaunchContext(). When its type is
private_draft_share, enter a read-only viewer, request
getLaunchAssertion(), resolve the exact snapshot from the provider using the
assertion as an Authorization header, and call privateDraftLoaded() only
after that snapshot renders. Normal player assertions, edits, publishing,
social actions, reports, camera/microphone, and monetization remain unavailable
in this mode.
Optional capabilities (0.4.0)
Immediate play / completed results (0.6.0 candidate)
leaderboards.submitCompletedRound({requestId, expectedPlayerId, day, rulesId,
outcomes}) submits a completed five-throw Lawn Darts round without a server start
or allowance. Use the existing profile id as expectedPlayerId (an account
precondition, not authority), a stable completed-round UUID, the played UTC date,
reviewed rules, and five ordered evidence objects. Server validation determines
scores. Exact retries return the original receipt; new historical submissions
are rejected. See platform docs/development/LBD_COMPLETED_ROUNDS.md.
Play is unlimited and local. Abandon/reload discards unfinished play; no resume,
reservation, refund or per-throw requests. Save completed rounds in the background
without blocking the next round. Show the player's improved local best immediately
as pending, separately from a confirmed score/rank. Never invent a confirmed rank
or move a guest/account result into another account. Capabilities advertise
supportsCompletedRound and completedRoundDailyLimit:null; fetching them must
not delay Play. An unavailable backend is not a successful save.
Legacy limited-round correction (0.5.0)
SDK 0.5.0 added leaderboards.startRound, submitRound, and recoverRound.
Use these only after the official distribution/release receipt and when
getCapabilities().supportsSubmitRound is true; method presence alone is not
service availability. See docs/development/GLD-LBD_ROUND_CORRECTION.md in the
platform repository for the authoritative contract.
The following is historical compatibility for existing builds, NOT the current Lawn Darts integration policy. Start consumes one try on explicit player intent. Restore local throw checkpoints against the active account round before enabling Play/Resume. Play all five throws without per-throw networking; submit the completed evidence batch in the background with a stable retry ID. If an incomplete round cannot be restored, recoverRound returns its try once, then a new startRound can replace it. This does not refund completed rounds or create a separate practice mode. Existing startRun/submitOutcome methods retain legacy behavior for older builds.
The additive GLD/LBD interfaces are documented in the platform repository's
docs/development/GLD-001_LOADING_CONTRACT.md and
docs/development/LBD-001_SDK_CONTRACT.md. Version 0.3.0 does not include these
interfaces. Runtime/hosted SDK loading support is deployed; adopting it remains
opt-in per build. SDK availability and service enablement are separate:
leaderboard calls return unavailable until the platform enables that Game and
context. Never interpret the presence of the facade as permission to submit.
World cloud-draft foundation (0.3.0)
The additive buncha.world.cloudDrafts namespace is present in the repository
source and published npm package. It remains feature-off for every provider.
The local mock returns unavailable unless a future test explicitly
supplies an approved persistence adapter; it never claims that an in-memory
value survived a reload.
When an eligible World is eventually issued the capability, signed-out local
drafts use readLocal, writeLocal, and deleteLocal. Account claim uses
beginAccountClaim followed, after same-tab login reload, by the one-time
consumeAccountClaimContinuation. Provider cloud calls use a separate
least-privilege assertion from getAssertion({ access: "read" | "write" }).
The provider remains authoritative for account-owned mutable projects.
