The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

LoL Worlds: Swiss Stage to Top-Cut Bracket

library(bracketeer)

This vignette models a League of Legends Worlds style event:

This is the canonical linear chain pattern — two stages in sequence with no branching. It demonstrates:


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 bracket

7) 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))
}

8) Outcomes

winner(trn)
rankings(trn)
routing_log(trn)

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")

10) Batch result entry

results() accepts a data frame for entering multiple results at once.

round1 <- data.frame(
  match  = matches(trn, "open")$id,
  score1 = rep(1L, 8),
  score2 = rep(0L, 8)
)

trn <- trn |> results("open", round1)

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.