NCG 5V5
SQUAD BUILDER
POWERED BY SAMSTA AI
HEXTECH LOBBY ENGINE

About NCG Squad Builder

What the engine does, where the numbers come from, and how it actually picks the teams.

◆ 01

The Pitch

A private, statistics-first team builder for the NCG friend group of 15 League of Legends players. No captain's-pick drama, no ego drafting, no "well I feel like my team's better". Two clicks produce two teams the math insists are as even as possible.

1

Pick 10 of 15

Toggle the summoners in tonight's lobby. Everyone not playing sits out — no pressure, no last-minute shuffling.

2

Hit SUMMON THE RIFT

The balancer runs an exhaustive search over every valid 2-team partition that locks one role per slot. The highest-scoring split wins — deterministic, reproducible.

3

Get a Deep Read

The Hextech Oracle generates a personal, stat-cited analysis: who's paired with who and why, key head-to-heads across the teams, X-factors, and a final verdict.

"We built this to end the weekly argument about who should captain."

— Samsta, host
◆ 02

The Data

Every rating the balancer uses comes from Riot's official match-v5 API — no scraping, no third parties. Each night the cron pulls the newest matches from each player's history, adds them to the archive, and the per-role profile updates itself.

Queues we count

Only serious Summoner's Rift modes. ARAM, URF, One-for-All and custom games are filtered out because they don't reflect real role skill.

Normal Draft (400) Ranked Solo/Duo (420) Ranked Flex (440) Quickplay (490)

Stats we extract per match, per role

Games played
Sample size per role — determines statistical confidence.
Win rate
Normalized to 0-100 on a 35% → 65% scale. Below 35% = 0 score, above 65% = 100.
Average KDA
(Kills + Assists) / Deaths, averaged over all games in role. A 4.0 KDA maps to a 100 combat score.
Kill participation %
How often you show up for team kills. Shows engagement and map presence.
Damage per minute
Damage to champions divided by game length. 800 DPM = elite carry output.
CS per minute
Farm efficiency. More meaningful in TOP/MID/BOT than in JG/SUP.
Vision score
Ward placements + denials. The quiet stat that separates good supports from great ones.
Champion pool depth
How many distinct champs you've played 2+ games on in this role. Capped at 8 for scoring.
Rank (Flex + Solo/Duo)
Current tier, division, and LP. Normalized to 0-100 across Iron → Master.
Recent form
Signed win-rate delta on the last 20 games vs historical baseline. Catches hot streaks and slumps.
ℹ︎
Scale of the pull. The initial population crunched 585 eligible matches across 14 players (dangalang98 is ARAM-only, no SR data). The nightly cron adds new matches — at your group's pace, that's 30-100 new matches per day being fed to the aggregator.
◆ 03

The Algorithm

Two layers: a scoring function that rates each player in each role 0-100, and a partition search that finds the most balanced way to split 10 players into two teams of 5.

Step 1 · Per-role skill score

For each player in each role they've played ≥3 games, the engine blends five signals into a single 0-100 number:

RANK
25%
Tier + division + LP, normalized Iron → Master on a 0-100 scale.
ROLE WIN RATE
25%
Win rate specifically in this role. 35% WR = 0, 65% WR = 100, linear in between.
COMBAT
20%
Blended KDA (50%) + KP% (25%) + DPM (25%). Rewards both efficiency and impact.
CHAMPION POOL
15%
How many different champs you've played 2+ games on in the role. Flexibility matters.
RECENT FORM
15%
Last-20-games WR delta vs historical. A +0.1 form signal = +5 on the score.

Step 2 · The partition search

With 10 players and 5 role slots per team, there are ~200-500 valid role-locked partitions for any given selection (depending on role-feasibility per player). The algorithm exhaustively evaluates all of them and picks the one that minimizes this objective:

balance_score = max(0, 100 - |team_A_power - team_B_power|)
within_penalty = stddev(team_A) + stddev(team_B)
off_role_penalty = Σ |main_role_score - assigned_role_score|
final = balance_score - 0.3·within_penalty - 0.65·off_role_penalty

Why this matters

It's balanced two ways at once
Team totals are close (balance_score) and each team's internal spread is tight (within_penalty). No team has 4 studs and a throwaway — that's a stacked team, not a balanced one.
It respects who plays what
The off-role penalty discourages putting a support main in top lane. We could force it, but your friend will rage-quit.
It's exhaustive, not heuristic
The search actually looks at every valid partition — no "good enough" approximations. If a better split exists, the algorithm finds it. Runs in under 50ms per lobby.
It's deterministic
Same 10 players in, same teams out. Every time. No random seeds, no "re-roll for a better result" nonsense. If you don't like the split, the answer is to swap a player, not hope for different dice.