RDS Calculator is an implementation of Loot Tables or Random Distribution Systems described by Mike (Prof. Chuck), but without the hooks. The concept of loot tables is what powers the "drops" that come from defeated enemeies in especially role playing games. "Lord of Destruction", the enemy, drops e.g. between 100-150 gold and "Shard of the Underworld", but then there's a 50% chance of dropping "Knuckledusters of Fury", a 25% chance to drop "Rolled-up Newspaper", and a 1% chance to drop "Morning's Cake Ring".
That can be represented (imperfectly) by a table with a count of 3 and the items:
|Shard of the Underworld
|Knuckledusters of Fury
|Morning's Cake Ring
In this system, name and range describe the item and how many are included when rolled. "Always" means the item must be included as one of the items in the results. "Chance" is the relative probability that the item will drop. The count on the table represents the number of times we roll on the table for a result.
In the case of the Lord of Destruction's loot via the above table, the results will always include Gold and Shard of the Underworld. That makes up two out of the three items. The final item could be any of the remaining items or nothing. In my app, the method I chose for figuring that out is
- Find a hit count between the range of 1 and the sum of chances (50 + 25 + 1 + 24 = 100)
- Iterate through the items
- If the hit count is less than or equal to the chance, return the item
- If the hit count is greater than the chance, subtract the chance from the hit count and continue
- Stop if we found enough items
This doesn't include considation for unique items or the idea of sub-tables. Those ideas are included in the full calculator and can lead to some really interesting situations.
RDS Calculator is a Ruby on Rails app that uses PostgreSQL for storage and Tailwind for styling. It is hosted on
Digital Ocean App Platform Railway via Docker container. Most of the app is classic MVC server-side, but the "Roll for X items" feature is implemented as a turbo stream so that the whole page doesn't need to be rerendered. It is open source.