About 3 years ago I wrote a random NPC generator for the then-brand-new 3rd edition of D&D. It was quite popular for a while (and still has a large following), but suffered from many defects. Eventually, I’d like to rewrite it, and do it exactly “right” this time.
I’ve been thinking for a long time about how to go about doing it “right”. I recently sent Andargor an outline of several items that any good NPC generator must possess. They are:
- The requirements of any purely random or user-directed NPC generator must be clearly specified. The kinds of inputs must be well-understood, in order to craft a generator that people will use. The inputs may be absent (in the case of a purely random NPC), or all-encompassing (in the case of a user building a specific NPC). They may also be specific (such as when a user says that an NPC must have a specific feat or skill), or general (like the concept of a “role”, i.e. a “blaster wizard”). And there may be a generous mix of all of the above (“Give me a neutral good scholar that knows at least 1st level arcane spells, but can also pick locks, and make sure that he has some sort of craft or profession skill, but no more than one of each.”) (90% of the challenge of this is coming up with a user-interface to specify all of the possible constraints.)
- Given those (general) requirements, the generator should be goal-directed and incremental.
Goal-directed: the generator should begin with some “blank slate” and work towards the goal given by the constraints. When a random value is needed to fill in some missing-but-critical constraint, the random value should be tailored somehow to be appropriate for the stated goal(s). There must be some way to identify whether or not the stated criteria are contradictory or not (which may prove quite difficult).
Incremental: the generator should save a snapshot of the NPC at appropriate “save points” along its progression. (These save points will typically be each time a new level is computed for the NPC). This allows the user to identify how the generator reached their stated goal, and also allows the user to tailor their initial criteria appropriately to refine their goal.
The incremental requirement also allows publishers (for instance) to provide snapshots of the NPC at selected points along their career (ie, “here’s Gorzak at level 1, and here he is at level 4, and here he is at level 8”). (Such a feature is very useful for identifying how a character advances through a given class or prestige class).
The incremental requirement also includes the ability to restart the generator from some prior snapshot, thereby appending a new progression to an existing NPC. This allows DM’s to take an existing villain and randomly add several levels to its progression.
- The ability for users to define their own data is critical. This allows publishers to add their own prestige classes, or gamers to add their own custom monsters to the generator. It has been assumed that a text file is the best way to do this (XML, YAML, etc.)
-which indeed is the most portable way. However, parsing megabytes of text on each program invocation is not going to be efficient in the long run (since it will be slow to parse, and would require all of the data to be stored in RAM), so I propose that the text format (whatever it may be) be used only for distributing data. The program itself should use some kind of relational database (sqlite would be ideal-portable, small, and lightweight) for fast access. This may also make it easier to design a user interface to allow users to add new data. (I would hate to require people to learn XML or YAML in order to add data to a program—the worst thing I ever did was with Basilisk and my treasure generator, where I required people to be programmers in order to add data.)
- Output should be customizable as well. The generated characters should be printable, but also transmittable in various formats. Where possible, generated characters should be interoperable with different programs (PCGen comes to mind). Users should be able to create output templates to specify how the characters are saved, printed, and even displayed in-program.
- It should be possible to export and share parts of the overall dataset. This allows users to share portions of their dataset that they created with others. Having some central database where users could upload and download data would be nice, too. Even multiple online datasets would be nice-
that would allow publishers to provide their own data for easy access. The export format should be flexible and portable-I would recommend either XML or YAML.
- The generator should be embeddable. Other programmers should be able to access a well-specified API to use the NPC generator in their own programs (ie, a dungeon generator that populates the rooms, or a town generator that provides details on notable citizens.) Making the generator embeddable would also allow for a web-based generator (such as currently exists), although the web-based version may necessarily be restricted in its functionality (since it may be difficult to create an intuitive web interface for specifying all possible constraints).
- The generator should be localizable. Internationalization should be considered from the very beginning, to make it easy for non-programmers to translate the program and the data to their (natural) language of preference.