Skip to main content

@eigeninteractive/server

@eigeninteractive/server: everything that deploys, being the createEngine API factory, the GameDO base class, the D1 applier, and the protocol types.

The D1 and Durable Object table definitions are deliberately NOT exported. They are engine-owned storage internals that migrate on their own schedule, and readGameRow already returns the whole game row typed. Exporting the drizzle tables would turn a private layout into a compatibility surface.

Classes​

AuthError​

Defined in: server/packages/server/src/auth/firebase.ts:12

Verification failure, always the caller's fault; the app maps it to 401.

Extends​

  • Error

Constructors​

Constructor​
new AuthError(message?): AuthError;

Defined in: web/node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1080

Parameters​
ParameterType
message?string
Returns​

AuthError

Inherited from​

Error.constructor

Constructor​
new AuthError(message?, options?): AuthError;

Defined in: web/node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1080

Parameters​
ParameterType
message?string
options?ErrorOptions
Returns​

AuthError

Inherited from​

Error.constructor


abstract BaseGameDO​

Defined in: server/packages/server/src/do/game-do.ts:117

Durable Object base class that owns one authoritative game session.

A game Worker subclasses this once to supply its gameModule and D1 binding. Do not override command, socket, alarm, or persistence behavior: the base class owns the serialized game loop and applies engine migrations on activation.

Example​

export class GameDO extends BaseGameDO<Env> {
protected readonly gameModule = gameModule;
protected d1(env: Env) {
return env.GAME_DB;
}
}

Extends​

  • DurableObject<TEnv>

Type Parameters​

Type Parameter
TEnv

Implements​

  • GameStub

Constructors​

Constructor​
new BaseGameDO<TEnv>(ctx, env): BaseGameDO<TEnv>;

Defined in: server/packages/server/src/do/game-do.ts:131

Parameters​
ParameterType
ctxDurableObjectState
envTEnv
Returns​

BaseGameDO<TEnv>

Overrides​

DurableObject<TEnv>.constructor

Properties​

gameModule​
abstract protected readonly gameModule: GameModule;

Defined in: server/packages/server/src/do/game-do.ts:119

The implementor's game: the versions map the engine dispatches on.

Methods​

abort()​
abort(gameId): Promise<void>;

Defined in: server/packages/server/src/do/game-do.ts:390

Unconditional teardown (cron reap): mark the game aborted in D1 and compact its game data, with no creator gate or init requirement. A never-touched lobby's DO has no meta row, so the caller passes the gameId. Idempotent; cancel shares the teardown for its live path.

Parameters​
ParameterType
gameIdstring
Returns​

Promise<void>

Implementation of​

GameStub.abort

alarm()​
alarm(): Promise<void>;

Defined in: server/packages/server/src/do/game-do.ts:949

A timeout is derived from committed state, not submitted, so it carries no caller identity. It is idempotent because the kernel abstains once the state it was derived from has moved on, so a double fire, a retry after an alarm handler throws, and a race with a latent on-time action all resolve the same way. handle() re-arms the alarm for the next turn on its way out.

Returns​

Promise<void>

Overrides​

DurableObject.alarm

d1()​
abstract protected d1(env): D1Database;

Defined in: server/packages/server/src/do/game-do.ts:122

The EngineConfig seam: the engine never assumes binding names, so the subclass picks the D1 database off its own Env.

Parameters​
ParameterType
envTEnv
Returns​

D1Database

fetch()​
fetch(request): Promise<Response>;

Defined in: server/packages/server/src/do/game-do.ts:963

The worker routes the upgrade here after authenticating; the principal header is worker-set (never client-supplied; the worker strips inbound headers when forwarding). One socket serves the game's whole lifetime and carries one message kind, the per-seat SessionSnapshot. A not-yet-seated user's socket receives the envelope with no frame until the roster contains them, which is how it learns the game started at all.

Parameters​
ParameterType
requestRequest
Returns​

Promise<Response>

Implementation of​

GameStub.fetch

Overrides​

DurableObject.fetch

firebaseAdmin()​
protected firebaseAdmin(env): FirebaseAdminEffects;

Defined in: server/packages/server/src/do/game-do.ts:125

Required Firebase Admin effects. Tests override this with the explicit fake exported by @eigeninteractive/server/testing.

Parameters​
ParameterType
envTEnv
Returns​

FirebaseAdminEffects

frames()​
frames(args): Promise<FrameMessage[]>;

Defined in: server/packages/server/src/do/game-do.ts:1154

Project a version range for one seat (null = public viewer, replay only). Live rows serve the stored frame; compacted/ratings rows re-project. Raw state never leaves the DO.

Parameters​
ParameterType
args{ from: number; isReplay?: boolean; seat: number | null; to: number; }
args.fromnumber
args.isReplay?boolean
args.seatnumber | null
args.tonumber
Returns​

Promise<FrameMessage[]>

Implementation of​

GameStub.frames

handle()​
handle(cmd): Promise<CommandResult>;

Defined in: server/packages/server/src/do/game-do.ts:144

Parameters​
ParameterType
cmdSingleCommand
Returns​

Promise<CommandResult>

Implementation of​

GameStub.handle

localRecord()​
localRecord(
gameId,
from,
to
): Promise<LocalRecord | null>;

Defined in: server/packages/server/src/do/game-do.ts:267

A local game's stored log: raw state and the action that produced it, plus the seed they were all derived from.

This is the one place raw state leaves the object, and it is safe for the same reason it is useful: a local game has exactly one human, the caller, who played every one of these transitions on their own device and still holds them there. There is no other participant for the disclosure to be against. The origin gate is restated here rather than trusted from the route, because "raw state never leaves the DO" is worth guarding at the object that owns it.

Parameters​
ParameterType
gameIdstring
fromnumber
tonumber
Returns​

Promise<LocalRecord | null>

Implementation of​

GameStub.localRecord

localTransitions()​
localTransitions(cmd): Promise<LocalBatchResult>;

Defined in: server/packages/server/src/do/game-do.ts:190

Import a run of a local game's transitions, in order, under one gate entry.

The device already played these against the Dart twin of these rules; this replays them through the authoritative ones, so the server's copy is produced by the TypeScript rules and a disagreement surfaces as a rejection rather than being taken on trust. Each transition commits through exactly the live action/forfeit path — same guards, same frames, same log — so an imported game is indistinguishable from a played one afterwards.

Three things differ, and only three: the whole run is one request, the per-commit D1 summary mirror is collapsed into one write at the end (a hundred-move game would otherwise cost a hundred round trips for a row nothing reads until it settles), and the first rejection stops the batch and is REPORTED rather than thrown, because everything before it is already committed and permanent.

Parameters​
ParameterTypeDescription
cmd{ actor: Principal; fromVersion: number; gameId: string; kind: "local-transitions"; transitions: LocalTransition[]; }-
cmd.actorPrincipalThe game's creator: the only principal a local game has.
cmd.fromVersionnumberThe version the device believes the server is at. The import is append-only, so a mismatch means another device already appended and this batch is refused whole (stateUpdated).
cmd.gameIdstring-
cmd.kind"local-transitions"Import a run of a local game's transitions into the authoritative object, in order, as one request. A batch rather than one command per transition because a finished local game is a whole transcript: sending it move by move would cost a Worker and a Durable Object request each, and would let a client stop halfway through with the server's copy in a state the device never saw.
cmd.transitionsLocalTransition[]-
Returns​

Promise<LocalBatchResult>

Implementation of​

GameStub.localTransitions

reconcile()​
reconcile(gameId): Promise<ReconcileReport>;

Defined in: server/packages/server/src/do/game-do.ts:913

Re-derive D1's read model from this object's committed state, and finish any post-commit work that never landed.

The repair counterpart to the fire-and-forget mirror. #mirrorD1 writes the roster/summary rows off the response path and gives up after its retries, because a commit whose truth is already durable must not fail on a read model — which leaves D1 stale with nothing to notice. Likewise a finish whose D1 apply failed keeps its outbox row precisely so this can retry it. Both are the same defect from D1's side (a game that stopped being updated), and both are fixed by the same act: write what the DO knows.

Deliberately does NOT lazy-init. Lazy init reads the games row from D1, so an object with no meta has nothing more authoritative than the row it would be repairing — reconciling it would read the stale copy and write it straight back, reporting success. No meta row means this object never committed anything, and the answer is honestly "nothing to reconcile".

The writes here are awaited, unlike the post-commit mirror: a repair that failed silently is worse than no repair, because the operator or sweep that asked for it would believe the divergence was resolved.

