This vignette models a League of Legends Worlds style event:
- A Swiss stage where all 16 teams compete over several rounds,
- The top 8 advance to a single-elimination top-cut bracket.
This is the canonical linear chain pattern — two stages in sequence with no branching. It demonstrates:
-
swiss("open", rounds = 5)for a Swiss-system stage, -
single_elim("top_cut", take = top_n(8))reading from the prior stage automatically (nofrom =needed), -
top_n(8)as the simplest flat routing selector, - the auto-advance default, and
- full inspection with
stage_status(),standings(), andwinner().
1) Define the entrants
teams <- c(
"Gen.G", "T1", "Hanwha Life", "Dplus KIA",
"BLG", "TES", "LNG", "JDG",
"G2", "Fnatic", "MAD Lions", "BDS",
"Cloud9", "Team Liquid", "FlyQuest", "100 Thieves"
)
length(teams)2) Define the tournament
Because the pipeline is a straight line, from is never
written. The single_elim stage implicitly reads from
swiss via previous_stage().
trn <- tournament(teams) |>
swiss("open", rounds = 5) |>
single_elim("top_cut", take = top_n(8))This is the entire routing definition: 16 teams play a 5-round Swiss; the top 8 by Swiss standings advance to a single-elimination bracket.
3) Preflight check (spec path)
When reusing a format across multiple events, define a spec first and validate before building.
worlds_spec <- spec() |>
swiss("open", rounds = 5) |>
single_elim("top_cut", take = top_n(8))
validate(worlds_spec, n = 16) # passes
# Build for this year's entrants
trn <- worlds_spec |> build(teams)4) Inspect the Swiss schedule
stage_status(trn)
open_ms <- matches(trn, "open")
nrow(open_ms) # 5 rounds × 8 matches = 40 matches
head(open_ms)5) Enter Swiss results
Round-by-round entry. Swiss schedules are generated round-by-round as results come in, so you’ll see new pending matches after each round.
for (i in seq_len(nrow(open_ms))) {
trn <- trn |> result("open", match = open_ms$id[i], score = c(1, 0))
# Refresh pending matches — Swiss generates each round dynamically.
open_ms <- matches(trn, "open")
}After the final Swiss result, the top-cut stage materializes automatically.
6) Confirm advancement
stage_status(trn)
# stage status complete total materialized
# open complete 40 40 TRUE
# top_cut active 0 7 TRUE
standings(trn, "open") # full Swiss standings, 1st through 16th
matches(trn, "top_cut") # 8-team bracket7) Run the top-cut bracket
cut_ms <- matches(trn, "top_cut")
for (i in seq_len(nrow(cut_ms))) {
trn <- trn |> result("top_cut", match = cut_ms$id[i], score = c(1, 0))
}9) Manual advance mode
For tournament operations where stages advance on an explicit signal
(e.g., after a broadcast break), use
auto_advance = FALSE:
trn <- tournament(teams, auto_advance = FALSE) |>
swiss("open", rounds = 5) |>
single_elim("top_cut", take = top_n(8))
# ... enter all Swiss results ...
# Stage does not advance until you say so:
trn <- trn |> advance("open")