Skip to content

@lastshotlabs/slingshot-game-engine

npm install @lastshotlabs/slingshot-game-engine

Authorize verified claims against the live session record.

Fails closed on every axis: wrong session, revoked epoch, or a session that is already over.

function authorizeDisplayToken(claims: DisplayTokenClaims, session: DisplaySessionFacts | null,): DisplayTokenVerification

Source: packages/slingshot-game-engine/src/lib/displayToken.ts

Build the content validation guard middleware.

Registered under 'contentValidationGuard' in the named middleware map.

function buildContentValidationGuard({ getSessionAdapter, getRegistry, }: ContentValidationGuardDeps): void

Source: packages/slingshot-game-engine/src/middleware/contentValidationGuard.ts

Build the lobby-only guard middleware.

Registered under 'lobbyOnlyGuard' in the named middleware map.

function buildLobbyOnlyGuard({ getSessionAdapter }: LobbyOnlyGuardDeps): void

Source: packages/slingshot-game-engine/src/middleware/lobbyOnlyGuard.ts

Build the rules validation guard middleware.

Registered under 'rulesValidationGuard' in the named middleware map.

function buildRulesValidationGuard({ getSessionAdapter, getRegistry, }: RulesValidationGuardDeps): void

Source: packages/slingshot-game-engine/src/middleware/rulesValidationGuard.ts

Create the game engine package.

function createGameEnginePackage(rawConfig: Partial<GameEnginePluginConfig> & { games?: GameDefinition[] } = {},): SlingshotPackageDefinition

Source: packages/slingshot-game-engine/src/plugin.ts

Create the default session access policy.

Dispatches on gameType field. Default fallback allows access to lobbies and denies access to in-progress sessions unless overridden by a game-type-specific handler.

function createGameSessionPolicy(): void

Source: packages/slingshot-game-engine/src/policy/index.ts

Default lifetime. Long enough to outlast a party, short enough that a photo of the TV rots.

Source: packages/slingshot-game-engine/src/lib/displayToken.ts

Stable key used for reading or publishing the game-engine plugin state.

Source: packages/slingshot-game-engine/src/types/state.ts

Stable policy key — referenced in entity route configs.

Source: packages/slingshot-game-engine/src/policy/index.ts

Declarative operations for the GameSession entity.

Includes lookups (findByJoinCode, findByGameType) and status transitions (startGame, pauseGame, resumeGame, completeGame, abandonSession).

Source: packages/slingshot-game-engine/src/operations/session.ts

The session this request is a display for, or null.

This is the ONLY sanctioned way an app authorizes a TV. Use it to widen a route that would otherwise require a user:

const userId = getActorId(c); // null for a TV
const display = getDisplaySessionId(c); // the session, for a TV
if (!userId && display !== match.gameSessionId) return c.json(…, 401);

Note what this does NOT do: it never returns a user id, so a display can never be mistaken for a player by any code that reads identity the normal way.

function getDisplaySessionId(c: Context<AppEnv>): string | null

Source: packages/slingshot-game-engine/src/lib/displayRuntime.ts

Build a host-only room key.

function hostRoom(sessionId: string): string

Source: packages/slingshot-game-engine/src/lib/display.ts

True when this request is a display bound to sessionId.

function isDisplayFor(c: Context<AppEnv>, sessionId: string): boolean

Source: packages/slingshot-game-engine/src/lib/displayRuntime.ts

Mint a display token for one session. Host-authorized — the caller enforces that.

function mintDisplayToken(input: { readonly sessionId: string; readonly epoch: number; readonly secret: string | readonly string[]; readonly ttlMs?: number; readonly now?: number; readonly tokenId?: string; }): void

Source: packages/slingshot-game-engine/src/lib/displayToken.ts

Build a per-player private room key.

function playerRoom(sessionId: string, userId: string): string

Source: packages/slingshot-game-engine/src/lib/display.ts

Register the game session policy on an app instance.

Called during setupMiddleware in the plugin lifecycle.

