eigen_flutter library

Reusable Flutter integration for EigenInteractive game applications.

A game app depends on this package and implements a GameModule. It can install EigenFlutterScope beneath its own application root or use the opinionated eigen_shell package for the complete first-party product.

import 'package:eigen_flutter/eigen_flutter.dart';

EigenFlutterScope(
  module: const MyGameModule(),
  config: appConfig,
  child: const MaterialApp(home: MyHome()),
);

This is the supported game-facing import. It exposes the embeddable scope, configuration, game contract, wire vocabulary, and shared game UI without taking ownership of routing or a root application widget.

Start with the EigenInteractive quickstart and use the task guides for end-to-end TypeScript and Dart examples.

Classes

AppConfig
Whitelabel configuration for one game app built on the engine.
AppTheme
Minimal app theme configuration using Material 3.
AuthGateway
Authentication required by the Flutter presentation package.
AuthStateChange
A single emission of the auth state stream: what happened, and who the session user is now (null when signed out).
AuthUser
The signed-in user as the app sees it: the backend-agnostic twin of the auth provider's session user.
AvatarStorageService
Uploads the signed-in user's avatar.
BearerTokenInterceptor
Adds a bearer token supplied by an identity adapter to engine requests.
Bot
BotRunner
Where a bot brain runs: the port the Flutter adapter implements.
BotSeatableArgs
A candidate bot seating, passed to GameRules.botSeatable.
BotTag
Compact pill that labels a participant as a bot.
Branding
User-facing identity for the app shell.
BudgetConfig
Each player has a personal time bank that drains while they act (Fischer increment).
CommandAccepted
Created
DeviceRepository
Push registrations for the authenticated user's installations.
EigenClient
A configured EigenInteractive backend.
EigenFlutterScope
Installs Eigen's reusable Flutter state beneath an application-owned root.
EigenRng
The engine's deterministic random stream, ported bit for bit from the kernel's deriveRng in server/packages/kernel/src/rng.ts.
EngineConfig
Runtime configuration the framework needs to talk to its backends.
Envelope<TState>
The result of advancing a local game by one transition: the twin of the TypeScript Envelope, and the return of every state hook.
Frame
Friend
FriendRequest
GameCause<TAction>
A rules-scoped move by playerIndex: the TypeScript {kind:"game"} variant.
GameContentContext
Everything GameRules.buildContent needs, bundled into one object.
GameCreationSpec
Declarative description of what is valid when creating a game of this type.
GameFrame
A single observation snapshot of an active or finished game.
GameModule
Contract every game implementor provides.
GamePlayer
Unified game-level player concept.
GameRepository
Everything a client does to a game: discovery, the waiting room, moves, and the live frame feed.
GameRules<TObs, TAction, TConfig>
The client-side surface of one schemaVersion of the game: the Dart twin of the same-named TS GameRules unit.
GameSession
One game's live session, as the client holds it: the newest snapshot the server stated, plus the frame being rendered and the one it replaced.
GameSocket
Opens a game's socket and keeps it open for the screen's lifetime.
GameSummary
GameTransition
The step from one frame to the next: the unit a game animates.
GuestTag
Compact pill that labels a player as an anonymous guest.
HttpDate
Parses the RFC 1123 dates HTTP uses.
InlineBotRunner
A BotRunner that runs the brain on the caller's isolate.
InMemoryLocalGameStore
A LocalGameStore held in memory: what tests and previews run on.
LifecycleAction
The engine-constructed payload of a lifecycle action, recorded verbatim in the transition log: the twin of the TypeScript LifecycleAction.
LifecycleAutoForfeit
The engine-driven forfeit (an account purge), which a local game only ever sees when replaying a record the server resolved.
LifecycleCause<TAction>
An engine-scoped lifecycle action: the TypeScript {kind:"lifecycle"} variant.
LifecycleForfeit
A voluntary resign by playerIndex.
LifecycleTimeout
The clock ran out for every seat in the pending set.
LocalActionIntent
A move by seat, decided against expectedVersion.
LocalBotActionArgs<TObs, TConfig>
A seated bot's turn to move: the twin of the TypeScript BotActionArgs.
LocalBotJob
One bot's turn to think, as the engine hands it to a BotRunner.
LocalCommitPlan
The transition to apply: the twin of the kernel's CommitPlan.
LocalCommitResult
What one commit produced: either a plan to apply, or a refusal. Sealed so a caller must handle both, where the TypeScript twin needs an isRejected type guard.
LocalEffect
Something the engine should do after applying a plan: the twin of the kernel's Effect, holding only the one a local game has.
LocalForfeitIntent
Resign seat. Unconditional: no pending, version or deadline guard.
LocalGameEngine
The device's Durable Object: one serialized command queue over one local game (decision 0012).
LocalGameMeta
The game's standing configuration: the twin of the kernel's GameRow, and the local record's meta.
LocalGameRecord
A whole local game as the device holds it: the record LocalGameStore persists and LocalGameEngine advances.
LocalGameRules<TState, TObs, TAction, TConfig>
One schemaVersion of a game, implemented a second time in Dart so the device can play it with no network: the twin of the TypeScript GameRules hooks in server/packages/rules/src/contract.ts.
LocalGameStore
Where local games live between sessions: the port the Flutter adapter implements with Drift on native and on the web (decision 0012).
LocalGameSync
Carries a device's local games to the server, where they become ordinary games (decision 0012).
LocalGameTransition
One committed transition of a local game: what the Durable Object stores per version, minus the engine's clocks.
LocalIntent
What the device asks the kernel to do: the twin of the kernel's Intent, restricted to the three a local game can raise.
LocalObservationFrame
One seat's projected frame: the twin of the kernel's ObservationFrame. No raw state escapes the kernel except through this projection.
LocalRecord
LocalRejected
An intent the kernel refused: the twin of the kernel's Rejected. A value, not a throw, because a rejection is part of the normal protocol.
LocalRejection
LocalSeat
One seat of the roster: the twin of the kernel's Seat.
LocalStartIntent
Begin the game at version 0 with a freshly minted base seed.
LocalStateRow
The latest committed transition: the twin of the kernel's StateRow, without the clocks an untimed game has no use for.
LocalSyncReport
What one LocalGameSync.syncAll pass did.
LocalTransition
LocalTransitionAction
The transition log entry for one commit: the twin of the kernel's TransitionAction, and the exact JSON shape the import route replays.
LocalTransitionRow
LocalTransitions
LocalTransitionsApplied
LocalWakeBot
A bot seat became pending and its brain should run.
MySeat
A sealed union of the two ways the current user relates to a game.
NoCause<TAction>
The opening frame, which no action produced: the TypeScript null.
ObservationSlice<TObs>
One participant's view of the state, produced by LocalGameRules.computeObservation: the twin of the TypeScript ObservationSlice.
Outcome
PerActionConfig
Each turn gets a fresh fixed window of minSecondsmaxSeconds.
Player
PlayerAvatar
Circular avatar for a player, with customizable size.
PlayerBatchLoader
Coalesces single-id player lookups into one batch request per frame.
PlayerLimits
The seats one config may be played with, returned by GameRules.playerLimits.
PlayerRepository
Fetches public player identities, humans and bots alike.
PlayersContext
Player identity data passed to GameRules.buildContent.
PlayerTimerBuilder
Headless widget that computes a single player's remaining budget time, exposing it to a builder callback every second.
Profile
ProfileRepository
The signed-in user's own profile.
Rating
RatingDelta
RatingHistoryEntry
RatingIdentity
RatingPoolArgs
The chosen game settings, passed to GameRules.ratingPool.
RatingRepository
Player ratings and the caller's own rating log.
Rng
Deterministic random source for one transition: the twin of the TypeScript Rng in server/packages/rules/src/contract.ts.
Seat
Seated
The current user holds seat index in the game (a participant).
ServerClock
Server time, as best the client can tell.
Session
SocialRepository
The friend graph: friends, pending requests, blocks, and user search.
SoloStarted
TimingContext
Timing data passed to GameRules.buildContent for every active game.
TimingModeConfig
Configuration for one timing option shown in the new-game dialog.
TransitionAction
TransitionCause<TAction>
What produced the state being projected: the twin of the TypeScript TransitionCause, whose null variant is NoCause here so the type stays non-nullable and a switch stays exhaustive.
TurnTimerBuilder
Headless widget that ticks toward a deadline, exposing the remaining Duration to a builder callback every second.
UnavailableAuthGateway
Authentication boundary used when an app has not installed an adapter.
UntimedConfig
No time limit. Players act at any pace. No additional controls rendered.
Viewer
The current user has no seat: a non-participant viewing a replay.

