beyond-all-reason / teiserver

Middleware server for online gaming
https://www.beyondallreason.info/
MIT License
50 stars 47 forks source link

split noobs balance algorithm (party support) #369

Closed jauggy closed 3 weeks ago

jauggy commented 1 month ago

Context

This PR adds a new balance algorithm split_noobs that does the following:

split_noobs algo

This algo only supports two teams. It will call Teifion's algo for FFA.

First, separate the players into two types

Noobs: Anyone not in party AND either

Experienced: Everyone else

Then behaviour will depend on the following uses cases:

If there are parties

The top 14 experienced players are fed into the brute force algorithm to find the best two team combination. To determine the top 14, we prefer players in parties, then prefer higher rating. The brute force algo will try and keep parties together and keep both team ratings close.

Next the teams will draft the remaining experienced players preferring higher rating. Then the teams will draft the noobs preferring higher rank and lower uncertainty.

If there are no parties

There's no need to use brute force. Just do a normal draft. Teams will prefer experienced players with high rating. If there are no more experienced players, prefer high rank and low uncertainty; this is because we don't trust the rating of new players.

brute_force algo

This algorithm only supports two teams. It will call Teifion's algo for FFA. It will go through each and every combination of possible teams and give each combination a score.

Score = team rating diff penalty + broken party penalty Broken party penalty = num broken parties * broken party multiplier broken party multiplier = 7

It will then pick the combination with the lowest score.

It takes 5ms to run 7v7 but 20-40ms to run 8v8

Testing

This is best tested by going to integration server and selecting a match then examining the output from the balance tab. Select the balance algorithm as split_noobs. To get matchids with one chevs use this

select  distinct  tbmm.match_id, tbm.finished   from account_users au
inner join teiserver_battle_match_memberships tbmm 
on tbmm.user_id =au.id 
inner join teiserver_battle_matches tbm 
on tbm.id = tbmm.match_id 
where cast(au."data" ->> 'rank' as INTEGER) = 0
and tbm.team_size =8
and tbm.game_type = 'Large Team'
order by tbm.finished desc
limit 50

Go to this url replacing the match id as appropriate

https://server5.beyondallreason.info/battle/<matchid>/balance
jauggy commented 1 month ago

This PR is dependant on brute_force algo so it would be easier to merge this first: https://github.com/beyond-all-reason/teiserver/pull/362

Then this PR becomes simpler.

L-e-x-o-n commented 3 weeks ago

This PR is dependant on brute_force algo so it would be easier to merge this first: #362

Then this PR becomes simpler.

Brute force has been merged

jauggy commented 3 weeks ago

Thanks Lexon. I'll clean this one up.

jauggy commented 3 weeks ago

@L-e-x-o-n this is now ready for review and merge.