Multi-player games — Plethora of engineering excellence

Prakash Shanbhag
Gameskraft
Published in
6 min readJan 8, 2021

Well well well, at some point in our life we all have enjoyed playing games like card games, ludo, chess, poker, carrom, and more. And given the recent situation where we are restricted to smaller circles, we have seen unprecedented traction to the online clone of these games. However simple the game may be, multi-player games pose technical challenges that one has to overcome to give a seamless experience to their customers. More importantly, when the DAUs scale up to millions from a few hundred, keeping up to the reputation and continue to provide the same UX becomes a tough nut to crack. Technology and engineering excellence has a major role to play in the gaming industry as it is considered one of the tech-heavy domains.

RummyCulture game table

Having seen what goes behind the scenes first-hand at GamesKrafts’ flagship product RummyCulture, we will glance over some of the tech challenges that our awesome engineering team continues to solve and optimize for. So let’s get started !!

Shaving off every microsecond

Image credit: pexels.com

If there is one thing that stands out in terms of better UX in multiplayer games, it has to be the real-time experience you provide to users. This is one of the factors that can make or break the product. Doing this at a high scale over flaky internet speeds and different mobile devices requires extreme engineering. We achieve this by having

  • Optimized algorithms: Yes, using O(l) instead of O(logN), and O(logN) instead of O(N) does to matter us. There is a user waiting to play his next move and we better make it quick!! Be it placing players on the table or picking/discarding a card, everything has to be lightning fast.
  • Save every RTT possible: We optimize every RTT between the inter-services and service-data layer. Doing X read/writes instead of 1 may not be a deal-breaker in a few applications, but it’s a big deal in our case. Not just because of the time taken for extra operations, more so we also want to save additional microseconds over the network. We batch queries, we script them on datastore to shave off those extra hops.
  • Lean on the wire: Again tying this up to latency, we only get absolute necessary data from the data layer to save those extra bytes and time taken to transfer them over the network. From optimized ORM layers -to-tweaking DB clients -to- tuning cache eviction strategies we ensure that we spend as much little time on fetching that data.

Every penny counts

Sure multi-player games are challenging enough, but when users’ money is at stake things becomes extra challenging. This is what makes it more interesting

  • Micro-transactions: Since the whole revenue model is based on cash transactions, there is a constant in-flow and out-flow of cash. Also, since we support adding/withdrawing small amounts we see a large number of small value transactions which is not the case for biz based on the subscription-model.
  • High transaction rates: The majority of money movements happen between users on the game settlement. For example, when a 6 player game gets over we need to adjust the balance of 6 users for every game settled. Credit money to winner(s) and debit from losers. Hence the write operations are directly proportional to the number of games played on our platform. Given we support game variants between few paise to several lakh rupees, the real challenge is to support lower variants that are played at higher rates.
  • Intact statements: RummyCulture supports winning and losing money at the lowest denomination, yes 1 paise. Unlike use cases where one can round off and getaway, we cannot afford to do that as even 1 paise won or lost by the user needs to be accounted for.

No room for fraudsters

Image credit: iStock

Keeping fraudsters away is key to retention and keeping up the credibility of the game. In multi-player real money games, users upon getting the slightest hint that there could be fraudsters playing along with them, they’ll not risk a single penny. Hence it becomes absolutely necessary to ensure that we keep fraudsters away from playing on our platform. We do that by

  • Looking for mutual friends: We look for common traits between users like common payment identifiers, device identifiers, style of playing, patterns of playing games, and 20+ more such indications to group them together.
  • Real-time decision making: Yes, crucial decision-making happens in real-time. These decisions can’t be taken beforehand because we simply won’t know which users will be active on our platform in the future. We place users on the game table in real-time when they hit “Enter game”. So when 6 players are being seated on a game table, we figure out if any of the players know each other in any possible way. If yes, we re-seat and place them on different game tables.
  • Efficient data storage: Since this decision-making has to be lightning-quick we need to pre-process this info and keep it ready for consumption. Finding connections between users on more than 20+ parameters is a challenging task and we cannot do that by using traditional data stores. Hence we use data stores that support graph traversals and complex queries around that.

Fair play using RNG certified algorithms

Image credit: medium.com

In real-money card games to ensure fair play, we have to ensure that the algorithm used for shuffling cards, picking up jokers, and assigning leaders has to be done in a truly randomized way. While generating random numbers is easy using standard random libraries available out there, but most of those random numbers are pseudo-random and can be craked if one really intends to do so. We ensure that the randomization algorithm is able to inject randomization to the maximum extent possible and is RNG certified.

Timers timers timers!!

Image credit: blog.hubstaff.com

Timers are like stopwatches that fire off action after time elapses. The simplest example is the maximum time a user can take to finish their turn in which they have to perform certain actions like roll dice in ludo, move a pawn in chess, pick/discard a card in rummy. Timers’ miss-firing could lead to very adverse effects like the user given too little time (or no time) to a very long time (or the game getting stuck). And yes, we have several thousand timers running at any point in time. From time interval between user turns, time for games to start, time to pick and discard a card, time to wrap up a game, time for tournament rounds to start/end, and much more. Ever wondered how the backend server keeps track of so many timers?

No dumb clients

Pic credit

Our client applications can not be a dumb render-only client. It does the equal heavy lifting of performing complicated tasks like keeping timer states, handling low bandwidth situations, maintaining backend connections, and of course efficient rendering. And since all of these have to be performed across multiple platforms (web/mweb/android/ios) we make an extra effort to develop once and use it everywhere for easy maintainability.

While we have solved the above problems currently, but as scale increases, there are constant optimizations that we keep doing to keep up with the increase in scale. So the journey only becomes interesting as we go forward. If any of the above challenges excites you please reach out to us as we are hiring at all levels. Please submit your resume at careers@gameskraft.com

--

--

Prakash Shanbhag
Gameskraft

A software engineer by profession who like to learn and share