Enums

ActionSubmitResult
How a submitted action resolved, reported to the game through the future returned by GameContentContext.onAction.
AuthEvent
Auth lifecycle events surfaced by the authentication state stream.
AuthUpgradeResult
Result of trying to turn a guest session into a Google-backed account.
BotType
How this bot's moves are produced: engine in the server's game rules, external by a hosted service, local by a brain shipped in the client.
DevicePlatform
Push-delivery platforms understood by the engine.
ErrorCode
A stable machine code identifying why a request failed.
FrameTypeEnum
FriendRequestDirectionEnum
FriendRequestResultStatusEnum
GameAccess
GameOrigin
Where a game is played. online is decided entirely by the server; local was played on the device against on-device bots and imported afterwards.
GameStatus
LifecycleType
The trigger of a lifecycle action: the twin of the TypeScript LifecycleType.
LocalActionKind
Which species a logged transition is: the twin of the TypeScript ActionKind. A game action is rules-scoped and rejectable; a lifecycle action is engine-scoped and always resolves.
LocalActionType
The performer recorded on a logged transition: the twin of the TypeScript ActionType.
LocalActor
Who submitted a move. A local game logs a brain's move as bot, which is exactly what the import route replays it as.
LocalRejectCode
Why the local kernel refused an intent: the twin of the kernel's RejectCode in server/packages/kernel/src/errors.ts, minus the codes an untimed single-device game cannot produce.
LocalSyncOutcome
How one game's synchronization ended.
LocalTransitionKindEnum
OutcomeResultEnum
SeatTypeEnum
TransitionActionKindEnum
TransitionActionTypeEnum