Idempotent, so a sweep may call it on a healthy game: the mirror is rewritten to the same values, repokeFinish reports nothing to do, and the alarm already matches.

Parameters​
ParameterType
gameIdstring
Returns​

Promise<ReconcileReport>

Implementation of​

GameStub.reconcile

session()​
session(gameId, userId): Promise<SessionSnapshot | null>;

Defined in: server/packages/server/src/do/game-do.ts:986

The snapshot over RPC, for the HTTP paths that have no socket.

Parameters​
ParameterType
gameIdstring
userIdstring | null
Returns​

Promise<SessionSnapshot | null>

Implementation of​

GameStub.session

webSocketClose()​
webSocketClose(): Promise<void>;

Defined in: server/packages/server/src/do/game-do.ts:999

Returns​

Promise<void>

Overrides​

DurableObject.webSocketClose

webSocketError()​
webSocketError(_ws, error): Promise<void>;

Defined in: server/packages/server/src/do/game-do.ts:1005

Parameters​
ParameterType
_wsWebSocket
errorunknown
Returns​

Promise<void>

Overrides​

DurableObject.webSocketError

webSocketMessage()​
webSocketMessage(ws): Promise<void>;

Defined in: server/packages/server/src/do/game-do.ts:991

Parameters​
ParameterType
wsWebSocket
Returns​

Promise<void>

Overrides​

DurableObject.webSocketMessage


CommercialLimitWriteError​

Defined in: server/packages/server/src/d1/apply.ts:407

Extends​

  • Error

Constructors​

Constructor​
new CommercialLimitWriteError(message?): CommercialLimitWriteError;

Defined in: web/node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1080

Parameters​
ParameterType
message?string
Returns​

CommercialLimitWriteError

Inherited from​

Error.constructor

Constructor​
new CommercialLimitWriteError(message?, options?): CommercialLimitWriteError;

Defined in: web/node_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1080

Parameters​
ParameterType
message?string
options?ErrorOptions
Returns​

CommercialLimitWriteError

Inherited from​

Error.constructor


HttpError​

Defined in: server/packages/server/src/http.ts:56

Extends​

  • Error

Constructors​

Constructor​
new HttpError(
status,
message,
code?,
retryAfterSeconds?
): HttpError;

Defined in: server/packages/server/src/http.ts:64

Parameters​
ParameterType
status400 | 401 | 403 | 404 | 409 | 413 | 415 | 422 | 429 | 500 | 502
messagestring
code?ErrorCode
retryAfterSeconds?number
Returns​

HttpError

Overrides​

Error.constructor

Properties​

code​
readonly code: ErrorCode | undefined;

Defined in: server/packages/server/src/http.ts:58

retryAfterSeconds​
readonly retryAfterSeconds: number | undefined;

Defined in: server/packages/server/src/http.ts:62

Seconds the caller should wait before retrying, rendered as the Retry-After header. Set only on a 429 (see ErrorCode.rateLimited); undefined everywhere else.

status​
readonly status: 400 | 401 | 403 | 404 | 409 | 413 | 415 | 422 | 429 | 500 | 502;

Defined in: server/packages/server/src/http.ts:57

Interfaces​

AccessGrant​

Defined in: server/packages/server/src/commerce/types.ts:34

Permissions, content ownership, and limits contributed by one source.

Extended by​

Properties​

content?​
content?: readonly ContentGrant[];

Defined in: server/packages/server/src/commerce/types.ts:36

limits?​
limits?: readonly CommercialLimit[];

Defined in: server/packages/server/src/commerce/types.ts:37

permissions?​
permissions?: readonly EngineAccessCapability[];

Defined in: server/packages/server/src/commerce/types.ts:35


AccessSnapshot​

Defined in: server/packages/server/src/commerce/types.ts:236

Properties​

content​
content: ContentGrant[];

Defined in: server/packages/server/src/commerce/types.ts:239

entitlements​
entitlements: ActiveEntitlement[];

Defined in: server/packages/server/src/commerce/types.ts:237

limits​
limits: LimitAccess[];

Defined in: server/packages/server/src/commerce/types.ts:240

permissions​
permissions: EngineAccessCapability[];

Defined in: server/packages/server/src/commerce/types.ts:238


AuthClaims​

Defined in: server/packages/server/src/auth/firebase.ts:18

What a verified ID token asserts. isAnonymous (the firebase.sign_in_provider === 'anonymous' claim) drives every guest gate; the profile claims seed user provisioning (Google supplies name/picture, Apple usually only email, guests none).

Properties​

email​
email: string | null;

Defined in: server/packages/server/src/auth/firebase.ts:21

isAnonymous​
isAnonymous: boolean;

Defined in: server/packages/server/src/auth/firebase.ts:20

name​
name: string | null;

Defined in: server/packages/server/src/auth/firebase.ts:22

picture​
picture: string | null;

Defined in: server/packages/server/src/auth/firebase.ts:23

uid​
uid: string;

Defined in: server/packages/server/src/auth/firebase.ts:19


CommerceCatalog​

Defined in: server/packages/server/src/commerce/types.ts:63

Properties​

botTiers?​
botTiers?: Readonly<Record<string, string>>;

Defined in: server/packages/server/src/commerce/types.ts:70

The bots priced differently from the rest, by registered bot id. Every bot this does not list is in standard (DEFAULT_BOT_TIER).

content?​
content?: Readonly<Record<string, Readonly<Record<string, ContentDefinition>>>>;

Defined in: server/packages/server/src/commerce/types.ts:67

entitlements​
entitlements: readonly EntitlementDefinition[];

Defined in: server/packages/server/src/commerce/types.ts:65

free​
free: AccessGrant;

Defined in: server/packages/server/src/commerce/types.ts:64

offers​
offers: readonly CommerceOffer[];

Defined in: server/packages/server/src/commerce/types.ts:66


CommerceCheckout​

Defined in: server/packages/server/src/commerce/types.ts:113

Properties​

expiresAt?​
expiresAt?: number;

Defined in: server/packages/server/src/commerce/types.ts:116

Provider session expiry in epoch milliseconds, when known.

providerAccountId?​
providerAccountId?: string;

Defined in: server/packages/server/src/commerce/types.ts:118

Returned when checkout created or resolved a provider customer.

url​
url: string;

Defined in: server/packages/server/src/commerce/types.ts:114


CommerceConfig​

Defined in: server/packages/server/src/commerce/types.ts:195

Type Parameters​

Type Parameter
TEnv

Properties​

catalog​
catalog: CommerceCatalog;

Defined in: server/packages/server/src/commerce/types.ts:196

now?​
now?: () => number;

Defined in: server/packages/server/src/commerce/types.ts:199

Test seam. Production uses Date.now.

Returns​

number

providers​
providers: readonly CommerceProvider<TEnv>[];

Defined in: server/packages/server/src/commerce/types.ts:197

reconcileBatch?​
reconcileBatch?: number;

Defined in: server/packages/server/src/commerce/types.ts:201

Maximum nonterminal transactions checked per provider and invocation.

reconcileMaxFailures?​
reconcileMaxFailures?: number;

Defined in: server/packages/server/src/commerce/types.ts:204

Consecutive failed sweeps after which a transaction stops being swept and is surfaced to the operator instead. Defaults to 10.


CommerceManagement​

Defined in: server/packages/server/src/commerce/types.ts:121

Properties​

url​
url: string;

Defined in: server/packages/server/src/commerce/types.ts:122


CommerceOffer​

Defined in: server/packages/server/src/commerce/types.ts:45

Properties​

description​
description: string;

Defined in: server/packages/server/src/commerce/types.ts:49

entitlements​
entitlements: readonly string[];

Defined in: server/packages/server/src/commerce/types.ts:51

key​
key: string;

Defined in: server/packages/server/src/commerce/types.ts:47

Stable logical key used by clients and analytics.

kind​
kind: "oneTime" | "subscription";

Defined in: server/packages/server/src/commerce/types.ts:50

name​
name: string;

Defined in: server/packages/server/src/commerce/types.ts:48

providerReferences​
providerReferences: Readonly<Record<string, string>>;

Defined in: server/packages/server/src/commerce/types.ts:60

Public, provider-owned sellable references. The engine treats each value as opaque; the matching adapter defines its form -- a Stripe Price, a Razorpay Plan, a Google Play product id, or a Play subscription's {productId}:{basePlanId}. Secret credentials remain in bindings.

repeatable?​
repeatable?: boolean;

Defined in: server/packages/server/src/commerce/types.ts:53

