# erebo.si SDK — AI Integration Instructions Authoritative current manifest: https://www.3js.games/sdk/latest.json Official documentation: https://www.3js.games/docs ## Required integration process 1. Read latest.json first. 2. Use the recommended version from the manifest. 3. Fetch the official SDK from sdkUrl. 4. Vendor the artifact unchanged into the game. 5. Verify its SHA-256 against the manifest. 6. Load the vendored SDK before application code. 7. Use only the documented ThreeJSGames namespace. 8. Keep standalone gameplay functional. 9. Build the distributable output and create the final upload-ready ZIP. Recommended vendored location: ./3jsgames-sdk/v4/3jsgames.js Recommended browser load pattern: Do not recreate, modify, minify, transpile, or bundle the SDK into application code. Do not use Supabase directly, private erebo.si APIs, raw window.parent, game-owned raw postMessage integration, auth tokens, credentials, internal player IDs, or hardcoded game IDs. The unchanged SDK v4 artifact automatically performs the platform-ready handshake and emits at most one qualifying pointer, touch, keyboard, or gamepad interaction signal to the trusted parent player. Iframe load alone is not a play. Games do not send IDs, timestamps, durations, or analytics credentials. ## Player Identity Beta Call ThreeJSGames.player.getProfile() with no arguments. It resolves with exactly: { username: "example", avatar: { type: "emoji", value: "🎮" }, isPremium: false } avatar.type is "image" or "emoji". Render image values with an img element (crossOrigin="anonymous" for canvas use), and emoji values with textContent. Use textContent for username and a visible Premium badge when isPremium is true. If an image fails, show 🎮. Never use innerHTML for profile values. The current SDK returns a frozen profile and avatar. Each getProfile() call reads the current public setting without caching. Call on lobby/HUD entry or an explicit refresh, never every frame. isPremium is a server-derived display flag, not authorization. Do not treat identity copied into multiplayer state by another game client as verified. Older vendored SDKs keep their username-only result; existing code using player.username remains compatible. Treat signed-out players as normal gameplay guests. AUTH_REQUIRED means the player is signed out. PLAYER_UNAVAILABLE means identity is unavailable. Do not block gameplay on identity, and do not treat a username as authorization or a permanent identifier. ## Cloud Storage The public methods are: - ThreeJSGames.storage.get(key) - ThreeJSGames.storage.set(key, value) - ThreeJSGames.storage.delete(key) - ThreeJSGames.storage.isAvailable() Storage is scoped to the authenticated account and current game by trusted platform context. Games never supply account or game identifiers. Handle AUTH_REQUIRED, STORAGE_UNAVAILABLE, and REQUEST_TIMEOUT without breaking gameplay. isAvailable() reports platform integration availability, not authentication. For acceptance or reference integrations, expose ordinary non-sensitive UI that makes persistence testable without internal APIs. Show at least Cloud status, the loaded persisted value or state, and whether the current state came from cloud, standalone fallback, or a fresh default. A useful game fixture can expose Best score and Games played. Verify an authenticated save, reload in the same browser, and the same account in a second browser or device where practical. ## Leaderboards Beta The public methods are: - ThreeJSGames.leaderboards.isAvailable() - ThreeJSGames.leaderboards.submit(key, score) - ThreeJSGames.leaderboards.getTop(key, { limit }) - ThreeJSGames.leaderboards.getPersonal(key) Keys must match a leaderboard configured by the creator; SDK calls do not create leaderboard definitions. Submit a JavaScript safe-integer score generally once, at final game-over. Handle AUTH_REQUIRED, LEADERBOARD_NOT_AVAILABLE, LEADERBOARD_UNAVAILABLE, and REQUEST_TIMEOUT without discarding results or breaking gameplay. ## Multiplayer SDK Beta Multiplayer is Beta for small-session browser games; limits and behavior may evolve. The creator requires Premium Creator AND operator-approved creator/game pilot access. Ordinary signed-in players need no Premium or creator allowlisting. Handle MULTIPLAYER_UNAVAILABLE when new admissions are paused or outside the pilot. Active sessions keep their existing grace/TTL. Use only: - ThreeJSGames.multiplayer.createRoom({ visibility, mode, maxPlayers }) - ThreeJSGames.multiplayer.isAvailable() — synchronous cached server hint, initially false while checking; not authorization - ThreeJSGames.multiplayer.joinRoom({ code }) - ThreeJSGames.multiplayer.quickMatch({ mode, maxPlayers }) - room.on(eventName, handler) - room.setPlayerState(state) - room.setSharedState(state) when room.isHost - room.send(name, payload) - room.startMatch(), room.finalizeMatch({ winnerId }), and room.leave() Never connect to Supabase, handle credentials, derive channel topics, supply player/game IDs, claim Premium status, choose host authority, or write ratings. Network state is limited to 15 updates/second and is not rendering FPS; interpolate remote state locally in requestAnimationFrame. Custom events are server-acknowledged live broadcasts, not durable or exactly-once delivery. Host authority and host-reported match results are suitable only for casual games and are not cheat-proof. Read the complete contract at https://www.3js.games/docs/sdk/multiplayer before implementation. ## Frame and lifecycle safety Never initiate SDK or other network-backed operations from a requestAnimationFrame, update, render, or per-frame call stack. Detect the terminal condition, freeze an immutable per-run result, synchronously transition the game to GAME_OVER, then queue persistence across a post-frame microtask or equivalent event/task boundary. Guard duplicate completion. Leaderboard submission, Cloud Storage writes, and personal-rank requests are asynchronous enhancements and must never control whether GAME_OVER appears. ## Upload-ready packaging When completing an integration, inspect the project's build system and produce its distributable/static output when required. Verify that index.html is at the ZIP root, all runtime paths work on static hosting, and the unchanged vendored official SDK is present in the distributable with the manifest SHA-256. Create the final ZIP yourself and report its path and contents. Do not assume one build command applies to every game. ## Fallback principle erebo.si platform features enhance gameplay but must not make standalone gameplay dependent on the platform. Branch on stable error.code values rather than message text, and keep guest, unavailable, timeout, and other error paths playable.