function registerGameSessionPolicies(app: Hono<AppEnv>): void

Source: packages/slingshot-game-engine/src/policy/index.ts

Build a per-role room key.

function roleRoom(sessionId: string, roleName: string): string

Source: packages/slingshot-game-engine/src/lib/display.ts

Build a session broadcast room key.

function sessionRoom(sessionId: string): string

Source: packages/slingshot-game-engine/src/lib/display.ts

Build a spectator room key.

function spectatorRoom(sessionId: string): string

Source: packages/slingshot-game-engine/src/lib/display.ts

Build a stream relay room key.

function streamRoom(sessionId: string, channelName: string): string

Source: packages/slingshot-game-engine/src/lib/display.ts

Build a per-team room key.

function teamRoom(sessionId: string, teamName: string): string

Source: packages/slingshot-game-engine/src/lib/display.ts

Verify a display token’s SIGNATURE and EXPIRY only.

Deliberately does not touch the database. Session existence, status and epoch are authorization questions and are answered by authorizeDisplayToken, which has the session record. Splitting them keeps this half pure and lets the WS path verify cheaply before doing any I/O.

function verifyDisplayToken(token: string, opts: { readonly secret: string | readonly string[]; readonly now?: number },): DisplayTokenVerification

Source: packages/slingshot-game-engine/src/lib/displayToken.ts

Provider-owned package contract for slingshot-game-engine.

Source: packages/slingshot-game-engine/src/public.ts

Canonically cased schema export.

Source: packages/slingshot-game-engine/src/validation/config.ts

Zod schema validating the game engine package config: mount path, WS endpoint, replay, cleanup, disconnect, rate-limit, heartbeat, recovery, and disabled routes.

FieldDescription
cleanupCleanup configuration for completed/abandoned sessions.
disableRoutesRoutes to disable. Keys are entityName.operationOrAction strings.
disconnectDefault disconnect configuration.
heartbeatWS heartbeat configuration.
mountPathMount path for game engine REST routes. Default: /game.
recoveryWS message persistence and recovery configuration.
replayReplay log storage and retention.
wsEndpointWS endpoint name. Default: ‘game’.
wsRateLimitWS rate-limiting configuration (per-socket, rolling window).

Source: packages/slingshot-game-engine/src/validation/config.ts

Capability handle for the game-engine runtime state.

Cross-package consumers resolve it via ctx.capabilities.require(GameEngineRuntimeCap). The legacy GAME_ENGINE_PLUGIN_STATE_KEY plugin-state slot is still published in parallel during the bridge period; new consumers should prefer the cap.

Source: packages/slingshot-game-engine/src/public.ts

All game engine error codes.

Source: packages/slingshot-game-engine/src/errors.ts

GamePlayer entity definition.

Persisted player record linking a user to a session with role, team, score, connection status, and join order. Unique on (sessionId, userId).

Source: packages/slingshot-game-engine/src/entities/gamePlayer.ts

Repository factories for the GamePlayer entity, dispatched by StoreType.

Source: packages/slingshot-game-engine/src/entities/factories.ts

Declarative operations for the GamePlayer entity.

Includes lookups (findBySession, findBySessionAndUser), mutations (incrementScore, updateConnection), and aggregates (countBySession).

Source: packages/slingshot-game-engine/src/operations/player.ts

GameSession entity definition.

Persisted session record with status, phase, round, RNG state, win result, and all timing fields. Indexed by game type, status, join code, host, and parent session.

Source: packages/slingshot-game-engine/src/entities/gameSession.ts

Repository factories for the GameSession entity, dispatched by StoreType.

Source: packages/slingshot-game-engine/src/entities/factories.ts

Structured game engine error.

Carries a machine-readable code from GameErrorCode, an HTTP status (for REST responses), and optional structured details (e.g., Zod validation errors, handler rejection reasons).

Source: packages/slingshot-game-engine/src/errors.ts

Buffered input from a stream channel (consumed in tick handler).

Source: packages/slingshot-game-engine/src/types/models.ts