Defaults to false. Enable only for intentionally repeatable support/tip offers.


CommerceProduct​

Defined in: server/packages/server/src/commerce/types.ts:107

Properties​

currencyCode?​
currencyCode?: string;

Defined in: server/packages/server/src/commerce/types.ts:110

displayPrice​
displayPrice: string;

Defined in: server/packages/server/src/commerce/types.ts:109

providerReference​
providerReference: string;

Defined in: server/packages/server/src/commerce/types.ts:108


CommerceProvider​

Defined in: server/packages/server/src/commerce/types.ts:171

A provider boundary. Implementations perform all remote verification.

Extended by​

Type Parameters​

Type ParameterDefault type
TEnvunknown

Properties​

key​
readonly key: string;

Defined in: server/packages/server/src/commerce/types.ts:172

Methods​

acknowledge()?​
acknowledge?(env, transaction): Promise<void>;

Defined in: server/packages/server/src/commerce/types.ts:190

Runs only after the normalized transaction and grants commit.

Parameters​
ParameterType
envTEnv
transactionCommerceTransactionReference
Returns​

Promise<void>

createCheckout()?​
createCheckout?(env, input): Promise<CommerceCheckout>;

Defined in: server/packages/server/src/commerce/types.ts:191

Parameters​
ParameterType
envTEnv
inputCreateCheckoutInput
Returns​

Promise<CommerceCheckout>

management()?​
management?(
env,
accountId,
providerAccountId,
returnUrl
): Promise<CommerceManagement>;

Defined in: server/packages/server/src/commerce/types.ts:192

Parameters​
ParameterType
envTEnv
accountIdstring
providerAccountIdstring
returnUrlstring
Returns​

Promise<CommerceManagement>

products()?​
products?(env, providerReferences): Promise<readonly CommerceProduct[]>;

Defined in: server/packages/server/src/commerce/types.ts:179

Parameters​
ParameterType
envTEnv
providerReferencesreadonly string[]
Returns​

Promise<readonly CommerceProduct[]>

reconcile()?​
reconcile?(env, transactions): Promise<readonly VerifiedCommerceTransaction[]>;

Defined in: server/packages/server/src/commerce/types.ts:188

Fetches current state for locally active or pending transaction refs.

Parameters​
ParameterType
envTEnv
transactionsreadonly CommerceTransactionReference[]
Returns​

Promise<readonly VerifiedCommerceTransaction[]>

validateReference()?​
validateReference?(providerReference, kind): void;

Defined in: server/packages/server/src/commerce/types.ts:178

Throws when a catalog reference cannot name anything this provider sells as an offer of kind. Called for every offer at createEngine, so a misspelt reference is a deploy failure rather than a refused purchase.

Parameters​
ParameterType
providerReferencestring
kind"oneTime" | "subscription"
Returns​

void

verifyClaim()​
verifyClaim(env, input): Promise<VerifiedCommerceTransaction>;

Defined in: server/packages/server/src/commerce/types.ts:180

Parameters​
ParameterType
envTEnv
inputVerifyClaimInput
Returns​

Promise<VerifiedCommerceTransaction>

verifyWebhook()?​
verifyWebhook?(env, request): Promise<VerifiedCommerceEvent | null>;

Defined in: server/packages/server/src/commerce/types.ts:186

Verifies the raw request and fetches current provider state when needed. Resolves null for an authentic notification that concerns no purchase, such as a console test message, so the provider is answered and stops resending.

Parameters​
ParameterType
envTEnv
requestRequest
Returns​

Promise<VerifiedCommerceEvent | null>


CommerceTransactionReference​

Defined in: server/packages/server/src/commerce/types.ts:161

Properties​

accountId​
accountId: string;

Defined in: server/packages/server/src/commerce/types.ts:163

acknowledgementPending​
acknowledgementPending: boolean;

Defined in: server/packages/server/src/commerce/types.ts:167

kind​
kind: "oneTime" | "subscription";

Defined in: server/packages/server/src/commerce/types.ts:165

providerReference​
providerReference: string;

Defined in: server/packages/server/src/commerce/types.ts:164

providerTransactionId​
providerTransactionId: string;

Defined in: server/packages/server/src/commerce/types.ts:162

sealedProviderState?​
sealedProviderState?: string;

Defined in: server/packages/server/src/commerce/types.ts:166


ContentDefinition​

Defined in: server/packages/server/src/commerce/types.ts:23

Properties​

classification​
classification: ContentClassification;

Defined in: server/packages/server/src/commerce/types.ts:24


ContentGrant​

Defined in: server/packages/server/src/commerce/types.ts:15

A stable, game-owned noun below the engine-owned content.use verb.

Extended by​

Properties​

collection​
collection: string;

Defined in: server/packages/server/src/commerce/types.ts:16

id​
id: string;

Defined in: server/packages/server/src/commerce/types.ts:17


CreateGameInput​

Defined in: server/packages/server/src/d1/apply.ts:364

The worker-direct create, engine-owned so implementors never touch the D1 schema: seats already validated by worker policy.

Properties​

access​
access: GameAccess;

Defined in: server/packages/server/src/d1/apply.ts:368

budgetSeconds​
budgetSeconds: number | null;

Defined in: server/packages/server/src/d1/apply.ts:373

capacity?​
capacity?: {
maximum: number;
};

Defined in: server/packages/server/src/d1/apply.ts:402

maximum​
maximum: number;
config​
config: JsonObject;

Defined in: server/packages/server/src/d1/apply.ts:371

content?​
content?: readonly SelectedContent[];

Defined in: server/packages/server/src/d1/apply.ts:394

createdAt​
createdAt: number;

Defined in: server/packages/server/src/d1/apply.ts:385

When the game began. now for an online create, which begins here; a local game began on the device, possibly days earlier, so it carries its own instant (clamped to now by the route, since it is a client claim) and history sorts by when it was played rather than when it synchronized.

createdBy​
createdBy: string | null;

Defined in: server/packages/server/src/d1/apply.ts:366

creation?​
creation?: {
creationId: string;
creatorId: string;
fingerprint: string;
};

Defined in: server/packages/server/src/d1/apply.ts:389

Present on client-facing creates; omitted only by low-level test/repair utilities that seed a game directly.

creationId​
creationId: string;
creatorId​
creatorId: string;
fingerprint​
fingerprint: string;
gameId​
gameId: string;

Defined in: server/packages/server/src/d1/apply.ts:365

incrementSeconds​
incrementSeconds: number | null;

Defined in: server/packages/server/src/d1/apply.ts:374

maxPlayers​
maxPlayers: number;

Defined in: server/packages/server/src/d1/apply.ts:378

minPlayers​
minPlayers: number;

Defined in: server/packages/server/src/d1/apply.ts:377

now​
now: number;

Defined in: server/packages/server/src/d1/apply.ts:386

origin​
origin: GameOrigin;

Defined in: server/packages/server/src/d1/apply.ts:369

rated​
rated: boolean;

Defined in: server/packages/server/src/d1/apply.ts:375

ratingPool​
ratingPool: string | null;

Defined in: server/packages/server/src/d1/apply.ts:376

schemaVersion​
schemaVersion: number;

Defined in: server/packages/server/src/d1/apply.ts:370

seats​
seats: Seat[];

Defined in: server/packages/server/src/d1/apply.ts:380

shortCode​
shortCode: string;

Defined in: server/packages/server/src/d1/apply.ts:379

status​
status: "waiting" | "ready";

Defined in: server/packages/server/src/d1/apply.ts:367

turnSeconds​
turnSeconds: number | null;

Defined in: server/packages/server/src/d1/apply.ts:372

usage?​
usage?: readonly {
maximum: number | null;
metric: "game.create.success" | "bot.game.success";
operationId: string;
periodKey: string;
}[];

Defined in: server/packages/server/src/d1/apply.ts:395


EngineConfig​

Defined in: server/packages/server/src/engine.ts:107

The EngineConfig seam: the engine never assumes binding names, so the implementor picks bindings off their own Env. Annotate the accessors' env parameter and both type arguments infer.

Type Parameters​

Type Parameter
TEnv
TDO extends BaseGameDO<TEnv>

Properties​

appName​
appName: string;

Defined in: server/packages/server/src/engine.ts:114

The whitelabel app's display name, the single source of truth for the engine's own identity (share metadata and public-page titles today; FCM titles and share copy later). Deliberately top-level, not nested under deepLink, so there is one place to set it regardless of which optional feature blocks are enabled.

avatars?​
avatars?: AvatarsConfig<TEnv>;

