// @fradiation/sdk types: https://www.fradiation.games/docs/sdk /** Wire protocol between a hosted game (iframe) and the Fradiation site (parent). Versioned; keep it boring. */ export declare const PROTOCOL = "fradiation/0"; export interface Player { handle: string; displayName: string; } /** * Where the game is running: * - live: its public page. Mutations and scores count. * - preview: the developer testing a draft. Calls are checked but not kept. * - playtest: a private playtest link. Calls are logged for the developer, not kept; feedback is open. */ export type Mode = "live" | "preview" | "playtest"; /** game → parent, once, via window.parent.postMessage(…, "*"). Carries nothing sensitive. */ export interface Hello { protocol: typeof PROTOCOL; type: "hello"; sdk: string; } /** parent → game, with a MessagePort transferred (ports[0]). All further traffic uses that port. */ export interface Welcome { protocol: typeof PROTOCOL; type: "welcome"; player: Player | null; /** Added in SDK 0.2. Older sites don't send it; treat missing as "live". */ mode?: Mode; } export type Method = { method: "unlockMutation"; params: { key: string; }; } | { method: "submitScore"; params: { board: string; value: number; }; } /** A named moment for the developer's playtest timeline ("reached level 3"). */ | { method: "track"; params: { name: string; data?: unknown; }; } /** An uncaught error or rejection, captured by the SDK. */ | { method: "error"; params: { message: string; stack?: string; }; } /** Open the site's feedback panel, e.g. at game over. Only playtests have one. */ | { method: "askForFeedback"; params: { prompt?: string; }; }; export type Request = Method & { id: number; }; export interface Response { id: number; ok: boolean; result?: unknown; error?: string; } export interface UnlockResult { /** False when nobody is signed in (the site shows a "get a badge" nudge). */ signedIn: boolean; /** True the first time this player unlocks it. */ unlocked: boolean; } export interface ScoreResult { signedIn: boolean; /** The submission beat the player's previous best. */ isBest: boolean; /** The player's best on this board after this submission. */ best: number | null; /** 1-based position on the board, if known. */ rank: number | null; } export interface FeedbackResult { /** True when the site opened its feedback panel (playtests only). */ opened: boolean; } /** * @fradiation/sdk — the only thing a game needs to talk to Fradiation Games. * * import { fradiation } from "./fradiation-sdk.mjs"; // https://www.fradiation.games/sdk/fradiation-sdk.mjs * const session = await fradiation.ready(); // { connected, player, mode } * fradiation.unlockMutation("first-blood"); // achievements, defined in fradiation.json * fradiation.submitScore("high-score", 12345); // scoreboards, defined in fradiation.json * fradiation.track("reached-level", { level: 3 }); // playtest timeline * fradiation.askForFeedback("How was that boss?"); // opens the feedback panel in playtests * * Once connected, uncaught errors are reported too, so playtest crashes reach the developer. * Outside the site (local dev, itch, anywhere) every call resolves harmlessly, so games never need to check. * Security: the game only ever talks through a MessagePort handed over by a parent on an allowlisted origin. */ export declare const VERSION = "0.2.0"; /** Sites allowed to host games. Anything else framing the game is ignored. */ export declare const PORTAL_ORIGINS: string[]; export interface Session { connected: boolean; player: Player | null; /** "live" on the public page, "preview" for a developer's draft, "playtest" on a private test link. */ mode: Mode; } export declare const fradiation: { VERSION: string; /** Handshake with the site. Safe to call many times; resolves within ~1.5 s even when standalone. */ ready(timeoutMs?: number): Promise; /** Unlock a mutation declared in fradiation.json. Idempotent. */ unlockMutation(key: string): Promise; /** Submit a score to a board declared in fradiation.json. The site keeps each player's best. */ submitScore(board: string, value: number): Promise; /** Mark a moment for the playtest timeline: "died", "reached-level" { level: 3 }. Ignored outside playtests. */ track(name: string, data?: unknown): void; /** Ask the player for feedback now (e.g. at game over). Opens the site's panel in playtests; otherwise resolves { opened: false }. */ askForFeedback(prompt?: string): Promise; }; export default fradiation;