Extensions

AuthStateChangePatterns on AuthStateChange
Adds pattern-matching-related methods to AuthStateChange.
AuthUserPatterns on AuthUser
Adds pattern-matching-related methods to AuthUser.
LocalRejectCodeError on LocalRejectCode
The wire error code each rejection surfaces as, so a local rejection and a server rejection reach the UI through one path.

Constants

activeGamesBucket → const String
Games still playable - the home screen's list.
finishedGamesBucket → const String
Games that have ended - the history list.
historyPageSize → const int
Number of games fetched per history page.
kMaxBudgetSeconds → const int
Infra hard maximum for budget (accumulated) clock (10 days).
kMaxTurnSeconds → const int
Infra hard maximum for per-action turn time (30 days).
kMinBudgetSeconds → const int
Infra hard minimum for budget (accumulated) clock (seconds).
kMinTurnSeconds → const int
Infra hard minimum for per-action turn time (seconds).
lobbyPageSize → const int
Number of games fetched per lobby page.
localSyncBatchSize → const int
The most transitions one append carries. The route accepts 200, and a long game syncs as several batches rather than one body the server would refuse.
profileGamesPageSize → const int
Number of games shown in the replay list on a player's profile.

Properties

appConfigProvider AppConfigProvider
The active AppConfig.
final
currentGameModuleProvider CurrentGameModuleProvider
The active GameModule.
final
localPlayAvailableProvider LocalPlayAvailableProvider
Whether this build can play any game on the device at all: the local arm of the solo picker's availability.
final