Defined in: server/packages/server/src/engine.ts:136

Opt-in avatar uploads. Omit → not mounted.

clientOrigins?​
clientOrigins?: readonly string[] | ((env) => readonly string[]);

Defined in: server/packages/server/src/engine.ts:132

Browser origins allowed to call the engine from a different origin.

Same-origin requests always work. When omitted, the engine trusts the exact origin from the conventional WEB_APP_ORIGIN var when it is set. Supply this option to replace that default for multiple or otherwise non-standard browser origins. Paths and wildcards are intentionally unsupported. The list also protects browser WebSocket upgrades, whose Origin header is not governed by CORS.

Set an empty list to disable the WEB_APP_ORIGIN default.

commerce?​
commerce?: CommerceConfig<TEnv>;

Defined in: server/packages/server/src/engine.ts:139

Opt-in commerce, entitlements, fixed capabilities, and commercial limits. Omit to mount no commerce routes and enforce no commercial policy.

deepLink?: DeepLinkConfig;

Defined in: server/packages/server/src/engine.ts:134

Native deep-link verification and store links. Omit for web-only.

gameModule​
gameModule: GameModule;

Defined in: server/packages/server/src/engine.ts:108

lifecycle?​
lifecycle?: LifecycleOptions;

Defined in: server/packages/server/src/engine.ts:146

Cron-backstop tuning: guest-purge/reap windows and batch caps. Omit for the defaults (LIFECYCLE_DEFAULTS); set any subset to override just those.

site?​
site?: SiteConfig;

Defined in: server/packages/server/src/engine.ts:142

The public web surface: download page, legal documents, crawler files. Omit → not mounted (the worker is API-only).

testing?​
testing?: {
auth: TokenVerifier;
firebaseAdmin(env): FirebaseAdminEffects;
};

Defined in: server/packages/server/src/engine.ts:151

Explicit test-only replacements for Firebase verification and Admin effects. Supplying them together prevents a fake verifier from accidentally turning missing production credentials into a nullable runtime path. Leave unset in production.

auth​
auth: TokenVerifier;
firebaseAdmin()​
firebaseAdmin(env): FirebaseAdminEffects;
Parameters​
ParameterType
envTEnv
Returns​

FirebaseAdminEffects

Methods​

d1()​
d1(env): D1Database;

Defined in: server/packages/server/src/engine.ts:116

The engine's D1 database (engine-private).

Parameters​
ParameterType
envTEnv
Returns​

D1Database

firebaseProjectId()?​
firebaseProjectId?(env): string;

Defined in: server/packages/server/src/engine.ts:121

Firebase project id for token verification; defaults to the FIREBASE_PROJECT_ID var (the only secret verification needs).

Parameters​
ParameterType
envTEnv
Returns​

string

gameDO()​
gameDO(env): DurableObjectNamespace<TDO>;

Defined in: server/packages/server/src/engine.ts:118

The GameDO namespace binding.

Parameters​
ParameterType
envTEnv
Returns​

DurableObjectNamespace<TDO>


EntitlementDefinition​

Defined in: server/packages/server/src/commerce/types.ts:40

Permissions, content ownership, and limits contributed by one source.

Extends​

Properties​

content?​
content?: readonly ContentGrant[];

Defined in: server/packages/server/src/commerce/types.ts:36

Inherited from​

AccessGrant.content

key​
key: string;

Defined in: server/packages/server/src/commerce/types.ts:42

Stable logical key, independent of any storefront product identifier.

limits?​
limits?: readonly CommercialLimit[];

Defined in: server/packages/server/src/commerce/types.ts:37

Inherited from​

AccessGrant.limits

permissions?​
permissions?: readonly EngineAccessCapability[];

Defined in: server/packages/server/src/commerce/types.ts:35

Inherited from​

AccessGrant.permissions


FinishApplyInput​

Defined in: server/packages/server/src/d1/apply.ts:39

Properties​

finishId​
finishId: string;

Defined in: server/packages/server/src/d1/apply.ts:43

The DO-minted idempotency key. The apply is a no-op replay when the games row already carries it.

gameId​
gameId: string;

Defined in: server/packages/server/src/d1/apply.ts:40

now​
now: number;

Defined in: server/packages/server/src/d1/apply.ts:50

outcomes​
outcomes: OutcomeEntry[];

Defined in: server/packages/server/src/d1/apply.ts:44

rated​
rated: boolean;

Defined in: server/packages/server/src/d1/apply.ts:46

ratingPool​
ratingPool: string | null;

Defined in: server/packages/server/src/d1/apply.ts:47

roster​
roster: Seat[];

Defined in: server/packages/server/src/d1/apply.ts:45

seq​
seq: number;

Defined in: server/packages/server/src/d1/apply.ts:49

The finishing commit's seq.


FirebaseAdminEffects​

Defined in: server/packages/server/src/firebase/admin-effects.ts:15

The Firebase Admin effects used by authenticated engine paths.

Methods​

deleteAccount()​
deleteAccount(userId): Promise<void>;

Defined in: server/packages/server/src/firebase/admin-effects.ts:19

Permanently delete one Firebase Authentication account.

Parameters​
ParameterType
userIdstring
Returns​

Promise<void>

notifyUser()​
notifyUser(
d1,
userId,
message
): Promise<void>;

Defined in: server/packages/server/src/firebase/admin-effects.ts:17

Send one notification through the engine's registered-device store.

Parameters​
ParameterType
d1D1Database
userIdstring
messageNotificationMessage
Returns​

Promise<void>


FrameMessage​

Defined in: server/packages/server/src/protocol.ts:204

One seat's versioned frame on the wire: the socket fan-out payload, and (for the receiving principal) the command-response ride-along. ratings appears only on the post-finish ratings transition.

Properties​

data​
data: JsonObject;

Defined in: server/packages/server/src/protocol.ts:207

deadline​
deadline: number | null;

Defined in: server/packages/server/src/protocol.ts:210

The true client-facing deadline (grace is display-only there).

outcomes?​
outcomes?: OutcomeEntry[];

Defined in: server/packages/server/src/protocol.ts:212

pendingPlayers​
pendingPlayers: number[];

Defined in: server/packages/server/src/protocol.ts:208

playerTimes​
playerTimes: number[] | null;

Defined in: server/packages/server/src/protocol.ts:211

ratings?​
ratings?: RatingDelta[];

Defined in: server/packages/server/src/protocol.ts:213

type​
type: "frame";

Defined in: server/packages/server/src/protocol.ts:205

version​
version: number;

Defined in: server/packages/server/src/protocol.ts:206


LegalConfig​

Defined in: server/packages/server/src/site/config.ts:29

Legal document overrides. Each is an HTML fragment: body content only, no document wrapper; the engine supplies the shell, styling and footer. Omitted documents fall back to the engine's generic templates.

A fragment is inserted as-is, so it is the implementor's own trusted markup with their own values already written in. There are no placeholders to fill: the engine's defaults take an OperatorConfig as typed props, which is what a template's tokens used to stand in for.

Properties​

deleteAccount?​
deleteAccount?: string;

Defined in: server/packages/server/src/site/config.ts:32

privacy?​
privacy?: string;

Defined in: server/packages/server/src/site/config.ts:31

terms?​
terms?: string;

Defined in: server/packages/server/src/site/config.ts:30


LocalRecord​

Defined in: server/packages/server/src/protocol.ts:257

What a device needs to continue a local game it holds no record for: the seed every transition's randomness derives from, plus the log itself.

Properties​

seed​
seed: string;

Defined in: server/packages/server/src/protocol.ts:258

transitions​
transitions: LocalTransitionRow[];

Defined in: server/packages/server/src/protocol.ts:259


LocalRejection​

Defined in: server/packages/server/src/protocol.ts:231

Which transition of an import batch the game refused, and why.

Not a transport error: everything before index is committed and permanent, so the batch answers 200 carrying this. It means the device's Dart twin and the authoritative TypeScript rules disagreed, which the client surfaces as a diverged record rather than retrying. abstain cannot appear: only the alarm's system timeout abstains, and a local game is untimed.

Properties​

code​
code:
| "expired"
| "notActive"
| "notReady"
| "notPending"
| "stateUpdated"
| "invalidPayload"
| "illegalMove"
| LobbyRejectCode;

Defined in: server/packages/server/src/protocol.ts:233

index​
index: number;

Defined in: server/packages/server/src/protocol.ts:232

message​
message: string;

Defined in: server/packages/server/src/protocol.ts:234


LocalTransition​

Defined in: server/packages/server/src/protocol.ts:117

