8 October 2015

fearsome critters

I'm working on random animal species for LoSt. I figured this is a good place to start, before adding (randomized) NPCs, which will be a lot more complex. The basic engine has been tested with a quite bland "foo beast" and a "monstrum biformis". The foo beast gets a very simple random name and shape that each member inherits, whilst each individual monstrum biformis is a unique mixture of two animal parts. I might keep these genotypes in the game, just for the hell of it, although they'll have to be refined and renamed (in particular the monstrum biformis, which I don't even know how to decline in plural).

Genotypes are distinguished at least by their morphology (including health and main attack form), habitat (how and where it's encountered), and behaviour (simple AI plug-ins like "flock mentality" and "self-preservation" apply goals and tactics), as well as special quirks (stuff like poison, spinnerets and tunneling fall under this category). Just working with these four basic parameters makes a wide range of beasts possible: Consider that if I hobbled together ten templates for each of them, the engine would support 10 000 different kinds of animals.

However, it also becomes clear that a completely random bestiary won't work. The results would too often be ridiculously unbalanced, or simply uninteresting. There must be some method to the madness, and it's worth considering which functions encounters serve in the first place.

1. They might provide a challenge to the player: Encounters which are aggressive or otherwise have to be overcome create a tension in the game. We're making a Roguelike here, so the player should always be wary of suddenly coming under attack. Even if not generated hostile, NPCs and neutral entities can provide challenges in the form of missions, puzzles and other tasks.

2. They might advance the character: The basic form of this in most Roguelikes and rpgs is killing the next guy to steal his cash or other stuff. Another classic RL trope is experience points. There'll be no xp in LoSt, nor will dumb beast go about carrying various treasures. (But there might come some survivalist mechanics that include hunting later on.) Again, neutral/friendly critters can also advance the character. Shopkeepers ("travelling saleskids" in LoSt) spring to mind, as do missions with rewards.

3. They should provide mood or story: Not least, and this goes for friendly as well as malicious critters, they should speak to the mood and setting of the game. Whether pilfering booze off a mad prospector, barely escaping a crazed bear, saving a small reptile from the claws of a feral cat, or just observing a flock of birds taking off from a far away field, the player should experience that the animals and persons s/he encounters form a greater whole, some kind of game world.

There's a lot to consider here, especially when expanding a randomized system. The first two points directly point to gameplay aspects, and must be balanced in relation to each other. But they also tie in with the third point: If a game world contains only vile predators, the engine has failed on all points – the game would probably be too hard, and in addition such a setting makes no sense (what would they eat, apart from the player?). The same goes for a world with nothing but docile prey – which might bore the player in so many ways, unless (who knows?) a freak accident transforms our Roguelike, for a single session, into some kind of pastoral simulator.

In that sense, consistency of mood and story is useful as a kind of measuring stick to get an intuitive feel for whether the game world is properly balanced. But for LoSt, it's no less important in and of itself. Frankly, I'd rather make a game with an evocative game world than one that is superbly balanced. And I certainly hope in the long run to implement some features and content that will borderline on procedurally generated literature, randomizing things like dialogue, monologue (including folk songs), monster memory, item descriptions and mission details.

Some words about the actual design: On the technical side, I have defined a bunch of critter templates and traits that can be combined to spawn actual beings (I call these data templates kits). Most of these kits describe very simple qualities, like "beaked", "small" and "avian", which combined gives the outline of some random bird. A slightly bigger bird, like a buzzard, could be specified as "medium" and attacking with an improved beak. And of course there is room for things like giant dogs with antlers and airborne mini-aligators!

What I'm doing at the moment, is bundling kits together into bigger packages and specifying templates which are more picky about which kits they choose. This enables me to steer what kinds of animals are generated, whilst still retaining a degree of randomness. For instance, the basic kit "flocking bird I" inherits subkits like "small avian template" (basic morphology, including attack and defense stats) and "flock mentality" (currently a very crude set of behaviours, just trying to approach as well as defend critters of the same species). This basic kit can be patched with further traits (specifying for instance that the species sports a special attack, or that it's a flightless fowl). Another basic template I have in place is called "royal predator I". It is always a solitary beast with good combat stats and a penchant for attacking critters tagged as "prey" (which in turn are programmed to flee anything tagged as a "predator"). Other than that, the royal predator can turn out a mammal, a reptile, or even a giant bird.

During world generation, each climate type randomly generates its encounter table by spawning a few species types. Again, the tables are weighted: A certain climate might demand to get one predator, one prey, one carrion eater, and one completely random animal. The system should be smart enough to be able to pick for instance "flocking bird I" as its carrion eater, and then patch it with the appropriate kits to make it go after corpses and eat them. I'll also have to implement filters to make sure that the same species template isn't picked over and over again. I'm considering emulating something like decks of cards – lists containing one or more references to each appropriate kit, removing referances as they are picked and used.

Be that as it may, I'm currently less concerned with balancing than just getting the engine to spit out some interesting beasts. I'm of course reviewing Borges' entry on American cryptozoology in The Book of Imaginary Beings, and trying to dig up some other sources of inspiration. One thing that is becoming clear to me, is that I need to differentiate between the different groups/families of species. Right now, there is little difference between a giant lizard and a cow, except for slightly different attack forms. Making each type more distinct will not only make the bestiary more varied, but will also strengthen the kind of learning curve that is typically associated with Roguelikes. I don't really want a game where experienced players share a standardized knowledge of "which resistances to stack up on" before engaging which critters. But it'd add some depth and predictability if certain patterns are true for every game. Maybe cats are inherently fast and reptiles inherently tough, for instance. That way, a knowledgeable player will be prepared to draw some information just from seeing a critter for the first time, and yet not be sure what to expect from every new playthrough. A world full of raging bulls will probably require different tactics to handle than one stalked by man-eating lizards. And the mark of an experienced player would be that s/he's able to deduce facts about the generated world, and react accordingly.

As the bestiary starts falling into place, I'll be picking up my old plant life generator and migrate it from python sources into files containing kit definitions. At which point we're looking at an upcoming release to see if I can harvest some comments on the basic workings of the biotope generator. Never mind if it's going to be badly balanced and utterly crazy – there will be due time to reflect and refine later on.

As always,