Backend
The core of the backend system uses ProfileService which is an extension module for DataStores. ProfileService is a is a profile object abstraction seperated from the Player instance which streamlines datastore implementation and handles lots of edge cases such as providing protection against item duplication exploits.
Monetization and Transaction Workflows
There are two types of transactions the player can make: Robux transactions and RVU transactions. RVUs (Relative Value Units) are the in-game premium currency.
Developer Products
- The client uses a remote event to request developer product purchase
- The server recieves event and fires
MarketplaceService:PromptProductPurchase
with the player and product id - The player purchases the product using the Roblox GUI
- If the transaction is successful, the
MarketplaceService.ProcessReceipt
callback is triggered- If verification fails,
Enum.ProductPurchaseDecision.NotProcessedYet
is returned
- If verification fails,
- The server retrieves and verifies player’s data profile from ProfileService
- If there is an error verifying the player profile,
Enum.ProductPurchaseDecision.NotProcessedYet
is returned
- If there is an error verifying the player profile,
- The player’s data profile’s metadata is reviewed and written to ensuring the developer product is not being granted multiple times for the same transaction
- If an error or abnormality is detected,
Enum.ProductPurchaseDecision.NotProcessedYet
is returned.
- If an error or abnormality is detected,
- The product id is processed and the product is added to the player’s account
- A remote event is fired informing the client that the purchase was a success
Enum.ProductPurchaseDecision.PurchaseGranted
is returned
Notes:
- If
Enum.ProductPurchaseDecision.NotProcessedYet
is fired,MarketplaceService
will perform the transaction again if the user makes another purchase or rejoins the server.

Custom Currency (RVU) Products
A similar workflow is used for RVU purchases, but it does not go through the MarketplaceService
due to the currency being proprietary. If a player does not have enough RVU to complete the transaction, they are prompted to purchase more.

Gamepasses
Gamepass purchases rely almost entirely on the Roblox backend, which prevents players from purchasing the same gamepass multiple times. When joining the game, players are sent to a lobby. When they are ready to play the game, players hop in an elevator which moves them to a private server and sets up the match. Gamepasses only purchasesable in the lobby or on the Roblox website and only affect the match servers, therefore there is no need to detect gamepass purchases in real time.
MarketplaceService.PromptGamePassPurchaseFinished
could detect real time purchases in game servers, but the player’s gamepasses would still need to be detected when the player loads into the server to account for purchases on the website. So to avoid redundancy, MarketplaceService.PromptGamePassPurchaseFinished
is not used and any new gamepasses are detected when players first load into a server and are recorded on the player data profile. These gamepasses are then applied accordingly.
Player Statistics
By using ProfileService, tracking specific player stats is streamlined. The module allows for the tracking of any player-specific statistic that seems interesting, such as deaths to specific monsters, games played, currency collected, etc. Statistic tracking runs through the custom PlayerDataService module, and any corner of the code base that wishes to record data runs through it.
Global Statistics
Global statistics rely solely on Roblox’s DataStoreService rather than running through PlayerService. For leaderboard tracking, ordered data stores are used and are shared throughout all servers. These sort user ids in descending order based on the statistic being tracked. When read from, only the top page in the data store is retrieved. For data stores that don’t need sorting (such as name in the game), only user ids are stored.
There are several globally tracked items:
- Name in the Game Gamepass Purchases
- When purchased, the player’s avatar will begin to spawn in hospital beds around the level. This occurs in all games, not just games the specific player is in making it possible for anyone who loads into the game to see the player’s avatar.
- Lifetime RVU
- This includes RVU earned by playing matches as well as RVU purchased
- Lifetime Wins
- Recorded when a player beats the game
- Lifetime Games
- This is recorded every time a player starts a match

Analytics
MODERN MEDICINE’s post launch development relies heavily on use of Roblox’s AnalyticsService
to determine player retention and drop off rates through funnels and other analyitics. Throughout the game state logic there are dozens of analytics hooks tracking player progression, monster damage, shop purchases (not with premium currency). Using the data accumulated from thousands of playthroughs on the live servers we are able to pinpoint weak aspects of our game and target them for improvement. Using analytics we were able to improve the tutorial conversion rate to over 87% only a few weeks after launch.