One transition of a local game's log, as the device recorded it.

data is the game's own action payload for game, and a LifecycleAction for lifecycle — of which only forfeit is importable, because a local game is untimed (so it can never time out) and autoForfeit is engine-driven. The worker validates the lifecycle payload before minting the command, so the DO reads the seat and nothing else.

Properties​

data​
data: unknown;

Defined in: server/packages/server/src/protocol.ts:120

kind​
kind: "lifecycle" | "game";

Defined in: server/packages/server/src/protocol.ts:119

seat​
seat: number;

Defined in: server/packages/server/src/protocol.ts:118


LocalTransitionRow​

Defined in: server/packages/server/src/protocol.ts:248

One row of a local game's stored log: the raw state and the action that produced it, which is everything a device needs to rebuild its local engine. The ONLY place raw state leaves the Durable Object, and only to the game's single human (see GameStub.localRecord).

Properties​

action​
action: TransitionAction | null;

Defined in: server/packages/server/src/protocol.ts:251

pending​
pending: number[];

Defined in: server/packages/server/src/protocol.ts:252

state​
state: JsonObject;

Defined in: server/packages/server/src/protocol.ts:250

version​
version: number;

Defined in: server/packages/server/src/protocol.ts:249


OperatorConfig​

Defined in: server/packages/server/src/site/config.ts:9

The legal entity publishing the game. Required whenever site is present: the default legal documents take it as a prop and cannot render without it.

Properties​

contactEmail​
contactEmail: string;

Defined in: server/packages/server/src/site/config.ts:15

Support and privacy contact address.

effectiveDate​
effectiveDate: string;

Defined in: server/packages/server/src/site/config.ts:18

Effective date of the legal documents, as displayed. A plain string, not a Date, since it is prose and its format is the operator's choice.

jurisdiction​
jurisdiction: string;

Defined in: server/packages/server/src/site/config.ts:13

Governing jurisdiction, e.g. India.

name​
name: string;

Defined in: server/packages/server/src/site/config.ts:11

Legal entity name. Also the page footers' copyright holder.


Principal​

Defined in: server/packages/server/src/protocol.ts:32

Who a command acts as, resolved at the edge. Exactly one id is set.

Properties​

botId​
botId: string | null;

Defined in: server/packages/server/src/protocol.ts:34

userId​
userId: string | null;

Defined in: server/packages/server/src/protocol.ts:33


RatingDelta​

Defined in: server/packages/kernel/dist/index.d.ts:140

One rated identity's before → after, exactly the rating_history row minus store keys. Computed by the D1 applier inside the rating CAS and delivered on the post-finish ratings transition (the kind: "ratings" action).

Properties​

displayAfter​
displayAfter: number;

Defined in: server/packages/kernel/dist/index.d.ts:148

displayBefore​
displayBefore: number;

Defined in: server/packages/kernel/dist/index.d.ts:145

displayChange​
displayChange: number;

Defined in: server/packages/kernel/dist/index.d.ts:149

identity​
identity: RatingIdentity;

Defined in: server/packages/kernel/dist/index.d.ts:141

muAfter​
muAfter: number;

Defined in: server/packages/kernel/dist/index.d.ts:146

muBefore​
muBefore: number;

Defined in: server/packages/kernel/dist/index.d.ts:143

pool​
pool: string;

Defined in: server/packages/kernel/dist/index.d.ts:142

sigmaAfter​
sigmaAfter: number;

Defined in: server/packages/kernel/dist/index.d.ts:147

sigmaBefore​
sigmaBefore: number;

Defined in: server/packages/kernel/dist/index.d.ts:144


RetryOptions​

Defined in: server/packages/server/src/retry.ts:17

Bounded retry with jittered exponential backoff.

Deliberately transport-agnostic: the caller supplies the predicate deciding which failures are worth retrying. Two live users, with very different predicates and budgets:

  • background D1 mirror writes (isTransientD1Error, in d1/errors.ts);
  • Worker-to-Durable-Object calls (isRetryableDoError, in game-stub.ts).

The shared discipline is the same in both: retry only transient infrastructure failures, never a deterministic one, where retrying would burn the budget before surfacing the real problem, and never an overload, where the documented remedy is to shed load rather than add to it.

Properties​

attempts?​
attempts?: number;

Defined in: server/packages/server/src/retry.ts:19

Total attempts including the first. Default 4.

baseDelayMs?​
baseDelayMs?: number;

Defined in: server/packages/server/src/retry.ts:21

First backoff, doubling each retry. Default 50ms.

maxDelayMs?​
maxDelayMs?: number;

Defined in: server/packages/server/src/retry.ts:23

Backoff ceiling. Default 2000ms.

onRetry?​
onRetry?: (error, attempt) => void;

Defined in: server/packages/server/src/retry.ts:29

Observe each retry (logging); never throws into the loop.

Parameters​
ParameterType
errorunknown
attemptnumber
Returns​

void

shouldRetry​
shouldRetry: (error) => boolean;

Defined in: server/packages/server/src/retry.ts:27

Which failures are worth retrying. Required: there is no safe default, because "retryable" is a property of the transport AND of whether the operation can be applied twice.

Parameters​
ParameterType
errorunknown
Returns​

boolean

sleep?​
sleep?: (ms) => Promise<void>;

Defined in: server/packages/server/src/retry.ts:31

Delay primitive, injectable so tests run without real timers.

Parameters​
ParameterType
msnumber
Returns​

Promise<void>


SelectedContent​

Defined in: server/packages/server/src/commerce/types.ts:216

One content choice snapshotted onto a game at creation.

Extends​

Properties​

classification​
classification: ContentClassification;

Defined in: server/packages/server/src/commerce/types.ts:218

collection​
collection: string;

Defined in: server/packages/server/src/commerce/types.ts:16

Inherited from​

ContentGrant.collection

id​
id: string;

Defined in: server/packages/server/src/commerce/types.ts:17

Inherited from​

ContentGrant.id

ownership​
ownership: ContentOwnershipScope;

Defined in: server/packages/server/src/commerce/types.ts:217


SessionSnapshot​

Defined in: server/packages/server/src/protocol.ts:164

The complete live truth about one game, as ONE SEAT sees it: the only message the socket carries, and the body of every accepted command.

Sent on socket open whatever the status, and after every committed change, lobby or state. Self-describing and idempotent: a client that applies the newest one it has seen is correct, having missed any number of earlier ones, so there is no state for it to reconstruct and no channel for it to correlate against another.

It carries the immutable header as well as the moving parts because a game screen must not need a second source. That is what the old split cost: status lived only in a D1 read nothing re-issued, so a client could observe a frame without the status it belonged to, and never learned a game had started.

Hidden information is safe by construction: the envelope is projected per seat before it is sent, and frame is only ever the receiving principal's own seat's view.

Properties​

access​
access: GameAccess;

Defined in: server/packages/server/src/protocol.ts:176

budgetSeconds​
budgetSeconds: number | null;

Defined in: server/packages/server/src/protocol.ts:182

config​
config: JsonObject;

Defined in: server/packages/server/src/protocol.ts:180

createdBy​
createdBy: string | null;

Defined in: server/packages/server/src/protocol.ts:188

frame​
frame: FrameMessage | null;

Defined in: server/packages/server/src/protocol.ts:198

The receiving seat's observation at version. Null in the lobby, and null for a principal holding no seat, which is how an unseated client still learns that the game started.

gameId​
gameId: string;

Defined in: server/packages/server/src/protocol.ts:174

Fixed at creation; carried so this is sufficient on its own.

incrementSeconds​
incrementSeconds: number | null;

Defined in: server/packages/server/src/protocol.ts:183

maxPlayers​
maxPlayers: number;

Defined in: server/packages/server/src/protocol.ts:187

minPlayers​
minPlayers: number;

Defined in: server/packages/server/src/protocol.ts:186

origin​
origin: GameOrigin;

Defined in: server/packages/server/src/protocol.ts:178

Where this game is played; never changes.

players​
players: Seat[];

Defined in: server/packages/server/src/protocol.ts:192

rated​
rated: boolean;

Defined in: server/packages/server/src/protocol.ts:184

ratingPool​
ratingPool: string | null;

Defined in: server/packages/server/src/protocol.ts:185

schemaVersion​
schemaVersion: number;

Defined in: server/packages/server/src/protocol.ts:179

seq​
seq: number;

Defined in: server/packages/server/src/protocol.ts:171

Monotonic per game, incremented by every commit. Totally orders snapshots across every path they arrive by, which version cannot do because a lobby change has none. Apply a snapshot only when seq exceeds the held one. finished and aborted are absorbing, so a client also refuses a later non-terminal snapshot rather than resurrecting a completed game.

shortCode​
shortCode: string;

Defined in: server/packages/server/src/protocol.ts:175

status​
status: GameStatus;

Defined in: server/packages/server/src/protocol.ts:191

What moves.

turnSeconds​
turnSeconds: number | null;

Defined in: server/packages/server/src/protocol.ts:181

type​
type: "session";

Defined in: server/packages/server/src/protocol.ts:165

version​
version: number | null;

Defined in: server/packages/server/src/protocol.ts:194

The newest committed version, or null while the game is in the lobby.


SiteConfig​

Defined in: server/packages/server/src/site/config.ts:53

The public web surface a deployed game serves on its own host: download page, legal documents, and the crawler files. Absent → none of it is mounted and the worker stays API-only.

The scaffold reserves these paths for the Worker with Static Assets' run_worker_first; customize legal prose through this typed config.

Properties​

description?​
description?: string;

Defined in: server/packages/server/src/site/config.ts:59

Longer download-page prose. Defaults to tagline.

legal?: LegalConfig;

Defined in: server/packages/server/src/site/config.ts:73

madeByCredit?​
madeByCredit?: string | null;

Defined in: server/packages/server/src/site/config.ts:71

Footer credit line. Defaults to DEFAULT_CREDIT; null removes it.

name?​
name?: string;

Defined in: server/packages/server/src/site/config.ts:55

Public game name in titles and OG tags. Defaults to appName.

ogImage?​
ogImage?: string;

Defined in: server/packages/server/src/site/config.ts:69

Path under public/ to the 1200x630 OG image. Defaults to /og-image.png, the name the branding guide prescribes for the Flutter app's own share card: one image, both surfaces. The engine never generates images.

operator​
operator: OperatorConfig;

Defined in: server/packages/server/src/site/config.ts:72

primaryColor​
primaryColor: string;

Defined in: server/packages/server/src/site/config.ts:61

Hex accent colour, e.g. #1a237e. Also the theme-color.

screenshots?​
screenshots?: string[];

Defined in: server/packages/server/src/site/config.ts:63

Filenames under public/screenshots/, shown as a scrolling strip.

tagline​
tagline: string;

Defined in: server/packages/server/src/site/config.ts:57

One-sentence hook. The meta description and OG description.


TokenVerifier​

Defined in: server/packages/server/src/auth/firebase.ts:29

The seam createEngine consumes. Production is createFirebaseVerifier with the default remote JWKS; tests inject a local JWKS and mint their own RS256 tokens.

Methods​

verify()​
verify(token): Promise<AuthClaims>;

Defined in: server/packages/server/src/auth/firebase.ts:31

Resolve a bearer token to claims, or throw AuthError.

Parameters​
ParameterType
tokenstring
Returns​

Promise<AuthClaims>


VerifiedCommerceEvent​

Defined in: server/packages/server/src/commerce/types.ts:149

A provider-authenticated notification resolved to current provider state.

Properties​

accountId?​
accountId?: string;

Defined in: server/packages/server/src/commerce/types.ts:157

The Eigen account the provider says the purchase belongs to. Absent when it names none -- a Play resubscription made from the Play Store carries no obfuscated account id -- and the ledger then attributes the transaction through the row it already has, or the one it replaced.

providerEventId​
providerEventId: string;

Defined in: server/packages/server/src/commerce/types.ts:150

transaction​
transaction: VerifiedCommerceTransaction;

Defined in: server/packages/server/src/commerce/types.ts:158


VerifiedCommerceTransaction​

Defined in: server/packages/server/src/commerce/types.ts:76

Provider output after server-side verification. Never accepted from a client.

Properties​

kind​
kind: "oneTime" | "subscription";

Defined in: server/packages/server/src/commerce/types.ts:82

Must match the configured logical offer kind.

providerAccountId?​
providerAccountId?: string;

Defined in: server/packages/server/src/commerce/types.ts:88

Provider customer/account id, when the provider exposes one.

providerReference​
providerReference: string;

Defined in: server/packages/server/src/commerce/types.ts:80

What this transaction serves now. A subscription's may change over its life (a plan change), and the ledger moves it to the matching offer.

providerTransactionId​
providerTransactionId: string;

Defined in: server/packages/server/src/commerce/types.ts:77

purchasedAt​
purchasedAt: number;

Defined in: server/packages/server/src/commerce/types.ts:84

replacesProviderTransactionId?​
replacesProviderTransactionId?: string;

Defined in: server/packages/server/src/commerce/types.ts:104

The transaction this one replaced at the provider, when it says so: Play issues a new purchase token for every plan change and for a resubscription after a lapse, and names the old token as linkedPurchaseToken. The ledger ends the replaced transaction, so the old token's grants do not outlive it, and attributes this one through it when the provider names no account.

requiresAcknowledgement?​
requiresAcknowledgement?: boolean;

Defined in: server/packages/server/src/commerce/types.ts:96

True when the provider requires a post-ledger acknowledgement.

sealedProviderState?​
sealedProviderState?: string;

Defined in: server/packages/server/src/commerce/types.ts:94

Adapter-sealed state needed for later verification (for example an encrypted Play purchase token). It MUST be safe to persist in D1 and MUST never contain a plaintext receipt, token, or payment credential.

state​
state: CommerceTransactionState;

Defined in: server/packages/server/src/commerce/types.ts:83

validFrom​
validFrom: number;

Defined in: server/packages/server/src/commerce/types.ts:85

validUntil?​
validUntil?: number;

Defined in: server/packages/server/src/commerce/types.ts:86

Type Aliases​

Command​

type Command =
| {
actor: Principal;
gameId: string;
kind: "join" | "leave";
}
| {
actor: Principal;
gameId: string;
kind: "cancel";
}
| {
actor: Principal;
gameId: string;
kind: "start";
seed?: string;
}
| {
actor: Principal;
botId: string;
gameId: string;
kind: "add-bot";
}
| {
actor: Principal;
data: unknown;
expectedVersion: number;
gameId: string;
kind: "action";
seat: number;
}
| {
actor: Principal | null;
gameId: string;
kind: "lifecycle";
seat?: number;
type: LifecycleType;
}
| {
actor: Principal;
fromVersion: number;
gameId: string;
kind: "local-transitions";
transitions: LocalTransition[];
};

Defined in: server/packages/server/src/protocol.ts:39

Everything that crosses the worker → DO boundary after creation ( create itself is a worker-direct D1 write; the DO does not exist yet).

Union Members​

Type Literal​
{
actor: Principal;
gameId: string;
kind: "join" | "leave";
}

Type Literal​
{
actor: Principal;
gameId: string;
kind: "cancel";
}

Type Literal​
{
actor: Principal;
gameId: string;
kind: "start";
seed?: string;
}
actor​
actor: Principal;
gameId​
gameId: string;
kind​
kind: "start";
seed?​
seed?: string;

The game's base RNG seed. Carried ONLY by the local-import create (POST /games/local): the device already played the game from this seed, so the server's replay has to draw the same values or every random hook would diverge on the first transition. Absent on every other path, where the DO generates one (randomSeed()) and the seed never leaves it.


Type Literal​
{
actor: Principal;
botId: string;
gameId: string;
kind: "add-bot";
}

Type Literal​
{
actor: Principal;
data: unknown;
expectedVersion: number;
gameId: string;
kind: "action";
seat: number;
}
actor​
actor: Principal;
data​
data: unknown;
expectedVersion​
expectedVersion: number;

The version the client computed the move against; a lower value is arbitrated by the same-view rule.

gameId​
gameId: string;
kind​
kind: "action";
seat​
seat: number;

The acting seat, carried uniformly by humans and bots. The DO verifies it belongs to the actor (user id from the token, bot id from the HMAC claim) against its own roster and rejects otherwise, so a client can never act on a seat it does not hold. Required because one bot id may hold several seats, and uniform for one code path.


Type Literal​
{
actor: Principal | null;
gameId: string;
kind: "lifecycle";
seat?: number;
type: LifecycleType;
}
actor​
actor: Principal | null;

Null for identity-less system lifecycles (timeout, autoForfeit).

gameId​
gameId: string;
kind​
kind: "lifecycle";
seat?​
seat?: number;

The affected seat: forfeit carries the resigning seat (verified against the actor, like an action); autoForfeit the purged seat; timeout carries none (it resolves all pending).

type​
type: LifecycleType;

