Case study · Pyramids Cup 8 · Wild Rift MENA
Six weeks, four stages, 335 matches. One system ran all of it.
Pyramids Cup 8 is the MENA local circuit inside the Wild Rift Rift Legends ecosystem. Nexaro built and operated the system behind it: a tournament bot, an operations app, a public website and one shared database. The whole season was run by a staff of five: Fog, mer, evil, itach and ananas.
Pyramids Queue and The Vicious Esports, powered by Nexaro. Supported by the Rift Legends Program by The Purge.

The numbers
Cup 8 at a glance
Tournament figures come from the Cup 8 database. Teams and players are counted two ways because six teams entered both qualifiers with different rosters: 60 team entries are 54 distinct teams, and 436 roster places are 364 distinct people. View numbers are reported by the organiser and the creators, and marked so.
Context
The brief
Seven editions of Pyramids Cup came before this one, run on Discord, spreadsheets and manual posting. Each edition grew, and so did the work: every result was typed into five places, and every match night depended on somebody remembering seventeen steps.
For Cup 8 the goal was a season that runs on a system: register, play, verify and publish once, in Arabic and English, with a public record any captain can check without asking an admin.
The season
Two doors in, one road through
Two open qualifiers on separate team pools with separate standings, never merged into one table, because a merged table would rank teams against opponents they never played. A team that qualified from the first could not re-enter the second; every other team could, with a fresh entry.
Qualifier 1
8 to 18 Sep
29 entries, 27 played. 10 Swiss rounds, 134 matches, 283 games. SBO3A went 10-0, the only unbeaten team in either qualifier.
Qualifier 2
22 Sep to 2 Oct
33 entries, all played. 10 Swiss rounds, 167 matches, 344 games. Bigger than the first, with no new campaign in between.
League Stage
7 to 16 Oct
Top six from each qualifier. Two groups of six, Bo3 Fearless, 30 series and 65 games. SBO3A and JSK Esports won their groups 5-0.
Playoffs
22 and 23 Oct
Top four. The teams asked for Bo5 semi-finals; the rule needed all four to agree in writing, and 4 of 4 did. JSK Esports won the Grand Final 3-2.
Rift Legends
Next
JSK Esports and SBO3A go to the Rift Legends Regional Groups. coming for you and 4Cats1Dog go to the Last Chance Qualifier.


