Creating a Race
Race folders need to go in [server folder]/plugins/Adventures/races/YourRaceHere. Every race needs a descriptor, or a file that tells Adventures what to load for your race. This will be info.yml OR info.js OR info.extension, where extension is an embedded Java script language such as Jython or JRuby.
If a scripting language is used for the info file, it will need to have a getDescriptor() method in the root namespace which returns an instance of net.citizensnpcs.adventures.race.RaceDescriptor.
YAML Info File Structure
Example YAML file showing all currently available keys:
name: Name # required tribe: max-size: 10 # required behavior: # optional, a behavior root node (explained later) members: names: # required, a list of possible names for new members to have, picked at random 0: Bob 1: SirBob 2: Bob2 types: # required, a list of possible entity types for new members to have, picked at random 0: CREEPER behavior: # optional, a behavior root node (explained later) dialog: allowed-rules: rule1, filename1 # comma-separated list of rules to allow (can be per-rule or per-file). Leave empty for all rules allowed.
The behavior root nodes are important for tribes. They are defined as a decision tree of behaviors, which are a single unit of work for an NPC. A tree is a way of organising data which looks similar to an upside-down tree. For a simple illustration, look here. The NPC's AI will start from the top and work its way down to a behavior.
There are three flow constructs that help with behavior flows: sequences, selectors, and decorators. A sequence simply executes each behavior in a list one-by-one until they are all finished. A selector picks one or more behaviors from a list based on some kind of strategy, like a random selection or a priority-based selection. A decorator wraps another behavior without knowing what it does, for things like stopping it after a certain amount of time, or inverting its responses, or doing something before/after it completes.
Finally we have the edge nodes, which are user-defined and do actual work with the NPC. This is a very powerful construct that allows complex behaviors to emerge.
We define this in YAML like so: