Matchmaking for a multiplayer game

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite
2












I have working code that needs some optimization for scalability and overall performance. This code basically creates a lobby where users wait for match to be created and link users for a multiplayer game match.



PlayerWait player = GameMatchEngine.getInstance().createMatch(userId);
if (player.getPlayer().getUserId() == userId)
while (player.isAvailable())
Thread.sleep(100);


if (player.getMatchBegan())
if (!hasUser(userId))
.... failed to find a match ....
else
multiplayer = getMultiplayer(userId);
//if




The code above is called when a user request for a match. if (player.getPlayer().getUserId() == userId) happens when a first user requests a match, and there is no player in the lobby.



private Map<Integer, Multiplayer> users = 
new ConcurrentHashMap<Integer, Multiplayer>();

/* removes user who was waiting and retrieves Multiplayer Session */
private boolean hasUser(Integer userId)
return this.users.containsKey(userId);



PlayerWait class:



private Player player;
private boolean availablility = true;
private boolean matchBegan = true;
Timer timer;

public PlayerWait(Player player)
setPlayer(player);
waitTimeExpired(10);


private void waitTimeExpired(int seconds)
this.timer = new Timer();
timer.schedule(new scheduledTask(), seconds * 1000);
//waitTimeExpired()

class scheduledTask extends TimerTask

@Override
public void run()
synchronized(this)
if(availablility)
setAvailable(false);
if(matchBegan)
GameMatchEngine.getInstance().
matchWithAI(getPlayerWait());

//if

timer.cancel();


//class scheduledTask

public PlayerWait createMatch(int user_id) throws SQLException
String rank = getRank(user_id);

PlayerWait playerFound = findOpponentUser(rank, user_id);

if (playerFound == null)
playerFound = addUser(new Player(user_id, rank));
else
try
.... found an opponent; create a match in db ....
catch (SQLException e)
LOGGER.error("Error in creating a match: ", e);
//try


LOGGER.error("PlayerWait: " + playerFound);
return playerFound;
//createMatch()

private PlayerWait findOpponentUser(String rank, int userId)
boolean found = false;
PlayerWait player = null;

if (hasUser(rank))
player = getUser(rank);
if (player.getPlayer().getUserId() != userId)
synchronized (player)
found = player.isAvailable();
player.setAvailable(false);
//synchronized()
else
found = true;


if (found)
removeUser(rank);
else
player = null;
//if
//if

return player;
//findOpponentUser()

private PlayerWait addUser(Player player)
PlayerWait playerWait = null;
String rank = player.getUserRank();

if(!this.users.containsKey(rank))
playerWait = new PlayerWait(player);
this.users.put(rank,playerWait);


return playerWait;
//addUser()


So when a user A requests a match and found no one, user A is put into the concurrent hash map "users" and waits for ten seconds before expiration. While user is in the wait list, request is held onto the server until being expired. When user B requests a match, user A is released from the concurrent hash map and matched against user B. Multiplayer Session is used for holding these two players' data.



Here's my concern:



  1. I believe the timer is a separate thread that runs on the background while request is also being held on the server. In addition, while user is waiting for the match, the Thread.sleep is called every 0.1 second. Is there any better way to implement/optimize this? There should be a scalability issue here.


  2. I think the overall performance soars as this is not really a real time match making method. Sharing any ideas on how to create matches with better performance would be greatly appreciated.







