Over the last week or so, instead of porting more map entities from the RMQ codebase, I sat down and did SJ’s loot system. As you can see in this flow chart, loot is absolutely central in SJ; almost everything in the game goes through the loot system at some point. So actually building it just came naturally.
SJ needs a way to store a lot of items of several different types, with quite a few properties per item; it needs to be able to add, remove and transfer items between entities; and it must be able to do random selections from the item pool according to various criteria. This was done using FTEQCC‘s support for structs and arrays.
The most time consuming part turned out to be the random selection. My first implementation was rather simplistic, basically setting up some biases for what could be dropped at what probability and by whom, and then running a simple random() across the pool of eligible items.
There were some problems with that, the major one being that rare items would end up having the same drop chance as common ones. That was shite. Instead, after a lot of research, SJ is going to use weighted random distribution. Most items (generic loot, meds/drugs, ammo, charms etc) will be dropped according to that method. Drop chances of each item are determined per-monster. Weapons are fixed drops, meaning any enemy will always drop their weapon and the ammo that’s still in it.
At some point, I noticed that certain subgroups of items needed to be better developed before they could be included; namely armour, which I hadn’t wasted too many thoughts on previously, and charms. Due to that, I’m now finally nailing down those aspects of the game in order to finish populating the loot structs and tweak the loot handling functions to take all item types into account. I’m researching, designing and programming my ass off at the moment, in other words.
Anyway, the basic system is there, and it only took like a week, which I think is fast. That’s some major progress with the implementation of critical game elements right there.
The same system for weighted selection is going to be used for spawning enemies; this because spawning creatures during runtime is the norm in SJ (unlike Quake where monsters are placed by the mapper and spawned all at once as the level is loaded). We had experimented with randomizing the monster spawns in RemakeQuake already, where they could be randomly picked from a pre-defined, mapper-selected group (‘Lardarse’s randomizer’). In Scout’s Journey, randomness is now a fundamental game mechanic. There are many entry points into the game world for enemies, and very few of them are determined by the level designer anymore. All the level designer does is place installations and mark patrol routes for the factions. Each of the 4 factions has several units (pure surveillance units as well as spellcasters) that can summon troops; even fixed installations around the level can summon troops on their own and send them out on patrols or whatever. That means a level is never truly “finished”, but instead becomes continuously contested ground where situations can emerge between enemy factions and so forth. And each randomly spawned unit is loaded with randomly selected loot, which in turn can be exchanged for *still* other things in certain places by the player.
I actually made myself a set of bottle caps with rarities noted on them to represent my items, and then did random selections on them to better understand the weighted selection process. It’s really quite remarkable. This is why drinking beer is good for you, it helps you understand statistics.
The other half of SJ’s core systems needs CSQC to graphically represent item transactions. That is the next big thing.
Lots of progress recently.
Thanks to Lord Havoc and Spike for valuable input.