Base channel definition shared by all modes.

Source: packages/slingshot-game-engine/src/types/models.ts

Runtime state of an active channel.

Source: packages/slingshot-game-engine/src/types/models.ts

Content definition for a game type.

Source: packages/slingshot-game-engine/src/types/models.ts

Content provider contract.

Game definitions declare content providers by name. Each provider loads content from an external source (API, database, user upload) and validates it against the game’s content schema.

Source: packages/slingshot-game-engine/src/types/adapters.ts

A named content provider.

Source: packages/slingshot-game-engine/src/types/models.ts

Session facts the authorization step needs.

Source: packages/slingshot-game-engine/src/lib/displayToken.ts

The claims carried inside a display token. Signed, not secret.

Source: packages/slingshot-game-engine/src/lib/displayToken.ts

Validated, frozen output of defineGame().

Source: packages/slingshot-game-engine/src/types/models.ts

Input shape passed to defineGame(). Accepts partial/optional fields that are resolved to full GameDefinition with defaults.

Source: packages/slingshot-game-engine/src/types/models.ts

Per-game disconnect configuration (overrides plugin-level defaults).

Source: packages/slingshot-game-engine/src/types/models.ts

Read-only snapshot of one active game session runtime.

The snapshot is safe for app-layer inspection and persistence projection. It intentionally does not expose the mutable SessionRuntime internals.

Source: packages/slingshot-game-engine/src/types/state.ts

Optional override input when advancing an active session phase.

Source: packages/slingshot-game-engine/src/types/state.ts

Configuration options for createGameEnginePackage().

Source: packages/slingshot-game-engine/src/types/config.ts

Runtime state stored in getContext(app).pluginState.

Shallow-frozen at registration time. The config and public control surface are independently frozen, while adapter references remain opaque mutable runtime resources and are never traversed by deepFreeze(). Adapters are captured via closure during buildAdapter callbacks.

Source: packages/slingshot-game-engine/src/types/state.ts

Narrow app-facing control surface for active session runtimes.

Apps should use this surface instead of reading mutable SessionRuntime internals from plugin state.

Source: packages/slingshot-game-engine/src/types/state.ts

Mutation callback surface for a live active session.

This intentionally exposes the engine’s sanctioned handler context rather than the underlying mutable SessionRuntime object.

Source: packages/slingshot-game-engine/src/types/state.ts

Result of a session mutation callback.

Source: packages/slingshot-game-engine/src/types/state.ts

Input payload for server-side submission into an active session channel.

Source: packages/slingshot-game-engine/src/types/state.ts

Lifecycle hooks for a game definition.

Source: packages/slingshot-game-engine/src/types/models.ts

Game loop configuration from a game definition.

Source: packages/slingshot-game-engine/src/types/models.ts

Runtime player state visible to clients.

Source: packages/slingshot-game-engine/src/types/models.ts

Runtime session state visible to clients.

Source: packages/slingshot-game-engine/src/types/models.ts

Server-authoritative game timer.

Source: packages/slingshot-game-engine/src/types/models.ts

Result returned by a handler.

Source: packages/slingshot-game-engine/src/types/models.ts

Acknowledgment sent to a client after input processing.

Source: packages/slingshot-game-engine/src/types/models.ts

Computed leaderboard.

Source: packages/slingshot-game-engine/src/types/models.ts

Lifecycle hooks for a game definition.

Source: packages/slingshot-game-engine/src/types/models.ts

Phase definition within a game’s phase graph.

Source: packages/slingshot-game-engine/src/types/models.ts

Minimal player info passed to relay filters and hooks.

Source: packages/slingshot-game-engine/src/types/models.ts

Full mutation API available to all game handlers.

Process handlers, onEnter, onExit, onTick, lifecycle hooks, and win condition checks all receive this context (or the read-only subset).

Source: packages/slingshot-game-engine/src/types/models.ts

Rate limit backend interface.

Matches the pattern from slingshot-polls. The game engine uses this for per-player per-channel rate limiting — the only rate limiter the engine implements itself.

Source: packages/slingshot-game-engine/src/types/adapters.ts

Read-only subset of ProcessHandlerContext.

Used for enabled conditions, checkWinCondition, dynamic config resolution (timeout: (ctx) => ...), and next function resolution.

Source: packages/slingshot-game-engine/src/types/models.ts

Single entry in the replay log.

Source: packages/slingshot-game-engine/src/types/models.ts

Replay log storage adapter.

The default implementation stores entries in-memory per session. Alternative implementations can persist to a durable store (e.g., MongoDB collection, S3 objects).

Source: packages/slingshot-game-engine/src/types/adapters.ts

Context available during role assignment.

Source: packages/slingshot-game-engine/src/types/models.ts

Role definition within a game type.

Source: packages/slingshot-game-engine/src/types/models.ts

Scheduled event for the game loop.

Source: packages/slingshot-game-engine/src/types/models.ts

Single score entry.

Source: packages/slingshot-game-engine/src/types/models.ts

Scoring configuration.

Source: packages/slingshot-game-engine/src/types/models.ts

Seeded PRNG interface exposed to handlers via ctx.random.

Source: packages/slingshot-game-engine/src/types/models.ts

Session lease adapter for multi-instance mode (§32).

Uses Redis-backed atomic leases to ensure a session is only active on one instance at a time. The owning instance renews the lease periodically. If the lease expires, another instance can claim it.

Source: packages/slingshot-game-engine/src/types/adapters.ts

Session-level async mutex for serializing state mutations.

Source: packages/slingshot-game-engine/src/types/models.ts

Sub-phase definition within a parent phase.

Source: packages/slingshot-game-engine/src/types/models.ts

State sync configuration.

Source: packages/slingshot-game-engine/src/types/models.ts

Team configuration for a game type.

Source: packages/slingshot-game-engine/src/types/models.ts

Team score entry.

Source: packages/slingshot-game-engine/src/types/models.ts

Runtime turn order state.

Source: packages/slingshot-game-engine/src/types/models.ts

Vote tally result for a vote channel.

Source: packages/slingshot-game-engine/src/types/models.ts

Result of a completed game.

Source: packages/slingshot-game-engine/src/types/models.ts

Who can submit input to a channel.

String literals cover common patterns. Object forms filter by role, state, team, or dynamic player subsets. Function form is fully custom.

Source: packages/slingshot-game-engine/src/types/models.ts

Channel interaction mode.

Source: packages/slingshot-game-engine/src/types/models.ts

Where processed inputs or channel events are relayed.

Source: packages/slingshot-game-engine/src/types/models.ts

Client → Server WS message types.

Source: packages/slingshot-game-engine/src/types/models.ts

Why a token was rejected. Returned rather than thrown so callers can log precisely.

Source: packages/slingshot-game-engine/src/lib/displayToken.ts

Successful display-token claims or a precise non-throwing verification failure.

Source: packages/slingshot-game-engine/src/lib/displayToken.ts

Union type of all game engine error code values.

Source: packages/slingshot-game-engine/src/errors.ts

Handler function signature. All handlers receive ProcessHandlerContext.

Source: packages/slingshot-game-engine/src/types/models.ts

Phase advance trigger strategy.

Source: packages/slingshot-game-engine/src/types/models.ts

Relay filter function for custom channel relay.

Source: packages/slingshot-game-engine/src/types/models.ts

All replay event types.

Source: packages/slingshot-game-engine/src/types/models.ts

Rule controlling which other roles a given role can see.

Source: packages/slingshot-game-engine/src/types/models.ts

Server → Client WS message types.

Source: packages/slingshot-game-engine/src/types/models.ts

Session status state machine states.

Source: packages/slingshot-game-engine/src/types/models.ts

Define a game type.

Takes a GameDefinitionInput with optional fields, resolves defaults, and returns a frozen GameDefinition ready for registration.

Source: packages/slingshot-game-engine/src/defineGame.ts