The Playoffs, 22 and 23 October
JSK Esports are the champions
Semi-final 1
22 Oct, 19:00
Semi-final 2
22 Oct, 22:00
Third place
23 Oct, 20:00
Grand Final
23 Oct, 22:00
Final placings
JSK Esports
Rift Legends Regional Groups
SBO3A
Rift Legends Regional Groups
coming for you
Last Chance Qualifier
4Cats1Dog
Last Chance Qualifier
SBO3A won sixteen series in a row from 8 September: 10-0 in Qualifier 1, 5-0 in the League Stage and 3-0 in the semi-final. It took JSK Esports all five games of the Grand Final to stop them.
pyramidsqueue.com
The public record, live
The challenge
What a match night actually is
Thirteen matches per round, two rounds a night, run by a staff of five in two languages, for players across nine time zones, on a platform with hard limits.
Sequencing
Swiss round two cannot be paired until every round one result is in. One team that leaves after its own last game delays twenty five others.
Concurrency
Thirteen matches per round, in two waves at 20:00 and 21:30 Cairo, to stagger the load on referees and creators.
Evidence
Every game needs its scoreboard captured while the players are still in the room. Ten seconds during the match, twenty minutes after it.
Hard limits
Discord caps a server at 500 channels and counts categories. Each round uses roughly seventeen.
What we built
Four parts, one database
None of it was bought. Each part was written in response to something that went wrong in an earlier edition, and every number below was counted from the live schema and the repositories.
Nexaro AI, the tournament bot
25 commands · ~17,900 lines of TypeScript
Registration from a pasted roster, a private channel per match scoped to two teams, a referee and a moderator, bilingual rules briefs, byes, ready checks ten minutes before kickoff, team sheets per game, draft and ban tracking, results and scoreboard capture.
Teams OS, the back office
Flutter web · ~75,800 lines of Dart
Rosters per stage, results review, incidents, champion review queue, media hub, staff roles and the bot log. Everything a referee or admin needs that is not a Discord command.
pyramidsqueue.com, the public record
20 public pages · Arabic and English
Live standings per stage, player statistics, champion meta, schedule and bracket, rules, the region map and creators. Pages rebuild only when the data behind them changes.
One shared database
Supabase Postgres · 83 tables · 20 views
Every number is written once and read everywhere. Public data leaves only through checked public views. Migrations are numbered, additive and logged.
244
match channels created
136
team registrations taken
1,014
match events logged
63
incidents logged, each with a written record
Bot and incident counts as of the Cup 8 impact report; they grow every match night.
Operations
A match night, in order
19:00
Pre-flight
A read-only check resolves every team in the next round and fails loudly, by name, if a team sheet would come out blank.
19:30
Draw the round
One command creates every match channel, scopes permissions, posts the brief, records the bye and reports how many channels are left.
19:50
Ready check
Posted ten minutes before kickoff. A moderator approves the start.
20:00
The matches
Team sheets per game, the draft and global ban recorded, the result submitted with screenshots.
23:30
Close the night
Every match submitted before the next round is paired, because Swiss pairs off the last round.
After
Clips and champions
The media hub and the champion review queue. Five minutes, and both go stale fast if skipped.
Before: five places
Discord, a spreadsheet, a bracket site, the website and a social post, each typed by hand. Five places, five chances to disagree.
Now: one entry
A referee submits the result once. Standings, the website and analytics read the same row. The one manual step left, the external bracket site, is named as such rather than hidden.
Competitive integrity
Automation removes typing, never judgement
A published rulebook, applied in the order it is written: eligibility, roster locks between stages, draft rules, evidence for every result, five tiebreakers published before the first match, and sanctions recorded against a player identity so “how many warnings” is a query, not a scroll.
Handled by the system
- Match channel creation and permission scoping
- Ready checks, ten minutes before kickoff
- Bye detection, recording and announcement
- Standings recalculated on every result
- Website rebuild, scoped to the page that changed
- Bilingual messages from stored templates
- Scoreboard rows matched to registered players
- Pre-flight checks before a match night
Still decided by a person
- Whether a result is correct before it is published
- Whether a team sheet is real or an untouched template
- Every tiebreak and every ruling
- Which clips reach the public site
- Which champion corrections are accepted
- Whether a warning is issued, and at what level
- Eligibility, deliberately not automated
3,044
player statistic rows recorded
96.4%
attach to a registered player automatically
111
rows waiting for a person, by design
What went wrong, and what changed
Where the system was tested
Discord's 500 channel ceiling
20 September
The server hit Discord's channel cap mid-tournament. Finished round categories were deleted to free space; results lived in the database and on the website, so only chat was lost.
The bracket command now refuses a batch that will not fit and reports free channels after every round.
A team lookup that failed silently
22 and 23 September
Six teams entered both qualifiers and held two roster rows on one Discord role. The lookup expected one, threw on two, and seven call sites swallowed the error. Team sheets and result attribution degraded with nothing logged.
The lookup is now stage-aware, and the read-only pre-flight check resolves every team before the night starts.
A bye with no channel
Qualifier 1
A team with no opponent got its point recorded but no channel and no message, so it had no confirmation it had not been forgotten.
A bye now gets a channel and a bilingual brief, and still records and announces when there is no room, so a courtesy channel never takes a real match's slot.
One shape connects all three: something failed, was caught, and became a silent fallback. All three now fail loudly instead.
The region
A MENA cup, not one country's
Player entries by declared nationality, top eight of 24
24 countries were declared across 431 of 436 player entries. 14 of the 15 MENA countries in the rulebook are represented.
Everything players read is in Arabic and English: the website with full right-to-left support, the match channel briefs, the ready checks and the warnings, rendered from stored templates staff can edit without a code change.
Discord and creators
The community around the cup
66.3%
new member retention
Discord benchmark: 20%
718
weekly visitors
week to 10 October
5,161
messages in a week
week to 10 October
6,001
voice minutes in a week
week to 10 October

There was no official broadcast. Eight stream creators and four clip creators covered the cup in Arabic, with 70 clips and 27 VODs, for up to 200K stream views and 800K clip views across the season (owner reported). The Grand Final alone peaked at 580 viewers across three live streams: Fog 146, Eazzy 144, boosted 290.
Peak live viewers per creator, creator reported
Outcomes
What Cup 8 proved
A second qualifier can grow inside a live event
33 team entries against 29, four weeks in, with no new campaign between them.
A staff of five can run a 335 match tournament
Because the seventeen steps behind every match are handled by a system rather than by somebody remembering.
Partial data can be published honestly
96.4% of 3,044 player statistic rows attach to a named player automatically. The other 111 wait for a person, and the site says so.
A rulebook survives being applied
Five teams tied on twelve points for three seats. The published tiebreak order resolved it, with the full working written down.
The region is wider than Egypt
24 declared countries, and Tunisia alone sent 50 player entries.
Before Cup 9
What comes next
Close the measurement gap
Clip views, watch time and reach are reported by people today. They should be read from the platforms.
Finish the evidence loop
Players already post end-of-game screenshots. Reading them into lines, with a person confirming, removes the last retyping.
Carry the record forward
Standings, player stats and match history carry into the next edition, so a team's history starts with it.
Separate case study
Pyramids Q Player Platform: profiles, inhouses and fantasy for the off-season
The side project built to grow the player base between cups.
Run your season on a system
The same stack is organisation-scoped: a new tournament or format is configuration, not a new codebase.