FAQ Friday #7: Loot

Since /u/ais523 is doing this with his decades-old codebase, I figured I might as well try to start doing this with Dungeon Crawl: Stone Soup's! :P I suspect that in general, the systems won't be as well-designed as they usually are in modern games with a design thought out from the start, but they do seem to work well enough as they are.

Not that this is a very easy question to answer. Basically, there are three (main) ways for an item to be generated: random generation on the floor, in a vault, or in a monster's inventory. There are also shops, acquirement, starting inventory, god gifts (usually acquirements), and definitely more ways that I'm forgetting.

Floor generation places 3 + 3d11 items (plus a chance to have 10 + ~2d45 instead, which I did not actually know about until I started writing this). These items have a general "quality" based on how deep in the dungeon you are (accounting for the increased difficulty in side branches, as well). This quality, or "item_level" as the code usually calls it is... sometimes relevant in how good the item is. Weapon/armour type, chance of being branded, chance of being an artefact, are all based on this, though what brands are available is not (except in the case of curare-tipped needles, which use the formula

one_chance_in(item_level > 27 ? 6   :
                     item_level < 2  ? 15  :
                     (364 - 7 * item_level) / 25);

). Books also are based on depth (rare ones less common at shallower levels).

On the other hand, scrolls, potions, and wands are for the most part not at all dependent on depth, except for disallowing a few very powerful/dangerous items at very shallow depths. It's all really quite a mess.

Vaults (handwritten pieces of the dungeon) can place items that are treated as being deeper from the generation point of view. Since the depth isn't so often noticeable, what's more important here is that they can place either specific items, which can be thematic/flavourful, and that they can make items a reward for an encounter, which isn't really done by the main item generation routines on its own.

Monsters don't drop any items on death other than what they were generated with as using / picked up while wandering around, which does help make scummy behavior less useful. They generally have a pretty limited set of equipment, which usually is not very useful. But sometimes it is; orc warriors for instance being relatively early monsters both dangerous for their equipment and often providing items that can be useful for a while.

Item generation is very nearly totally independent of your character; vaults can place "acquirement" items (which are guaranteed to not be 100% useless, and try to be useful for your character), but that's frowned upon in general. Arguably the scroll of acquirement, which is generated randomly, fills the role of player-based item generation while at the same time providing a choice -- it lets you choose between several general types of item before giving you one of that type.

I'm afraid that short of ripping out all the formulas and starting over (that example I pasted above may be the worst, but it isn't all that atypical) there's very little way to balance. However, since monster equipment is pretty reliable, that is one thing that can be tweaked quite easily, and has a noticeable effect when playing. For example, when the hell knight monster started to be a lot more common than before with the addition of the Depths branch, their equipment was nerfed hard, since before they'd had very good chances for endgame weapons, which made you stronger (once you killed them and took their stuff) than it did them. So it was pretty straightforward to lower the chances of the really high-tier stuff, in that case at least.

We have tried to improve the situation -- specifically, a system to provide a spreadsheet of item generation (-objstat command line option) was added, to help rebalance item generation after the removal of item destruction. Additionally, several "choose an item/brand type" functions were changed to use explicit weights for each choice, rather than unreadable chained "if (x_chance_in_y())" conditionals.

/r/roguelikedev Thread