How Multi-Table Tournaments (MTTs) Are Implemented

Probability

Overview

While poker games like Texas Hold’em have complex rules, it’s possible to implement them even as an individual developer. That’s exactly what I’ve been thinking about lately (the game rules themselves are in the public domain, so there don’t seem to be any copyright or patent issues). Commercial poker games often implement a feature called Multi-Table Tournaments (MTT). Players familiar with Japanese games like m Hold’em or Poker Chase will likely know what kind of rules these games follow.

 Implementing this Multi-Table Tournament (MTT) feature seems quite challenging to me. This functionality appears to be the wall separating individual hobbyists from professional organizations. As an individual developer, implementing large-scale features is difficult for me. However, I’m motivated to challenge myself to implement MTT and be able to say, “I crossed that barrier!”

 This article is a compilation of my thoughts on how to approach the implementation, serving as a way to organize my ideas. Since it’s based on my own thinking (though I did use ChatGPT), it might not be the most efficient approach, but I’ll jot down my notes anyway.

Multiplayer Functionality

Before diving into multi-table tournaments, let’s briefly cover how to enable multiple players to share data while playing poker. When playing against NPCs in single-player mode, the entire process can be handled internally within the smartphone. Therefore, only the client-side functionality needs to be implemented. However, for multiplayer poker, information like hole cards, community cards, and each player’s actions must be shared in real-time across multiple devices.

 To share data across multiple smartphones, you need to set up a server separate from the smartphones themselves. Data sharing between smartphones then occurs via communication with this server. While I wrote “just set up a server” simply, in practice, starting the service would likely require renting a server or using a cloud service like AWS or Google Cloud. This would probably cost around 5,000 to 10,000 yen per month, which seems like a painful expense even for a hobby. (If you have a fixed IP address through your ISP contract and can open a hole in your home firewall, you could technically use your home PC as a server. However, this doesn’t seem like a proper setup, and it would likely fail app reviews…)

 To share data, communication processing is required. This is handled using a communication method called WebSocket, which uses the same underlying internet protocol. Downloading and displaying homepage data is asynchronous processing, but WebSocket enables synchronous processing over the same protocol. The implementation itself isn’t overly difficult. Using a server development book as a guide, I managed to develop a program enabling multiple devices to share data and play poker within about a week. Assuming this functionality is already in place, the following section explores how to implement a multi-table tournament.

Handling Thousands of Simultaneous Connections

Multi-table tournaments can sometimes attract thousands of participants, even up to 10,000 players (it appears that sites like m Hold’em and Poker Chase often have around 1,000 participants). Of course, the game I’m developing has zero expectation of reaching such numbers, but I’m curious about the technical approach. Load balancing seems necessary, and I speculated that parallel processing across multiple servers might require some specialized handling.

 So, I asked ChatGPT: “How should load balancing be implemented for a multi-table tournament handling thousands of simultaneous connections? Please explain the mechanism.” The answer was different from what I expected:

”For a few thousand connections, a single server with decent specs should handle it easily.”

Apparently, poker has low action density and consumes very little CPU or memory. The number of connections becomes the main bottleneck, but this isn’t heavily dependent on server specs. Servers can generally handle around 10,000 to 30,000 connections. Incidentally, even for MMORPGs with higher action intensity than poker, it’s common to operate around 3,000 to 5,000 simultaneous connections on a single server. For poker, it seems possible to consolidate and operate a single server even for a MTT with 10,000 players.

 I had assumed parallel processing would be necessary, but being told it wasn’t needed was a surprise. Still, I asked what kind of configuration would be used if load balancing were implemented. I was told several configurations, but the basic setup seems to be:

“LB + Sticky + Lightweight Backplane”

LB stands for Load Balancer, which automatically distributes connections to servers based on user ID or IP address. Sticky means assigning a fixed server to each user. The Backplane handles communication between servers and shares data in memory (apparently using mechanisms like Redis Pub/Sub or ElastiCache).

 Fundamentally, the client application doesn’t need to be aware of which server it connects to; the data sharing between servers (the backplane) handles the operations. For example, when processing like breaking down a table and then joining a new one spans multiple servers, the backplane issues instructions like moving this user to another server (disconnect + reconnect). The server receiving the instruction then notifies the client, and the client disconnects from the old server and reconnects to the new one. This flow makes it possible.

 Well, I listened to the explanation, but personally, I feel one server is sufficient. If thousands of connections can run smoothly on a single server, it’s unlikely to be an issue for my application…

Feature List

I overthought the infrastructure aspects, but it seems like unnecessary worry. Let’s identify the features needed for MTT. The key features are as follows:

  1. Time: Recruitment start time, game start time, registration (re-entry) end time
  2. Stack and blind rules
  3. Structure level-ups over time (blinds, antes)
  4. Number of re-entries allowed
  5. Player count rules per table (e.g., 3 to 9 players)
  6. Table rebalancing based on stack distribution and remaining players
  7. Player action time management (time per action, extension options)
  8. Display of near-real-time statistics and posting of final rankings

That covers the main points. While I mentioned one server should suffice, rules for the following scenarios may also need consideration:

  1. Mid-game exit: Handling when a player gives up and leaves mid-game
  2. Inactivity: How many times to allow a player to run out of time without acting
  3. Connection loss: Whether to allow reconnection if a connection is lost, and if so, for how long.
  4. Handling disconnected players: Automatic actions via Check or Fold, and the time threshold for triggering auto-play. Consider treating them as withdrawn after a set period.

While social games likely require defining prize structures, the author’s game uses chips with no real value. Since there’s no reward beyond personal satisfaction (though, to be honest, social games probably offer little beyond that too…), this can be ignored. However, it might be advisable to save the final ranking results in the database for a certain period of time for reference. Individual items can be implemented steadily by defining appropriate rules, but let’s briefly consider the Table Rebalancing algorithm at the end.

Table Rebalancing

Multi-table tournaments have the characteristic that players are eliminated starting with those who lose all their chips. Therefore, if the number of players at a table falls below a specified threshold, the tables are reconfigured. Performing rebalancing too frequently makes it impossible to read opponents’ strategies, turning the game into pure luck. Therefore, it’s preferable to maintain existing tables as much as possible. Additionally, if stack sizes differ too greatly, players with larger stacks gain an unfair advantage. Thus, when rebalancing, it’s better to select players with similar stack sizes (rankings) for the same table.

 Considering the above conditions, let’s tentatively devise a Table Rebalancing algorithm.

  1. If the number of players at a table falls below the specified minimum, dissolve the table and add the players to the waiting list.
  2. If the number of players on the waiting list exceeds the table’s minimum requirement and the stack difference falls within a certain range (e.g., within 5 times between the largest and smallest), create a new table by extracting players from the waiting list in order of largest stack.
  3. The waiting list will contain players rejected due to stack conditions and leftover players. These are assigned to existing tables with open seats. Players with low stacks are assigned to the table with the smallest stack among players with the largest stacks in open tables (min-max rule).
  4. Players still unassigned after this are kept on the waiting list until conditions are met.
  5. Execute steps 1 to 4 at the end of each round for every table.

Note: Tables newly created in step 2 should probably not start until step 3 is complete. This is because a player rejected due to stack conditions might still end up assigned to that table via the min-max rule. If it feels unnatural during actual implementation, I plan to adjust this later (Note: At the time of this blog’s publication, the author has not yet implemented this feature).

Comments