share|improve this question



























    up vote
    3
    down vote

    favorite
    2












    I have working code that needs some optimization for scalability and overall performance. This code basically creates a lobby where users wait for match to be created and link users for a multiplayer game match.



    PlayerWait player = GameMatchEngine.getInstance().createMatch(userId);
    if (player.getPlayer().getUserId() == userId)
    while (player.isAvailable())
    Thread.sleep(100);


    if (player.getMatchBegan())
    if (!hasUser(userId))
    .... failed to find a match ....
    else
    multiplayer = getMultiplayer(userId);
    //if




    The code above is called when a user request for a match. if (player.getPlayer().getUserId() == userId) happens when a first user requests a match, and there is no player in the lobby.



    private Map<Integer, Multiplayer> users = 
    new ConcurrentHashMap<Integer, Multiplayer>();

    /* removes user who was waiting and retrieves Multiplayer Session */
    private boolean hasUser(Integer userId)
    return this.users.containsKey(userId);



    PlayerWait class:



    private Player player;
    private boolean availablility = true;
    private boolean matchBegan = true;
    Timer timer;

    public PlayerWait(Player player)
    setPlayer(player);
    waitTimeExpired(10);


    private void waitTimeExpired(int seconds)
    this.timer = new Timer();
    timer.schedule(new scheduledTask(), seconds * 1000);
    //waitTimeExpired()

    class scheduledTask extends TimerTask

    @Override
    public void run()
    synchronized(this)
    if(availablility)
    setAvailable(false);
    if(matchBegan)
    GameMatchEngine.getInstance().
    matchWithAI(getPlayerWait());

    //if

    timer.cancel();


    //class scheduledTask

    public PlayerWait createMatch(int user_id) throws SQLException
    String rank = getRank(user_id);

    PlayerWait playerFound = findOpponentUser(rank, user_id);

    if (playerFound == null)
    playerFound = addUser(new Player(user_id, rank));
    else
    try
    .... found an opponent; create a match in db ....
    catch (SQLException e)
    LOGGER.error("Error in creating a match: ", e);
    //try


    LOGGER.error("PlayerWait: " + playerFound);
    return playerFound;
    //createMatch()

    private PlayerWait findOpponentUser(String rank, int userId)
    boolean found = false;
    PlayerWait player = null;

    if (hasUser(rank))
    player = getUser(rank);
    if (player.getPlayer().getUserId() != userId)
    synchronized (player)
    found = player.isAvailable();
    player.setAvailable(false);
    //synchronized()
    else
    found = true;


    if (found)
    removeUser(rank);
    else
    player = null;
    //if
    //if

    return player;
    //findOpponentUser()

    private PlayerWait addUser(Player player)
    PlayerWait playerWait = null;
    String rank = player.getUserRank();

    if(!this.users.containsKey(rank))
    playerWait = new PlayerWait(player);
    this.users.put(rank,playerWait);


    return playerWait;
    //addUser()


    So when a user A requests a match and found no one, user A is put into the concurrent hash map "users" and waits for ten seconds before expiration. While user is in the wait list, request is held onto the server until being expired. When user B requests a match, user A is released from the concurrent hash map and matched against user B. Multiplayer Session is used for holding these two players' data.



    Here's my concern:



    1. I believe the timer is a separate thread that runs on the background while request is also being held on the server. In addition, while user is waiting for the match, the Thread.sleep is called every 0.1 second. Is there any better way to implement/optimize this? There should be a scalability issue here.


    2. I think the overall performance soars as this is not really a real time match making method. Sharing any ideas on how to create matches with better performance would be greatly appreciated.







    share|improve this question























      up vote
      3
      down vote

      favorite
      2









      up vote
      3
      down vote

      favorite
      2






      2





      I have working code that needs some optimization for scalability and overall performance. This code basically creates a lobby where users wait for match to be created and link users for a multiplayer game match.



      PlayerWait player = GameMatchEngine.getInstance().createMatch(userId);
      if (player.getPlayer().getUserId() == userId)
      while (player.isAvailable())
      Thread.sleep(100);


      if (player.getMatchBegan())
      if (!hasUser(userId))
      .... failed to find a match ....
      else
      multiplayer = getMultiplayer(userId);
      //if




      The code above is called when a user request for a match. if (player.getPlayer().getUserId() == userId) happens when a first user requests a match, and there is no player in the lobby.



      private Map<Integer, Multiplayer> users = 
      new ConcurrentHashMap<Integer, Multiplayer>();

      /* removes user who was waiting and retrieves Multiplayer Session */
      private boolean hasUser(Integer userId)
      return this.users.containsKey(userId);



      PlayerWait class:



      private Player player;
      private boolean availablility = true;
      private boolean matchBegan = true;
      Timer timer;

      public PlayerWait(Player player)
      setPlayer(player);
      waitTimeExpired(10);


      private void waitTimeExpired(int seconds)
      this.timer = new Timer();
      timer.schedule(new scheduledTask(), seconds * 1000);
      //waitTimeExpired()

      class scheduledTask extends TimerTask

      @Override
      public void run()
      synchronized(this)
      if(availablility)
      setAvailable(false);
      if(matchBegan)
      GameMatchEngine.getInstance().
      matchWithAI(getPlayerWait());

      //if

      timer.cancel();


      //class scheduledTask

      public PlayerWait createMatch(int user_id) throws SQLException
      String rank = getRank(user_id);

      PlayerWait playerFound = findOpponentUser(rank, user_id);

      if (playerFound == null)
      playerFound = addUser(new Player(user_id, rank));
      else
      try
      .... found an opponent; create a match in db ....
      catch (SQLException e)
      LOGGER.error("Error in creating a match: ", e);
      //try


      LOGGER.error("PlayerWait: " + playerFound);
      return playerFound;
      //createMatch()

      private PlayerWait findOpponentUser(String rank, int userId)
      boolean found = false;
      PlayerWait player = null;

      if (hasUser(rank))
      player = getUser(rank);
      if (player.getPlayer().getUserId() != userId)
      synchronized (player)
      found = player.isAvailable();
      player.setAvailable(false);
      //synchronized()
      else
      found = true;


      if (found)
      removeUser(rank);
      else
      player = null;
      //if
      //if

      return player;
      //findOpponentUser()

      private PlayerWait addUser(Player player)
      PlayerWait playerWait = null;
      String rank = player.getUserRank();

      if(!this.users.containsKey(rank))
      playerWait = new PlayerWait(player);
      this.users.put(rank,playerWait);


      return playerWait;
      //addUser()


      So when a user A requests a match and found no one, user A is put into the concurrent hash map "users" and waits for ten seconds before expiration. While user is in the wait list, request is held onto the server until being expired. When user B requests a match, user A is released from the concurrent hash map and matched against user B. Multiplayer Session is used for holding these two players' data.



      Here's my concern:



      1. I believe the timer is a separate thread that runs on the background while request is also being held on the server. In addition, while user is waiting for the match, the Thread.sleep is called every 0.1 second. Is there any better way to implement/optimize this? There should be a scalability issue here.


      2. I think the overall performance soars as this is not really a real time match making method. Sharing any ideas on how to create matches with better performance would be greatly appreciated.







      share|improve this question













      I have working code that needs some optimization for scalability and overall performance. This code basically creates a lobby where users wait for match to be created and link users for a multiplayer game match.



      PlayerWait player = GameMatchEngine.getInstance().createMatch(userId);
      if (player.getPlayer().getUserId() == userId)
      while (player.isAvailable())
      Thread.sleep(100);


      if (player.getMatchBegan())
      if (!hasUser(userId))
      .... failed to find a match ....
      else
      multiplayer = getMultiplayer(userId);
      //if




      The code above is called when a user request for a match. if (player.getPlayer().getUserId() == userId) happens when a first user requests a match, and there is no player in the lobby.



      private Map<Integer, Multiplayer> users = 
      new ConcurrentHashMap<Integer, Multiplayer>();

      /* removes user who was waiting and retrieves Multiplayer Session */
      private boolean hasUser(Integer userId)
      return this.users.containsKey(userId);



      PlayerWait class:



      private Player player;
      private boolean availablility = true;
      private boolean matchBegan = true;
      Timer timer;

      public PlayerWait(Player player)
      setPlayer(player);
      waitTimeExpired(10);


      private void waitTimeExpired(int seconds)
      this.timer = new Timer();
      timer.schedule(new scheduledTask(), seconds * 1000);
      //waitTimeExpired()

      class scheduledTask extends TimerTask

      @Override
      public void run()
      synchronized(this)
      if(availablility)
      setAvailable(false);
      if(matchBegan)
      GameMatchEngine.getInstance().
      matchWithAI(getPlayerWait());

      //if

      timer.cancel();


      //class scheduledTask

      public PlayerWait createMatch(int user_id) throws SQLException
      String rank = getRank(user_id);

      PlayerWait playerFound = findOpponentUser(rank, user_id);

      if (playerFound == null)
      playerFound = addUser(new Player(user_id, rank));
      else
      try
      .... found an opponent; create a match in db ....
      catch (SQLException e)
      LOGGER.error("Error in creating a match: ", e);
      //try


      LOGGER.error("PlayerWait: " + playerFound);
      return playerFound;
      //createMatch()

      private PlayerWait findOpponentUser(String rank, int userId)
      boolean found = false;
      PlayerWait player = null;

      if (hasUser(rank))
      player = getUser(rank);
      if (player.getPlayer().getUserId() != userId)
      synchronized (player)
      found = player.isAvailable();
      player.setAvailable(false);
      //synchronized()
      else
      found = true;


      if (found)
      removeUser(rank);
      else
      player = null;
      //if
      //if

      return player;
      //findOpponentUser()

      private PlayerWait addUser(Player player)
      PlayerWait playerWait = null;
      String rank = player.getUserRank();

      if(!this.users.containsKey(rank))
      playerWait = new PlayerWait(player);
      this.users.put(rank,playerWait);


      return playerWait;
      //addUser()


      So when a user A requests a match and found no one, user A is put into the concurrent hash map "users" and waits for ten seconds before expiration. While user is in the wait list, request is held onto the server until being expired. When user B requests a match, user A is released from the concurrent hash map and matched against user B. Multiplayer Session is used for holding these two players' data.



      Here's my concern:



      1. I believe the timer is a separate thread that runs on the background while request is also being held on the server. In addition, while user is waiting for the match, the Thread.sleep is called every 0.1 second. Is there any better way to implement/optimize this? There should be a scalability issue here.


      2. I think the overall performance soars as this is not really a real time match making method. Sharing any ideas on how to create matches with better performance would be greatly appreciated.









      share|improve this question












      share|improve this question




      share|improve this question








      edited May 22 at 23:03









      Jamal♦

      30.1k11114225




      30.1k11114225









      asked May 22 at 22:59









      John

      161




      161




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote













          I believe what you describe fits the producer-consumer pattern: A player who wishes to be matched is a consumer of another player from the lobby. when players join the lobby, it should produce them to consumers. Therefore I think a better data structure for your requirements is BlockingQueue. The most advantageous feature is the blocking of consumers. this eliminates the need for the timer. you can have consumer wait forever for an item (another player) or have it timeout after a certain time. regarding rank, you can still use a Map with rank as key, and the queue as value. which brings up the question: in its current definition, the Map can hold only one game per rank?



          However, as long as the solution is confined within one JVM, you will have a scalability concern. To fix that, you will need to externalize the queue and use a messaging system (like RabbitMQ) and then rank becomes a topic where consumer register for. This is a much more complex solution but it has the potential to grow to social-network scale.



          One more comment regarding readability:




          if (player.getPlayer().getUserId() == userId) happens when a first
          user requests a match, and there is no player in the lobby.




          First of all, I do not understand how this may happen, since in findOpponentUser() you ask on unequality of user ids. anyway, at the very least, you should make a method like isOnlyPlayerInLobby().






          share|improve this answer





















          • First of all, great thanks to your comment. They seem to be great answers. Yes, it is producer-consumer pattern. How would you go about implementing this BlockingQueue instead PlayerWait class that I use? I am not really familiar with BlockingQueue, so before I dive into it, I just want to have a general idea of how to approach this. Can you elaborate more on the use of external messaging system? Every user has rank and I retrieve it from the database. What difference would this RabbitMQ make? How would I approach about using this? For the readability part, I totally agree with you on this.
            – John
            May 23 at 14:19










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f194978%2fmatchmaking-for-a-multiplayer-game%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote













          I believe what you describe fits the producer-consumer pattern: A player who wishes to be matched is a consumer of another player from the lobby. when players join the lobby, it should produce them to consumers. Therefore I think a better data structure for your requirements is BlockingQueue. The most advantageous feature is the blocking of consumers. this eliminates the need for the timer. you can have consumer wait forever for an item (another player) or have it timeout after a certain time. regarding rank, you can still use a Map with rank as key, and the queue as value. which brings up the question: in its current definition, the Map can hold only one game per rank?



          However, as long as the solution is confined within one JVM, you will have a scalability concern. To fix that, you will need to externalize the queue and use a messaging system (like RabbitMQ) and then rank becomes a topic where consumer register for. This is a much more complex solution but it has the potential to grow to social-network scale.



          One more comment regarding readability:




          if (player.getPlayer().getUserId() == userId) happens when a first
          user requests a match, and there is no player in the lobby.




          First of all, I do not understand how this may happen, since in findOpponentUser() you ask on unequality of user ids. anyway, at the very least, you should make a method like isOnlyPlayerInLobby().






          share|improve this answer





















          • First of all, great thanks to your comment. They seem to be great answers. Yes, it is producer-consumer pattern. How would you go about implementing this BlockingQueue instead PlayerWait class that I use? I am not really familiar with BlockingQueue, so before I dive into it, I just want to have a general idea of how to approach this. Can you elaborate more on the use of external messaging system? Every user has rank and I retrieve it from the database. What difference would this RabbitMQ make? How would I approach about using this? For the readability part, I totally agree with you on this.
            – John
            May 23 at 14:19














          up vote
          1
          down vote













          I believe what you describe fits the producer-consumer pattern: A player who wishes to be matched is a consumer of another player from the lobby. when players join the lobby, it should produce them to consumers. Therefore I think a better data structure for your requirements is BlockingQueue. The most advantageous feature is the blocking of consumers. this eliminates the need for the timer. you can have consumer wait forever for an item (another player) or have it timeout after a certain time. regarding rank, you can still use a Map with rank as key, and the queue as value. which brings up the question: in its current definition, the Map can hold only one game per rank?



          However, as long as the solution is confined within one JVM, you will have a scalability concern. To fix that, you will need to externalize the queue and use a messaging system (like RabbitMQ) and then rank becomes a topic where consumer register for. This is a much more complex solution but it has the potential to grow to social-network scale.



          One more comment regarding readability:




          if (player.getPlayer().getUserId() == userId) happens when a first
          user requests a match, and there is no player in the lobby.




          First of all, I do not understand how this may happen, since in findOpponentUser() you ask on unequality of user ids. anyway, at the very least, you should make a method like isOnlyPlayerInLobby().






          share|improve this answer





















          • First of all, great thanks to your comment. They seem to be great answers. Yes, it is producer-consumer pattern. How would you go about implementing this BlockingQueue instead PlayerWait class that I use? I am not really familiar with BlockingQueue, so before I dive into it, I just want to have a general idea of how to approach this. Can you elaborate more on the use of external messaging system? Every user has rank and I retrieve it from the database. What difference would this RabbitMQ make? How would I approach about using this? For the readability part, I totally agree with you on this.
            – John
            May 23 at 14:19












          up vote
          1
          down vote










          up vote
          1
          down vote









          I believe what you describe fits the producer-consumer pattern: A player who wishes to be matched is a consumer of another player from the lobby. when players join the lobby, it should produce them to consumers. Therefore I think a better data structure for your requirements is BlockingQueue. The most advantageous feature is the blocking of consumers. this eliminates the need for the timer. you can have consumer wait forever for an item (another player) or have it timeout after a certain time. regarding rank, you can still use a Map with rank as key, and the queue as value. which brings up the question: in its current definition, the Map can hold only one game per rank?



          However, as long as the solution is confined within one JVM, you will have a scalability concern. To fix that, you will need to externalize the queue and use a messaging system (like RabbitMQ) and then rank becomes a topic where consumer register for. This is a much more complex solution but it has the potential to grow to social-network scale.



          One more comment regarding readability:




          if (player.getPlayer().getUserId() == userId) happens when a first
          user requests a match, and there is no player in the lobby.




          First of all, I do not understand how this may happen, since in findOpponentUser() you ask on unequality of user ids. anyway, at the very least, you should make a method like isOnlyPlayerInLobby().






          share|improve this answer













          I believe what you describe fits the producer-consumer pattern: A player who wishes to be matched is a consumer of another player from the lobby. when players join the lobby, it should produce them to consumers. Therefore I think a better data structure for your requirements is BlockingQueue. The most advantageous feature is the blocking of consumers. this eliminates the need for the timer. you can have consumer wait forever for an item (another player) or have it timeout after a certain time. regarding rank, you can still use a Map with rank as key, and the queue as value. which brings up the question: in its current definition, the Map can hold only one game per rank?



          However, as long as the solution is confined within one JVM, you will have a scalability concern. To fix that, you will need to externalize the queue and use a messaging system (like RabbitMQ) and then rank becomes a topic where consumer register for. This is a much more complex solution but it has the potential to grow to social-network scale.



          One more comment regarding readability:




          if (player.getPlayer().getUserId() == userId) happens when a first
          user requests a match, and there is no player in the lobby.




          First of all, I do not understand how this may happen, since in findOpponentUser() you ask on unequality of user ids. anyway, at the very least, you should make a method like isOnlyPlayerInLobby().







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 23 at 6:44









          Sharon Ben Asher

          2,038512




          2,038512











          • First of all, great thanks to your comment. They seem to be great answers. Yes, it is producer-consumer pattern. How would you go about implementing this BlockingQueue instead PlayerWait class that I use? I am not really familiar with BlockingQueue, so before I dive into it, I just want to have a general idea of how to approach this. Can you elaborate more on the use of external messaging system? Every user has rank and I retrieve it from the database. What difference would this RabbitMQ make? How would I approach about using this? For the readability part, I totally agree with you on this.
            – John
            May 23 at 14:19
















          • First of all, great thanks to your comment. They seem to be great answers. Yes, it is producer-consumer pattern. How would you go about implementing this BlockingQueue instead PlayerWait class that I use? I am not really familiar with BlockingQueue, so before I dive into it, I just want to have a general idea of how to approach this. Can you elaborate more on the use of external messaging system? Every user has rank and I retrieve it from the database. What difference would this RabbitMQ make? How would I approach about using this? For the readability part, I totally agree with you on this.
            – John
            May 23 at 14:19















          First of all, great thanks to your comment. They seem to be great answers. Yes, it is producer-consumer pattern. How would you go about implementing this BlockingQueue instead PlayerWait class that I use? I am not really familiar with BlockingQueue, so before I dive into it, I just want to have a general idea of how to approach this. Can you elaborate more on the use of external messaging system? Every user has rank and I retrieve it from the database. What difference would this RabbitMQ make? How would I approach about using this? For the readability part, I totally agree with you on this.
          – John
          May 23 at 14:19




          First of all, great thanks to your comment. They seem to be great answers. Yes, it is producer-consumer pattern. How would you go about implementing this BlockingQueue instead PlayerWait class that I use? I am not really familiar with BlockingQueue, so before I dive into it, I just want to have a general idea of how to approach this. Can you elaborate more on the use of external messaging system? Every user has rank and I retrieve it from the database. What difference would this RabbitMQ make? How would I approach about using this? For the readability part, I totally agree with you on this.
          – John
          May 23 at 14:19












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f194978%2fmatchmaking-for-a-multiplayer-game%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation