FAForever / server

The servercode for the Forged Alliance Forever lobby
http://www.faforever.com
GNU General Public License v3.0
67 stars 62 forks source link

Change how rating interpolation works for new players #1024

Open BlackYps opened 4 weeks ago

BlackYps commented 4 weeks ago

While trying to implement functionality to enable the client to notify the current user when someone else they could probably match with I stumbled upon two problems.

  1. 1v1 uses mean rating to match and all other queues use displayed rating
  2. The mean of new players gets changed for matching purposes.

Both are an issue, because at the moment the client would need to know about these, so it can determine how to compare the players rating to the ratings that get sent over by the server. 1) can be fixed (the client would compare to mean for 1v1 and compare to displayed rating for everything else), but would still be ugly, but 2) is basically impossible to reliably calculate in the client. Ideally the client shouldn't have to worry about any of this, and should be able to compare the player rating with the other ratings in a trivial way that is the same for all queues.

I propose that we use mean rating and the rating adjustment for everything. For established players it doesn't change anything to change the team matchmaker matching from displayed rating to mean, as everybody should roughly stabilize at the same deviation in the long term. It is just a change for people that are affected by the rating adjustment. I originally used displayed rating in the team matchmaker because it seemed like a "more elegant" way to match new players in the low end and not at a mean of 1500. But as it turns out this split between the queues is biting us now, so we should unify them. This way we solve problem 1. I'll have to study some real data to determine if we should choose a different interpolation for the team queues, but this is an implementation detail. All these rating manipulations should only concern the server and the ratings it sends out to the clients should be the already adjusted ratings. This way the client doesn't have to worry about rating interpolation and we solve problem 2. The rating interpolation should maybe even be done for global, because I heard people complain that the autobalancer for custom lobbies uses mean and basically has the same problem as we originally had with 1v1 that it overvalues new players because of this.

I am interested in your thoughts about this @Askaholic

Askaholic commented 3 weeks ago

That sounds fine to me. It was my opinion originally that we should be using mean rating for matching rather than displayed rating, but ultimately you have put in the work to model / simulate the results of the implementation, and if it works, it works.

I don't have any thoughts other than that. I haven't been paying much attention to FAF lately but I'd be happy to review and merge a PR for this.

BlackYps commented 3 weeks ago

I wonder where we should move the rating adjustment. We should move it out of the search class, because we want it to not only affect matchmaking, but also the ratings that get sent out to the client. On the other hand we have to make sure that we don't accidentally persist adjusted ratings into the database, for example when processing game results. Do you have a good idea for this?

Askaholic commented 3 weeks ago

Well when you’re sending the rating groups in the queue you have access to the search class so that’s not an issue. What you might want to do is allow different queues or maybe different algorithms to use different adjustments in which case it might make sense to add a function like this to either the Queue class or the Algorithm class:

def get_adjusted_ratings(self, search: Search) -> list[tuple[float, float]]:
BlackYps commented 3 weeks ago

But the client needs to know the adjusted ratings, at least of the own logged in player. Otherwise if I am about to play e.g. my 4th ladder game the client doesn't know the rating the server is trying to match me at and consequently can't show the planned notification correctly. And if I get my own ratings sent in adjusted forms, it should then probably be the same for all other players. Otherwise it would be confusing that other people see a different ladder rating for me than I myself see.

Askaholic commented 3 weeks ago

I see. Sending adjusted ratings for players in the queue is no problem as that can be part of the matchmaker_info message. Getting your own is a bit more tricky since it could be different for each queue. I guess we could add a matchmaker_ratings key to the player_info message although that starts to get ugly.

Alternatively it could be sent separately in a new message that is sent on login or something, but then you don’t get the updates when your rating changes. So realistically, the player_info message makes the most sense.

Sheikah45 commented 3 weeks ago

With all this rating info needing to be passed back and forth why isn't the server just determining if someone in your range is searching and putting that in the matchmaker info message?

When this starts to get complicated with all the rating adjustments we seem to lose some of the benefit of flexibility in the client determining if others are near you. And it doesn't seem like exposing the implementation of the matchmaking process is a good idea since that could change and then the clients would have to change all their logic too.

Askaholic commented 3 weeks ago

That's a good point. It just means additional CPU cycles on the server, but I imagine it can be implemented in a way that the performance impact is negligible.

BlackYps commented 3 weeks ago

This seems like the best solution. Then we also don't have to think about rounding the rating to make it more anonymous. The server would have to personalize the matchmaker info message then and for each of the 1000-2000 logged in players the server needs to compare the player's rating to everyone else that is currently in a queue which can easily be above 30 in total. So we need something that can handle 50,000 comparisons every few seconds. But as it is mostly a number comparison I guess it would be fine?

I don't really have ideas how we would implement the personalized field in the matchmaker message though

Askaholic commented 3 weeks ago

I think maybe a separate message would be better because adding personalized stuff to those info messages makes them less efficient to broadcast out. We also only need to check idle players since there’s no need to send someone a notification if they’re already in the queue or are already actively playing another game.

I could see an implementation where you just make a new dedicated service that does these checks on a certain schedule. Or maybe build in some event triggers somehow so that it re-checks when people join a queue.