/** ScorpionAPI contract 1.0.0. Private preview; unavailable to community scripts. */ export type Availability = 'verified' | 'stale' | 'unavailable'; export type RuntimePhase = 'initializing' | 'ready' | 'degraded' | 'unsupported' | 'recovering' | 'stopped'; export type GameState = 'unknown' | 'menu' | 'live' | 'dead' | 'disconnected'; export type Entitlement = 'api.access' | 'api.advanced' | 'developer.tools'; export type ApiEvent = 'state' | 'spawn' | 'death' | 'despawn' | 'connection'; export type NativeKey = 0 | 16 | 32 | 37 | 38 | 39 | 40; export type ApiErrorCode = 'access-denied' | 'disposed' | 'unavailable' | 'invalid-argument' | 'owner-conflict'; export type EntityKey = `${number}:${number}:${number}`; export interface Point { readonly x: number; readonly y: number } export interface Observation { readonly availability: Availability; /** Milliseconds on this game document's performance clock. */ readonly observedAt: number | null; readonly ageMs: number | null; readonly source: 'client-observed'; readonly value: T | null; } export interface Barrel { readonly id: string; readonly durationMs: number; readonly remainingMs: number; readonly progress: number; readonly ready: boolean; readonly reportedAt: number; readonly angle: number | null; } export interface Geometry { readonly radius: number; readonly height: number; readonly sides: number; readonly barWidth: number; readonly healthBarY: number; readonly nameY: number; readonly barTrack: string; } export interface Entity { readonly key: EntityKey; readonly generation: number; readonly kind: 'entity' | 'player' | 'attachment' | 'object' | 'projectile'; readonly x: number | null; readonly y: number | null; readonly renderX: number | null; readonly renderY: number | null; readonly angle: number | null; readonly positionSpace: 'world' | 'parent-local'; readonly positionSource: 'native-current-sample'; readonly positionUpdatedAt: number | null; readonly hp: number | null; readonly maxHp: number | null; readonly hpPercent: number | null; readonly name: string | null; readonly classId: number | null; readonly relation: 'self' | 'ally' | 'enemy' | 'neutral' | null; readonly ownerKey: EntityKey | null; readonly nativeScoreboardId: number | null; readonly geometry: Geometry | null; readonly barrels: readonly Barrel[]; } export interface Player extends Entity { readonly classSource: 'native-client-class'; readonly nativeCursor: Readonly<{ screenX: number; screenY: number; source: 'wasm' }>; readonly nativeScope: Readonly | null; readonly velocity: null; } export interface Camera extends Point { readonly scale: number } export interface GameObservation { readonly phase: RuntimePhase; readonly state: GameState; readonly observedAt: number | null; /** Absence can infer menu/dead state; only native-health establishes the SDK's observed death event. */ readonly stateSource: 'connection' | 'native-health' | 'native-local-player' | 'local-player-absence' | 'unavailable'; readonly clock: 'document-performance'; readonly timeOrigin: number | null; readonly availability: Readonly>; } export interface NetworkState { readonly state: 'unobserved' | 'connecting' | 'open' | 'closed'; readonly connections: number; readonly protocol: 'opaque'; readonly received: number; readonly sent: number; readonly receivedBytes: number; readonly sentBytes: number; } export interface ApiSnapshot { readonly schema: 1; readonly apiVersion: '1.0.0'; readonly game: GameObservation; readonly player: Observation; readonly entities: Observation; readonly camera: Observation; readonly network: NetworkState; readonly provenance: Readonly<{ position: 'native-current-sample'; renderPosition: 'client-interpolation'; health: 'native-client-component'; healthPercent: 'derived'; relation: 'native-team-derived'; reload: 'native-recoil-derived'; velocity: 'unavailable' }>; } export interface Capability { readonly id: string; readonly method: string; readonly entitlement: Entitlement; readonly description: string; readonly authorized: boolean; } export interface ObservedFrame { readonly connection: number; readonly direction: 'in' | 'out'; readonly type: 'text' | 'binary' | 'blob' | 'unsupported'; readonly byteLength: number; readonly at: number; readonly protocol: 'opaque'; /** A new copy for supported binary frames <= 1 MiB; unavailable otherwise. Checks current authorization. */ bytes(): Uint8Array | null; } export interface WasmInfo { readonly profile: string | null; readonly fingerprint: string | null; readonly status: 'loading' | 'compatible' | 'partial' | 'incompatible'; readonly bound: boolean; readonly memoryBytes: number; readonly rawAccess: false; } export interface ScorpionAPI { readonly version: '1.0.0'; capabilities(): readonly Capability[]; readonly game: { getState(): GameObservation; getSnapshot(): ApiSnapshot }; readonly player: { getState(): Observation }; readonly entities: { getState(): Observation }; readonly camera: { getState(): Observation }; readonly input: { /** Canvas backing-pixel aim coordinates; 250 ms lease; physical holds and other owners preserved. */ lease(state: { keys: readonly NativeKey[]; aim?: Point | null }): void; release(): void; }; readonly net: { getState(): NetworkState; onFrame(listener: (frame: ObservedFrame) => void): () => void }; readonly render: { /** Synchronous callback. Canvas state is restored; no asynchronous rendering callbacks. */ onFrame(listener: (context: CanvasRenderingContext2D, snapshot: ApiSnapshot, at: number) => void): () => void; }; readonly events: { on(event: ApiEvent, listener: (snapshot: ApiSnapshot) => void): () => void }; readonly wasm: { getInfo(): WasmInfo }; readonly debug: { getDiagnostics(): Readonly> }; /** Idempotent; releases only this session's input, subscriptions and render callbacks. */ dispose(): void; } export class ScorpionApiError extends Error { readonly code: ApiErrorCode }