Sector's Edge Autobalance Specification

This has been a common topic lately so here are all the details of the current system.

Criteria

The server checks if the teams are unbalanced on each death, team change, player join and player leave

Teams are not unbalanced if:

  • Sandbox or trailer mode is enabled
  • A tournament or scrimmage is running
  • < 3 minutes left in the round
  • Gamemode is FFA
  • Team size difference is <= 1

Teams are unbalanced if:

  • Team sizes are:
    • 2 (or more) vs 0
    • 3 (or more) vs 1 (or less)
    • 4 (or more) vs 2 (or less)
  • Team power difference is >= 10

Player Values

Each player has the following values:

pubPower
A player’s pubPower is their average scoreboard position over their past 50 matches. Note this is called pubPower to refer to public/casual matches.

The max values for each mode are:

  • 6 for SPI | STA
  • 16 for SAL
  • 24 for BRK | CTF

A larger pubPower is better. For example, if a player has their first match of CTF and places at the top of the scoreboard (out of all players in the match), their pubPower will become 24.

sortedPower
A player’s sortedPower is calculated by sorting all players ascending by their pubPower for this gamemode, then assigning each player an incrementing value.
5 is added to this incrementing value to make each player’s presence worth more. This helps avoid situations like 5v10s

// Sort players ascending by their individual power
var sorted = players.OrderBy(x => x.pubPower).ToList();

for (int i = 0; i < sorted.Count; i++)
	sorted[i].sortedPower = i + 5;

sortedPointsPower - v1.2.2 (Upcoming)
A player’s sortedPointsPower is calculated by sorting all players ascending by their current in-game points, then assigning each player an incrementing value.
5 is added to this incrementing value to make each player’s presence worth more. This helps avoid situations like 5v10s

// Sort players ascending by their current in-game points
var sorted = Players.OrderBy(x => x.points).ToList();

// Start at 5 to make each player's presence worth more
int currentPower = 5;

for (int i = 0; i < sorted.Count; i++)
{
    var p = sorted[i];

    p.sortedPointsPower = currentPower;

    // All players on 0 points are given a value of 5
    if (p.points > 0)
        sortedPointsPower++;
}

CurrentAveragePower

v1.2.1 (Current)
A player’s CurrentAveragePower is simply their sortedPower.

v1.2.2 (Upcoming)
A player’s CurrentAveragePower is simply calculated by (sortedPower + sortedPointsPower) / 2. This means that if team A is destroying team B, the autobalance system can detect that the match is unbalanced as team A’s total power will increase.

A team’s power is simply calculated by accumulating the total CurrentAveragePower of all players in that team.

Autobalancing Process

When a player dies / changes teams / leaves, or a new player joins a team, the system recalculates the total power of each team and checks if the power difference between teams is >= 10.

If true, the system will mark team A as overpowered and after 20 seconds will attempt to balance the teams. When a player on team A dies, they will be moved to the weaker team (team B) if:

  • They are not in a party
  • They have not been autobalanced yet
  • They are in the bottom 2/3rds of players on their team (excluding players that are in a party or have been autobalanced)
public bool CanBeAutobalanced(Player p)
{
    if (p.hasBeenAutobalanced || p.InParty)
        return false;

    // Get all eligible players in their team
    List<Player> sorted = new List<Player>();

    foreach (var q in Players)
        if (q.teamType == p.teamType && !q.hasBeenAutobalanced && !p.InParty)
            sorted.Add(q);

    // Order by points
    sorted = sorted.OrderBy(x => x.points).ToList();

    int max = (int)(sorted.Count * 0.67);

    // This player can be autobalanced if they are in the bottom 2/3rds of their team
    for (int i = 0; i < max; i++)
        if (sorted[i].ID == p.ID)
            return true;

    return false;
}

Note that the player will not be moved to team B if that will cause team B’s total power to be greater than team A’s power + 10, since that means the autobalance system will now try to balance someone from team A to team B.

Once a player has been moved to the weaker team, the server will check if the teams are now balanced. If not, it will continue to attempt to autobalance players that are on the strongest team when they die.

2 Likes

Great post. It’s very transparent and helps us understand how balancing works. Several of my thoughts pertains these specific sections

They are in the bottom 2/3rds of players on their team (excluding players that are in a party or have been autobalanced)

Will this cause top 1/3 players to remain stacked on one team even if the other team top 1/3 players left? It will just move even more weaker players to the left and allows a strong player to join the stacked team later on?

5 is added to this incrementing value to make each player’s presence worth more. This helps avoid situations like 5v10s

This feels more of a RNG than actual balancing. If I may suggest focusing on actual metrics to balance? It will skew things less and allow you to measure the data more accurately?

(sortedPower + sortedPointsPower) / 2

I like this change. It actually reviews the past performance with the current match performance. Great idea!

1 Like

Will this cause top 1/3 players to remain stacked on one team even if the other team top 1/3 players left?

Yeah, this is the case too if a party of 4 joins a match and reaches the top of the scoreboard. The system will balancing more players onto the weaker team to compensate, which usually turns out pretty balanced. It really depends on the caliber of the players in the match

5 is added to this incrementing value to make each player’s presence worth more.

Originally the system didn’t add 5, which led to situations like 3v8s in Salvage. While that’s balanced in terms of total player power, it was very difficult for that team with 3 people to contest the objective and win matches. Over time I’ve increased and decreased this offset and found that people report unbalanced matches far less frequently with the +5.

Hey Verc,

Here’s my proposition to fixing autobalance. I have removed some conditions, added new one, and tweaked the algorithm to provide a better insight into assigning players to the right team.


Auto Balancing is Disabled

  • Sandbox, Trailer Mode, or Endless options is enabled.
  • Game is in tournament or scrimmage mode.
  • Less than 3 minutes left in the round.
  • Gamemode is FFA; GG, HH, etc.

Values in Algorithm

  • KDR
  • Power Points
  • Party Size

Conditions for Auto Balancing

Weight difference is greater than 20% between two teams.


Pseudo Weight Algorithm

  • Special Rule: Assists count as 0.25 of a kill.
  • Value A = Lowest of Mean or Median for Overall KDR.
  • Value B = Lowest of Mean or Median for 20 Games KDR.
  • Value C = Lowest of Mean or Median for Overall Power.
  • Value D = Lowest of Mean or Median for 20 Games Power.

Value X = Multiply A & B
Value Y = Multiply C & D then Divide by 100,000.
Value Z = Multiply X & Y

  • If player is not in a party, Z is the final weight.
  • Parties of 2, Multiply Z by 1.15 for final weight.
  • Parties of 3, Multiply Z by 1.20 for final weight.
  • Parties of 4 or more, Multiply Z by 1.25 for final weight.

Explained

Why do we have mean and median? Mean averages out a player’s performance, regardless of their playstyle changes. Median focuses on the player’s most common performance.

  • Example… a player has 7 KDR in three games, but has 1 KDR in other seventeen games.
    Mean = 3.4 KDR.
    Median = 1 KDR.

It’s very important to use the right kind of value. We want to be careful with measuring a player’s potential and not use it against them. In fact, it’s better to focus on their consistency than peaks.

  • Example Two… a player has 7 KDR in seventeen games, but has 1 KDR in other three games.
    Mean = 6.1 KDR.
    Median = 7 KDR.

In rare situations, a player might have a consistent performance, but then decides to play casually in three games. Median hurts them, so we want to pick the mode to make it more fair. For instance, this player could be carrying a flag, so they hide more often and shooting less, but still wins the objective.


Team Assignment Pseudo Algorithm

  • Special Rule: Parties are assigned first to teams pre-sorting.
  • All players’ weights are sorted from greatest to lowest.
  • Assign player to the team with lowest weight.
  • Algorithm disregards team size to focus on balancing.

Example One - Normal Game

Salvage Game with Players of Weights 7, 6, 5.5, 5.5, 5, 5, 5, 5, 3, 2, 2, 1.5, 0.5, 0.5, and 0.5.

  • 7, 6, 5.5 is in a team. Their weight is multiplied by 1.20 then assigned by algorithm to Team A.

Team A: 22.5
Team B: 0

  • Algorithm Assigns 5.5, 5, 5, 5, 5 to Team B.

Team A: 22.5
Team B: 25.5

  • Algorithm Assigns 3 and 2 to Team A.
    Team A: 27.5
    Team B: 25.5
  • Algorithm Assigns 2 and 1.5 to Team B.
    Team A: 27.5
    Team B: 29.0
  • Algorithm Assigns 0.5, 0.5, and 0.5 to Team A:
    Team A: 29.0 with Total of 8 Players.
    Team B: 29.0 with Total of 7 Players.
  • Algorithm Assigns the Latecomer to Team A.

Example Two - Superteam Game

Salvage Game with Players of Weights 11, 11, 10, 5, 5, 5, 3, 3, 3, 2, 2, 1, 1, 1, 1.

  • 11, 11, 10 is in a team. Their weight is multiplied by 1.20 then assigned by algorithm to Team A.

Team A: 38.4
Team B: 0

  • Algorithm Assigns 5, 5, 5, 3, 3, 3, 2, 2, 1, 1, 1, 1 to Team B.

Team A: 38.4 with Total of 3 Players.
Team B: 32.0 with Total of 12 Players.

  • Algorithm Assigns the Latecomer to Team B.

Auto Balance Algorithm

  • Triggered if a Player Leaves, Joins, or a Party Forms Mid-Game.
  • Triggered if Team Power of a team is greater than 20% of the other team.
  • May select any player in other team not in a party.

Select a player that brings both teams’ weights closest to each other.
Rinse and repeat until both team power is not greater than 20% of the other team.