Sign in to follow this  
thatnoobguy

PVP matchmaking system

Recommended Posts

Hey everyone, Sorry for that rookie question.

I'm trying to develop this 1vs1 RPG multiplayer game and have a hard time implementing player matchmaking mechanism.

For testing purposes, I'm creating a player when the client connects to the server. 

// Client side:

const socket = io();

socket.on('connect', () => {
   socket.emit('create player', data => console.log(data))
})

// Server side:

let players = [];

const playerFactory = () => {
  return {
    state: 'idle', // idle, searching, fightInProgress
    lvl: getRandomArbitrary(1, 10), // Get random number from 1 - 10
    winRatio: getRandomArbitrary(0, 100)
  }
};

io.on('connection', socket => {
  socket.on('create player', fn => {
    console.log('Player created');

    const player = playerFactory(name);
    player.id = socket.id;

    players.push(player);

    //returning acknowledgement to client
    fn(player);
  })

})

Assuming there is a 'Find opponent' button. How do I watch and match players with 'searching' statuses and appropriate levels? Also, how would I match players by their win/loss ratio? Any information or code examples, libraries or frameworks would help a lot.

Thank you in advance!

Share this post


Link to post
Share on other sites

What you're after is heuristic-based searches, this might sound scary but every time you search and retrieve from a list you're setting a heuristic and applying it to retrieve an item from a list.

So, the simplest case here is a time-based heuristic and you can use a FIFO (first-in-first-out) to achieve this.

When each player connected they are pushed on to the end of the list of waiting players (Array.push). Whenever any of them hits the 'start' or 'find opponent' button you're getting in to the search. Remove the initiator from the list and your time-based heuristic is simply to take the head of the list (Array.shift), because they enter from the tail you know the first one in the list (at the head) has been waiting the longest. These 2 players are now matched, removed from the waiting list and can get going.

From there you need to create a more complex heuristic (rather than Array.shift) that is going to match on win/loss ratio or player experience level or whatever.

To prepare for this you take the code you already have, shove the Array.shift bit into its own function (find, maybe), write some test and now you're ready to 'play' with your matching algorithm.

The api for the 'find' function needs to take the list of waiting players (search space) and the initiator player and spit out another player (whether you remove these players from the list of waiting players in this function or outside is up to you, you'd probably want to do it elsewhere and keep this searching function pure but its up to you). I'd suggest you pass a 'copy' of the search space into this function, then you can mutate it all you like, but, again, this is up to you.

Now you have a sandboxed 'find' function and you can do what you like in here to implement whatever heuristic you want (there is a metric ton of info on heuristic based searches out there).

You might want to pull out all players in the list with a similar win/loss ratio to the initiator and randomly pick one. You might want to just find the first player with a similar win/loss ratio (if you have kept with the ordered list, by time, then searching head to end will mean you tend to pick out the players waiting the longest, which is probably a good thing). You might want to pick a totally random opponent 10% of the time if you decide always picking a similarly matched opponent (by win/loss) gets a bit stale for users. There are lots of options and totally dependent on your use-case.

Share this post


Link to post
Share on other sites
11 hours ago, mattstyles said:

What you're after is heuristic-based searches, this might sound scary but every time you search and retrieve from a list you're setting a heuristic and applying it to retrieve an item from a list.

So, the simplest case here is a time-based heuristic and you can use a FIFO (first-in-first-out) to achieve this.

When each player connected they are pushed on to the end of the list of waiting players (Array.push). Whenever any of them hits the 'start' or 'find opponent' button you're getting in to the search. Remove the initiator from the list and your time-based heuristic is simply to take the head of the list (Array.shift), because they enter from the tail you know the first one in the list (at the head) has been waiting the longest. These 2 players are now matched, removed from the waiting list and can get going.

From there you need to create a more complex heuristic (rather than Array.shift) that is going to match on win/loss ratio or player experience level or whatever.

To prepare for this you take the code you already have, shove the Array.shift bit into its own function (find, maybe), write some test and now you're ready to 'play' with your matching algorithm.

The api for the 'find' function needs to take the list of waiting players (search space) and the initiator player and spit out another player (whether you remove these players from the list of waiting players in this function or outside is up to you, you'd probably want to do it elsewhere and keep this searching function pure but its up to you). I'd suggest you pass a 'copy' of the search space into this function, then you can mutate it all you like, but, again, this is up to you.

Now you have a sandboxed 'find' function and you can do what you like in here to implement whatever heuristic you want (there is a metric ton of info on heuristic based searches out there).

You might want to pull out all players in the list with a similar win/loss ratio to the initiator and randomly pick one. You might want to just find the first player with a similar win/loss ratio (if you have kept with the ordered list, by time, then searching head to end will mean you tend to pick out the players waiting the longest, which is probably a good thing). You might want to pick a totally random opponent 10% of the time if you decide always picking a similarly matched opponent (by win/loss) gets a bit stale for users. There are lots of options and totally dependent on your use-case.

 
 
 
 

Amazing, thank you!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.