Functions

buildGameSocketUri({required String apiBaseUrl, required String gameId, required String ticket}) → Uri
Builds the browser-compatible authenticated socket URI.
engineCall<T>(Future<T> run()) → Future<T>
Runs a generated API call, rethrowing a server-reported failure as the domain EngineException so nothing above the data layer handles Dio types.
engineData<T>(Future<Response<T>> run()) → Future<T>
Runs a generated API call and returns its decoded body, unwrapping the Response.
fanOutObservations(AnyLocalGameRules rules, {required Object? state, required List<int> pending, required int participantCount, required TransitionCause<Object?> cause, required bool isReplay, required Object? config}) → List<LocalObservationFrame>
Projects the new state into one slice per seat: the port of the kernel's fanOutObservations.
jsonEquals(Object? a, Object? b) → bool
Deep equality for two serializations of the same JSON value.
localCommit({required LocalGameMeta game, required LocalStateRow? state, required List<LocalSeat> roster, required LocalIntent intent, required AnyLocalGameRules rules}) LocalCommitResult
One state transition in, one plan or rejection out: the port of the kernel's commit() in server/packages/kernel/src/commit.ts, restricted to what a local game can need.
localFrame(LocalGameRecord record, {required int playerIndex, required int version}) Frame?
One seat's Frame at version, or null when that seat has no projection there (a seat nobody holds).
localRecordFromRemote({required LocalRecord remote, required AnyLocalGameRules rules}) LocalGameRecord
Rebuilds the device's record of a local game from the server's copy.
localSession(LocalGameRecord record, {required int playerIndex}) Session
Builds the Session snapshot a local game presents, so a game screen, replay, history and buildContent consume a local game through the existing session path with no game code change (decision 0012).
newLocalGameId([Random? random]) → String
A fresh game id: a random UUID the device mints, which the server adopts verbatim when the game is imported.
newLocalSeed([Random? random]) → String
A fresh base RNG seed: 128 random bits, hex-encoded, exactly like the kernel's randomSeed().
resolveAvatarUrl(String? avatarUrl, String apiBaseUrl) → String?
Resolves a stored avatarUrl into something an image widget can load.
usableLocalBots(List<Bot> bots, GameModule module, {required Map<String, dynamic> config}) → List<Bot>
Bots this build can run on the device for a game using config.

Typedefs

AccessTokenProvider = Future<String?> Function()
Obtains the current access token for one engine request.
AnyLocalGameRules = LocalGameRules<Object?, Object?, Object?, Object?>
A LocalGameRules unit with its payload types erased: the twin of the TypeScript AnyGameRules, and what the kernel, the engine and the bot runner hold.
GameSocketEvent = Session
The socket carries exactly one message: the complete live truth about the game as this seat sees it.
GamesPage = ({List<GameSummary> games, String? nextCursor})
One page of a paged game list, plus the token that continues it.
LocalBotAction<TAction, TObs, TConfig> = FutureOr<TAction> Function(LocalBotActionArgs<TObs, TConfig>)
One local bot brain: the value type of LocalGameRules.botActions, and the twin of the TypeScript BotAction.

Exceptions / Errors

EngineException
A failure the engine server itself reported: a non-2xx response carrying the { error, code? } envelope.
IllegalMoveException
A move the game's rules refuse: the twin of the TypeScript IllegalMoveError.
LocalBotFailed
A bot's turn failed: its brain threw, answered with a move the rules refused, or has no registry row on this device.
LocalGameBugError
A broken game or engine invariant: the twin of the TypeScript GameBugError.
PlayerNotFoundException
Thrown when a player lookup matches no row.
UnsupportedGameSchemaException
Thrown when a game's games.schema_version has no entry in GameModule.versions. It was created by a newer app version and can't be loaded until the user updates.