Jump to content

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!

Link to comment
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.

Link to comment
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!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...