Match Session
MatchSession is the high-level live match helper returned by simulatorClient.session.create().
const matchSession = simulatorClient.session.create(hostAccess, {
handshakeTimeoutMs: 10_000,
})
await matchSession.connect()For the full match flow, read Match Lifecycle. This page is the class-level quick reference.
State
// These cached values update as matching server frames arrive.
matchSession.connectionState // 'idle' | 'connecting' | 'open' | 'closed'
matchSession.seat // 'one' | 'two' | 'three' | 'four' | undefined
matchSession.snapshot // GameState | undefined
matchSession.aiStatus // AiStatusPayload | undefined
matchSession.events // readonly GameEvent[]
matchSession.errorMessages // readonly string[]The state getter returns the same renderable data without exposing seatToken.
Events
const stopSnapshotListener = matchSession.on('snapshot', matchSnapshot => {
// Snapshot listeners are the main hook for UI state updates.
render(matchSnapshot)
})
// Call the returned function when the UI no longer needs updates.
stopSnapshotListener()on() returns the unsubscribe function. Listener callbacks are typed by event name.
| Event | Payload |
|---|---|
change | MatchSessionState |
connectionState | ConnectionState |
welcome | WelcomePayload |
snapshot | GameState |
aiStatus | AiStatusPayload |
event | GameEvent |
error | ErrorPayload |
pong | PongPayload |
message | ServerMessage |
interactionCue | CardInteractionCue |
historySnapshot | MatchHistorySnapshot |
historyEntry | MatchHistoryFeedEntry |
reconnectState | MatchSessionReconnectState |
Lifecycle
const premierHostDeck = {
leader: 46102,
leaders: [],
base: 308,
cards: premierMainDeck,
sideboard: [],
}
const premierGuestDeck = {
leader: 46107,
leaders: [],
base: 309,
cards: premierMainDeck,
sideboard: [],
}
await matchSession.createMatch({
format: 'premier',
playerCount: 2,
hostDeck: premierHostDeck,
hostName: 'Host',
hostAuthenticated: false,
historyIdentities: [],
aiOpponents: [],
})
await matchSession.joinMatch(hostAccess, {
deck: premierGuestDeck,
name: 'Guest',
authenticated: false,
historyIdentities: [],
})
await matchSession.connect({ matchId: hostAccess.matchId, seatToken: hostAccess.seatToken })createMatch() and joinMatch() store the returned private access, seed state from the HTTP snapshot, then connect the socket.
Commands
matchSession.ready()
matchSession.sync()
matchSession.ping('host-latency-1')
matchSession.undo()
matchSession.setAiPaused(true)
matchSession.sendCommand('pass')
matchSession.sendFormatEvent({ type: 'readyNextGame', ready: true })Outbound envelopes are validated before being sent only when the client was created with a validator. See Runtime validation.
undo() restores the previous server checkpoint for the latest accepted player action. In AI matches, one human undo also rolls back any AI responses after that action and the server resumes the undo-created AI pause after the next successful human mutation. setAiPaused() is manual AI control and does not change gameplay state.
Waiting
await matchSession.waitForSnapshot(matchSnapshot => matchSnapshot.phase === 'action', {
timeoutMs: 15_000,
})The helper returns the current snapshot immediately when it already matches.
Reconnect
await matchSession.reconnect({ handshakeTimeoutMs: 5_000 })Reconnect closes the current socket, reopens with the stored match id and seat token, waits for handshake, and requests a fresh snapshot.
Close
matchSession.close()Close is idempotent and detaches socket listeners.