Type Literal​
{
actor: Principal;
fromVersion: number;
gameId: string;
kind: "local-transitions";
transitions: LocalTransition[];
}
actor​
actor: Principal;

The game's creator: the only principal a local game has.

fromVersion​
fromVersion: number;

The version the device believes the server is at. The import is append-only, so a mismatch means another device already appended and this batch is refused whole (stateUpdated).

gameId​
gameId: string;
kind​
kind: "local-transitions";

Import a run of a local game's transitions into the authoritative object, in order, as one request.

A batch rather than one command per transition because a finished local game is a whole transcript: sending it move by move would cost a Worker and a Durable Object request each, and would let a client stop halfway through with the server's copy in a state the device never saw.

transitions​
transitions: LocalTransition[];

CommandResult​

type CommandResult =
| {
ok: true;
session: SessionSnapshot;
}
| {
code: | RejectCode
| LobbyRejectCode;
message: string;
ok: false;
};

Defined in: server/packages/server/src/protocol.ts:222

What GameDO.handle() returns: one accepted shape for every command kind, the caller's own post-commit SessionSnapshot, so a lobby command and a move answer with the same value and the client feeds both into one path.

Rejections are values and are recomputed against the authoritative current state on every attempt.


CommerceTransactionState​

type CommerceTransactionState = "pending" | "active" | "grace" | "expired" | "revoked";

Defined in: server/packages/server/src/commerce/types.ts:73


CommercialLimit​

type CommercialLimit =
| {
maximum: number;
metric: CommercialMetric;
period: CommercialPeriod;
}
| {
maximum: "noCommercialLimit";
metric: CommercialMetric;
};

Defined in: server/packages/server/src/commerce/types.ts:31


CommercialMetric​

type CommercialMetric =
| "game.create.success"
| "games.openCreated"
| "bot.game.success"
| "analysis.run.success";

Defined in: server/packages/server/src/commerce/types.ts:27


CommercialPeriod​

type CommercialPeriod =
| {
kind: "calendarMonth";
timezone: "UTC";
}
| {
kind: "subscriptionPeriod";
}
| {
kind: "lifetime";
}
| {
kind: "concurrent";
};

Defined in: server/packages/server/src/commerce/types.ts:29


ContentClassification​

type ContentClassification = "sharedRuleset" | "cosmetic";

Defined in: server/packages/server/src/commerce/types.ts:20


ContentOwnershipScope​

type ContentOwnershipScope = "creator" | "eachParticipant" | "viewer";

Defined in: server/packages/server/src/commerce/types.ts:21


EngineAccessCapability​

type EngineAccessCapability =
| {
kind: "app.access";
}
| {
access: GameAccess;
kind: "game.create";
}
| {
access: GameAccess;
kind: "game.join";
}
| {
kind: "game.create.rated";
}
| {
kind: "bot.use";
tier: string;
}
| {
collection: string;
id: string;
kind: "content.use";
}
| {
kind: "replay.read";
}
| {
analysisType?: string;
kind: "analysis.use";
};

Defined in: server/packages/server/src/commerce/types.ts:4

The engine-owned commercial authorization vocabulary.


GameOrigin​

type GameOrigin = "online" | "local";

Defined in: server/packages/server/src/protocol.ts:29

Where a game is played, fixed at creation and immutable.

online is the ordinary game: every transition is decided by this server. local is a game the device played offline against on-device bot brains and imported afterwards, transition by transition, through the two import routes. The server still commits every one of them through the same rules, so an imported game is an ordinary game once it lands; origin says how it got here, which is what lets a client badge it, keep it unrated, and know that it may continue appending to it from the device.

Lives here rather than beside the D1 column because it is protocol: it rides SessionSnapshot and the game summary, so a game screen needs no second source to know what it is looking at.


LobbyRejectCode​

type LobbyRejectCode =
| "unknownGame"
| "notJoinable"
| "gameFull"
| "alreadyJoined"
| "notParticipant"
| "notCreator"
| "creatorCannotLeave";

Defined in: server/packages/server/src/protocol.ts:128

