Skip to Content
⚔ BattleMeme docs · early preview · expect rough edges
ProtocolBracket cut table

Bracket cut table

How many fighters get eliminated each round depends on the bracket size M at the start of that round — and M shrinks after each cut. The battle hits _finalize the moment M ≤ 1 or round 4 completes, whichever comes first — so smaller brackets finish in fewer than 4 rounds.

Defined in BattleOrchestrator._cutSizeForRound(round, M) and finalize gate runRound line if (round == TOTAL_ROUNDS || b.active.length <= 1) _finalize(...).

Progression per starting bracket

Each cell is the cut applied during that round. 🏆 marks the round in which the battle finalizes (only one fighter left). Dashes () are rounds that never run.

Starting MR1R2R3R4Total rounds
20 (skip)1 → 🏆2
311 → 🏆2
4111 → 🏆3
51111 → 🏆4
61211 → 🏆4
72211 → 🏆4
81231 → 🏆4
92231 → 🏆4
102331 → 🏆4

Notes

  • M=2 special: round 1’s cut is 0 — the round still has a trade phase, but no eliminations happen. The afterSwap hook auto-advances past zero-cut rounds via nextRoundIsSafeToAutoAdvance, so trades inside R1 keep flowing; the keeper bot only needs to fire at the actual cut. R2 then cuts the loser → finalize.
  • Brackets of 2 and 3 finish in 2 rounds; bracket of 4 in 3 rounds; everything ≥5 plays the full 4 rounds.
  • R4 always cuts M − 1 (whatever’s left → 1 winner). That’s why all paths converge to M=2 going into R4.
  • For M=7 and ≥9, R1 cuts 2 — lookup checks M >= 9 first then M == 7, so M=10 (≥9) and M=7 both yield 2; M=8 falls through to the generic M >= 3 → 1.
  • After each cut, M decreases — subsequent rounds re-evaluate against the new bracket. The table above already does that walk for you.

Example: 6-fighter bracket

Start: [A B C D E F] M=6 After R1: [B C D E F] M=5 (cut 1) After R2: [C D E] M=3 (cut 2) After R3: [D E] M=2 (cut 1) After R4: [E] M=1 (cut M−1 = 1 → winner)

Example: 2-fighter bracket

Start: [A B] M=2 After R1: [A B] M=2 (cut 0 → no elimination, trade phase only) After R2: [B] M=1 (cut 1 → winner, FINALIZE)

No R3 or R4 runs — runRound finalizes the battle the instant b.active.length <= 1.

Lookup function reference

For contract devs: the raw _cutSizeForRound(round, M) lookup (without progression context):

round \ M2345678910
1011112122
2111222333
3111333333
4M − 1 for all M ≥ 2

This is what the function returns for arbitrary (round, M) inputs — but most of these cells are unreachable during a real battle, because the bracket already collapsed to 1 before that (round, M) pair occurs. The progression table above shows only the cells actually visited.

Last updated on