Skip to content

Limited Events ​

Limited Events generate Sealed pools and Draft pods outside a match. Completed events produce deck-source provenance that can be submitted to normal sealed or draft matches.

Create ​

ts
// A fixed seed makes generated packs reproducible for tests and examples.
const 
draftEventAccess
= await
simulatorClient
.
limitedEvents
.
create
({
kind
: 'draft',
setCode
: 'SOR',
playerCount
: 4,
// Per-round booster sets; only `chaosDraft` fills this, a plain draft // repeats `setCode` for every round.
draftRounds
: [],
// Turns on the per-pick countdown that auto-picks when a seat times out.
pickTimerEnabled
: false,
seed
: '7',
})

Supported event sizes:

  • Sealed: 1-12 players.
  • Draft: 4-12 players.

The response contains eventId, seatIndex, seatToken, and a viewer-private snapshot.

Join ​

ts
// Joining with event access fills the next open seat in the pod.
const 
draftSeatAccess
= await
simulatorClient
.
limitedEvents
.
join
(
draftEventAccess
)

Joining fills the next open seat. The returned access object includes eventId, seatIndex, seatToken, and a viewer-private snapshot, and it can be passed directly to later Limited Event calls.

Keep direct-seat presence live ​

Direct HTTP-created events need one session per human seat. Socket liveness lets server distinguish active humans from abandoned tabs and pushes changed snapshots without polling.

ts
const 
limitedEventSession
=
simulatorClient
.
limitedEvents
.
createSession
(
draftEventAccess
)
limitedEventSession
.
on
('snapshot',
snapshot
=>
console
.
log
(
snapshot
.
phase
.
kind
))
await
limitedEventSession
.
connect
()
// Closing allows a 60-second reconnect grace. Explicit Leave is immediate.
limitedEventSession
.
close
()
await
simulatorClient
.
limitedEvents
.
leave
(
draftEventAccess
)

Lobby and tournament room sockets own presence for their Limited Events; do not open an additional direct-event session for room-issued access.

Fetch state ​

ts
// Public fetch: no viewer-private pack, pick, or pool details.
const 
publicLimitedEventSnapshot
= await
simulatorClient
.
limitedEvents
.
get
(
draftEventAccess
.
eventId
)
// Private fetch: seat token unlocks this player's viewer state. const
privateLimitedEventSnapshot
= await
simulatorClient
.
limitedEvents
.
get
(
draftEventAccess
)
console
.
log
(
publicLimitedEventSnapshot
.
phase
.
kind
,
privateLimitedEventSnapshot
.
viewer
)

Without a token, viewer is omitted. With a valid token, the snapshot includes private leader choices, active pack cards, review-visible drafted cards, or a completed deck source.

Draft cardId values are card ids from generated packs. They can be resolved with simulatorClient.cards.get() like any deck card id.

Draft commands ​

Pick a leader:

ts
// Pick from the private leader choices visible only to this seat.
const 
leaderChoiceCardId
=
draftEventAccess
.
snapshot
.
viewer
!.
leaderChoices
[0]!
await
simulatorClient
.
limitedEvents
.
applyCommand
(
draftEventAccess
, {
type
: 'pickLeader',
cardId
:
leaderChoiceCardId
,
})

Pick from the active pack:

ts
// Refresh before picking so the active pack matches the server state.
const 
activePackSnapshot
= await
simulatorClient
.
limitedEvents
.
get
(
draftSeatAccess
)
const
selectedDraftCardId
=
activePackSnapshot
.
viewer
!.
activePack
[0]!.
cardId
await
simulatorClient
.
limitedEvents
.
applyCommand
(
draftSeatAccess
, {
type
: 'pickCard',
cardId
:
selectedDraftCardId
,
})

Ready after a review gate:

ts
await 
simulatorClient
.
limitedEvents
.
applyCommand
(
draftSeatAccess
, {
type
: 'readyForNextDraft' })

Build a match deck from a completed event ​

ts
const 
completedDraftSnapshot
= await
simulatorClient
.
limitedEvents
.
get
(
draftSeatAccess
)
// Deck source proves that match cards came from the generated draft pool. const
draftDeckSource
=
completedDraftSnapshot
.
viewer
!.
deckSource
!
const
draftMatchAccess
= await
simulatorClient
.
matches
.
create
({
format
: 'draft',
playerCount
: 2,
hostDeck
: {
leader
:
draftDeckSource
.
leaders
[0]!,
leaders
: [], // Twin Suns only; a Limited deck has one leader.
base
:
draftDeckSource
.
commonBases
[0]!,
cards
:
draftDeckSource
.
pool
.
slice
(0, 30),
sideboard
: [], // Limited decks reject a non-empty sideboard.
},
hostName
: 'Host',
hostAuthenticated
: false,
historyIdentities
: [],
aiOpponents
: [],
formatSetup
: {
type
: 'draft',
// Provenance lets match deck validation check the completed draft pool.
seatCount
:
completedDraftSnapshot
.
playerCount
,
packs
:
draftDeckSource
.
packs
,
pool
:
draftDeckSource
.
pool
,
commonBases
:
draftDeckSource
.
commonBases
,
}, })
console
.
log
(
draftMatchAccess
.
matchId
)

Deck validation uses the submitted provenance to confirm that leaders and deck cards came from the generated pool.

Released under the MIT License.