Why the DO refused a waiting-room command: the integrity column. These are expected refusals (accepted lobby staleness: the lobby may show a game that just filled), returned as values exactly like kernel rejections; the worker maps them to HTTP. Genuine protocol violations (acting on a seat you don't own) still throw.


LocalBatchResult​

type LocalBatchResult =
| {
applied: number;
ok: true;
rejection: LocalRejection | null;
session: SessionSnapshot;
}
| {
code: | RejectCode
| LobbyRejectCode;
message: string;
ok: false;
};

Defined in: server/packages/server/src/protocol.ts:242

What one import batch returns: how far it got, the creator's session after the last committed transition, and the rejection that stopped it (null when the whole batch landed). A refusal of the batch as a whole (an unknown game, a non-creator, a fromVersion another device moved past) is the same rejection value shape every command uses.


SingleCommand​

type SingleCommand = Exclude<Command, {
kind: "local-transitions";
}>;

Defined in: server/packages/server/src/protocol.ts:106

Every command that is exactly one commit: what GameStub.handle takes. The import batch is the one command that is not, and it has its own entry point, because it answers with how far it got rather than with one commit's result.


UserRow​

type UserRow = typeof users.$inferSelect;

Defined in: server/packages/server/src/auth/provision.ts:19

Variables​

DEADLINE_GRACE_MS​

const DEADLINE_GRACE_MS: 750 = 750;

Defined in: server/packages/kernel/dist/index.d.ts:380

Grace window (ms) added to every deadline comparison so a player who submits on time is not rejected because network latency carried the request past the deadline. Keep it small relative to per-action turnSeconds windows. The client's display-only kServerDeadlineGrace mirrors this.


DEFAULT_BOT_TIER​

const DEFAULT_BOT_TIER: "standard" = "standard";

Defined in: server/packages/server/src/commerce/capability.ts:14

The tier of every bot botTiers does not list.

Every bot belongs to exactly one tier, so a bot.use grant always names one and covers only that one. There is deliberately no grant meaning "every bot": it is the grant a free profile reaches for to keep ordinary bots free, and it would quietly cover the paid tiers too. A deployment that prices no bot grants standard; one that sells a tier grants standard free and the paid tier through an entitlement.


DEFAULT_CREDIT​

const DEFAULT_CREDIT: "Built with EigenInteractive" = "Built with EigenInteractive";

Defined in: server/packages/server/src/site/config.ts:41

The credit line in every page footer. Set site.madeByCredit to your own string, or to null to drop it.

The footer links whichever part of the line reads CREDIT_BRAND, so a custom credit that names the engine gets the link too, and one that does not renders as plain text rather than pointing somewhere it never mentioned.

Functions​

applyFinish()​

function applyFinish(d1, input): Promise<RatingDelta[] | null>;

Defined in: server/packages/server/src/d1/apply.ts:76

Apply one finished game to D1. Returns the rated deltas (null for an unrated game) for the DO to deliver as the ratings transition. Throws on failure, so the caller logs and keeps the outbox row (single attempt at the call site; the internal loop only absorbs CAS conflicts).

Parameters​

ParameterType
d1D1Database
inputFinishApplyInput

Returns​

Promise<RatingDelta[] | null>


capabilityAllows()​

function capabilityAllows(granted, required): boolean;

Defined in: server/packages/server/src/commerce/capability.ts:87

Whether a grant covers a requirement. A grant covers exactly the resource it names and nothing wider: a creation access mode, a bot tier, a content item. As with game.create, there is no unparameterized grant standing for "all of them", because that is the grant that silently gives away what a deployment sells. analysis.use still accepts an untyped grant, which covers untyped analysis only; whether an analysis type must be named belongs to the decision that ships analysis.

Parameters​

ParameterType
grantedEngineAccessCapability
requiredEngineAccessCapability

Returns​

boolean


capabilityKey()​

function capabilityKey(capability): string;

Defined in: server/packages/server/src/commerce/capability.ts:60

Stable structural identity for set membership, logs, and error details.

Parameters​

ParameterType
capabilityEngineAccessCapability

Returns​

string


createEngine()​

function createEngine<TEnv, TDO>(cfg): ExportedHandler<TEnv>;

Defined in: server/packages/server/src/engine.ts:487

Creates the complete Cloudflare Worker for one game deployment.

Call this once from the default export of src/index.ts. The returned handler mounts the authenticated game API, WebSocket upgrades, scheduled lifecycle work, and any configured public/deep-link routes. Game implementors provide only EngineConfig.gameModule and binding accessors; routes, persistence, migrations, authentication, and session dispatch stay engine-owned.

Type Parameters​

Type Parameter
TEnv extends object
TDO extends BaseGameDO<TEnv>

Parameters​

ParameterType
cfgEngineConfig<TEnv, TDO>

Returns​

ExportedHandler<TEnv>

Example​

export default createEngine({
gameModule,
appName: "My Game",
d1: (env: Env) => env.GAME_DB,
gameDO: (env: Env) => env.GAME_DO,
});

createFirebaseVerifier()​

function createFirebaseVerifier(projectId, getKey?): TokenVerifier;

Defined in: server/packages/server/src/auth/firebase.ts:46

Parameters​

ParameterType
projectIdstring
getKey?JWTVerifyGetKey<CryptoKeyStructuralFallback | Uint8Array<ArrayBufferLike>>

Returns​

TokenVerifier


createGame()​

function createGame(d1, input): Promise<void>;

Defined in: server/packages/server/src/d1/apply.ts:414

Write the games row + one participants row per seat, atomically. The DO lazy-inits from exactly these rows on first contact.

A duplicate short code is the only expected insert collision; callers retry it with a newly generated code.

Parameters​

ParameterType
d1D1Database
inputCreateGameInput

Returns​

Promise<void>


deriveBotKey()​

function deriveBotKey(masterSecret, botId): Promise<string>;

Defined in: server/packages/server/src/bot/bot-auth.ts:60

The per-bot signing key as base64, the operator utility. This is the one value an external bot's owner is given, and the only one they need: it is what they HMAC their request bodies with. The master BOT_SIGNING_SECRET never leaves the operator, and because every bot's key is derived from it, registering a bot needs no new secret and no redeploy.

Base64 to match the signature transport encoding. Equivalent to:

echo -n "<botId>" | openssl dgst -sha256 -hmac "<BOT_SIGNING_SECRET>" -binary | base64

Treat the result as a credential: it authenticates that bot to the engine for as long as it is registered. Rotating one bot's key means rotating the master secret, which rotates every bot's key, so issue per-bot keys only to owners you would re-issue all of them for.

Parameters​

ParameterType
masterSecretstring
botIdstring

Returns​

Promise<string>


displayRating()​

function displayRating(mu, sigma): number;

Defined in: server/packages/kernel/dist/index.d.ts:153

max(0, round((mu − 3σ) · 40)): the one server-side home of the display formula (the client mirrors it for optimistic display only).

Parameters​

ParameterType
munumber
sigmanumber

Returns​

number


ensureUser()​

function ensureUser(
d1,
claims,
now
): Promise<{
avatarUrl: string | null;
createdAt: number;
displayName: string;
email: string | null;
id: string;
isAnonymous: boolean;
updatedAt: number;
username: string;
}>;

Defined in: server/packages/server/src/auth/provision.ts:51

Load the caller's row, creating or backfilling it as the token demands. One read on the hot path; writes only on first sight and on guest → permanent conversion.

Parameters​

ParameterType
d1D1Database
claimsAuthClaims
nownumber

Returns​

Promise<{ avatarUrl: string | null; createdAt: number; displayName: string; email: string | null; id: string; isAnonymous: boolean; updatedAt: number; username: string; }>


isTransientD1Error()​

function isTransientD1Error(error): boolean;

Defined in: server/packages/server/src/d1/errors.ts:118

True for the D1 failures worth retrying: a network blip, a storage or Durable-Object reset, a code-update restart, or a transient routing failure.

Deliberately narrow; see RETRYABLE_D1. Pass to withRetry as its shouldRetry for an idempotent D1 write.

Parameters​

ParameterType
errorunknown

Returns​

boolean


mirrorRoster()​

function mirrorRoster(d1, args): Promise<void>;

Defined in: server/packages/server/src/d1/apply.ts:330

The roster mirror after a committed waiting-room command. The DO's roster is the integrity copy; this rewrites the D1 display copy wholesale (delete + reinsert), which is idempotent and immune to per-row drift. Fire-and-forget post-commit (the DO leaves it unawaited, under a retry).

Each reinsert is an INSERT ... SELECT from the game's own row at this revision, so it carries the same guard as the delete: a stale mirror must leave the roster a newer one wrote, not delete it and put back an older one.

Parameters​

ParameterType
d1D1Database
args{ gameId: string; now: number; seats: Seat[]; seq: number; status: GameStatus; }
args.gameIdstring
args.nownumber
args.seatsSeat[]
args.seqnumber
args.statusGameStatus

Returns​

Promise<void>


openApiDocument()​

function openApiDocument(version): OpenAPIObject;

Defined in: server/packages/server/src/engine.ts:602

Parameters​

ParameterType
versionstring

Returns​

OpenAPIObject


readCreationOperation()​

function readCreationOperation(
d1,
creatorId,
creationId
): Promise<
| {
createdAt: number;
creationId: string;
creatorId: string;
fingerprint: string;
gameId: string;
id: string;
shortCode: string;
}
| undefined>;

Defined in: server/packages/server/src/d1/apply.ts:510

Parameters​

ParameterType
d1D1Database
creatorIdstring
creationIdstring

Returns​

Promise< | { createdAt: number; creationId: string; creatorId: string; fingerprint: string; gameId: string; id: string; shortCode: string; } | undefined>


readGameRow()​

function readGameRow(d1, gameId): Promise<
| {
access: GameAccess;
archivedAt: number | null;
budgetSeconds: number | null;
config: JsonObject;
createdAt: number;
createdBy: string | null;
finishedAt: number | null;
finishId: string | null;
id: string;
incrementSeconds: number | null;
maxPlayers: number;
minPlayers: number;
origin: GameOrigin;
outcomes: OutcomeEntry[] | null;
participants: Seat[];
pendingPlayers: number[] | null;
rated: boolean;
ratingPool: string | null;
schemaVersion: number;
seq: number;
shortCode: string;
status: GameStatus;
turnDeadline: number | null;
turnSeconds: number | null;
updatedAt: number;
}
| undefined>;

Defined in: server/packages/server/src/d1/apply.ts:520

Lazy-init read: the D1 game + participants rows the DO copies into its meta/roster on first contact, in one batched round trip.

Parameters​

ParameterType
d1D1Database
gameIdstring

Returns​

Promise< | { access: GameAccess; archivedAt: number | null; budgetSeconds: number | null; config: JsonObject; createdAt: number; createdBy: string | null; finishedAt: number | null; finishId: string | null; id: string; incrementSeconds: number | null; maxPlayers: number; minPlayers: number; origin: GameOrigin; outcomes: OutcomeEntry[] | null; participants: Seat[]; pendingPlayers: number[] | null; rated: boolean; ratingPool: string | null; schemaVersion: number; seq: number; shortCode: string; status: GameStatus; turnDeadline: number | null; turnSeconds: number | null; updatedAt: number; } | undefined>


resolveCommerce()​

function resolveCommerce<TEnv>(config): ResolvedCommerce;

Defined in: server/packages/server/src/commerce/catalog.ts:80

Validate a deployment catalog once, before any request can reach it.

Type Parameters​

Type Parameter
TEnv

Parameters​

ParameterType
configCommerceConfig<TEnv>

Returns​

ResolvedCommerce


updateSummary()​

function updateSummary(d1, args): Promise<void>;

Defined in: server/packages/server/src/d1/apply.ts:308

The display upsert after a non-finishing transition: fire-and-forget post-commit (the DO leaves it unawaited, under a retry), re-derivable from the DO at any time.

Parameters​

ParameterType
d1D1Database
args{ gameId: string; now: number; pendingPlayers: number[]; seq: number; status?: "active"; turnDeadline: number | null; }
args.gameIdstring
args.nownumber
args.pendingPlayersnumber[]
args.seqnumber
args.status?"active"
args.turnDeadlinenumber | null

Returns​

Promise<void>


withRetry()​

function withRetry<T>(op, options): Promise<T>;

Defined in: server/packages/server/src/retry.ts:49

Run op, retrying a retryable failure with jittered exponential backoff up to attempts. A non-retryable failure, or the last attempt, throws.

Safe to leave unawaited inside a Durable Object: the DO stays alive while the returned promise (and its backoff timers) is pending, so the whole sequence runs to completion without waitUntil, exactly like the single-attempt writes it wraps.

op MUST be idempotent: a retry can fire after an operation that actually landed but whose acknowledgement was lost. Nothing here can detect that, so it is the caller's invariant, not this function's.

Type Parameters​

Type Parameter
T

Parameters​

ParameterType
op() => Promise<T>
optionsRetryOptions

Returns​

Promise<T>