Skip to content

New Contributor Guide NPCs

Mark Langsdorf edited this page Jun 17, 2020 · 2 revisions

Adding more NPC dialogue part 2: New NPCs

In addition to normal dialogue, NPCs have mission dialogue and class information.

NPC classes and templates

NPC classes are defined in data/json/npcs/classes.json. The JSON object looks like this:

  {
    "type": "npc_class",
    "id": "NC_FENCE_BARKEEP",
    "name": "Barkeep",
    "job_description": "I'm a local bartender.",
    "common": false,
    "bonus_per": { "one_in": 4 },
    "shopkeeper_item_group": "NC_FENCE_BARKEEP_misc",
    "skills": [
      {
        "skill": "ALL",
        "level": { "mul": [ { "one_in": 3 }, { "sum": [ { "dice": [ 2, 2 ] }, { "constant": -2 }, { "one_in": 4 } ] } ] }
      },
      { "skill": "speech", "bonus": { "rng": [ 1, 5 ] } },
      { "skill": "barter", "bonus": { "rng": [ 2, 4 ] } }
    ],
    "traits": [ [ "FLEET2", 100 ] ],
    "bionics": [ { "id": "bio_ethanol", "chance": 10 }, { "id": "bionic_id_int_enhancer", "chance": 5 }  ]
  }

Relevant bits:

  • "type" has to "npc_class"
  • "id" can be anything, but custom is to start with NC_
  • "name" can also be anything.
  • "job_description" is what the NPCs answers with if you asking what he's doing.
  • "bonus_per", "bonus_str", "bonus_dex", and "bonus_int`" are any increases to the NPC's Perception, Strength, Dexterity, or Intelligence. These bonuses can be negative to reduce the value. I'll describe the format later.
  • "skills" is a list of bonuses to skills, with the skill ids taken from data/json/skills.json
  • "traits" is a list of possible traits. Each possible trait has a trait's "id" from data/json/mutations.json and a value from 0 to 100 that is the percent chance that trait will appear, so this shopkeeper will always have FLEET2.
  • "bionics" is a list of possible bionics. Each possible bionic has a bionic's "id" from data/json/bionics.json and a chance that the bionic will be installed on the NPC. Bionic chances are X in 100, just like traits.

skill and stat bonus and level format

  • "rng": [ X, Y ] means a randomly determined number between X and Y
  • { "one_in": X } means 1 on a randomly determined chance that occurs 1 time in X attempts and 0 otherwise.
  • { "dice": [ X, Y ] } means a randomly determined number generated by summing X randomly determined numbers with values from 1 to Y
  • { "sum": [ X, Y, Z ] } means the sum of X, Y, and Z, where X, Y, and Z can be any of the previous or a mul (below) value.
  • { "mul": [ X, Y ] } means X * Y. X and Y can be one of the previous expressions.

So 1 in 4 shopkeepers will have Perception 9 and the rest will have Perception 8. For each skill, each shopkeeper has a 1 in 3 chance of of having a random skill value between 0 and 2 with 50% of them being 1, and 1 in 4 of those skills will actually be between 1 and 3.

NPC Equipment

Each NPC class can have equipment lists associated with it. These are stored in the data/json/npcs/NC_*.json file corresponding to the NPC's class name (though this structure might change shortly). Inside each equipment list file are a bunch of item_groups, as described in the item creation guide above.
At NPC creation time, items are worn in the order specified in the item_group, so start from inner layers and work your way out.

NPC Templates

NPC classes aren't super interesting. NPC templates are more important. They're the data structures that determine what missions an NPC can provide and what talk_topic the NPC starts talking about. NPC templates are also what you specify in a location's mapgen to actually spawn an NPC.

Templates are stored in data/json/npcs/npcs.json, and look like this:

{
  "type" : "npc",
  "id" : "evac_merchant",
  "//" : "Appears in the refugee center as shopkeeper with missions.  Faction critical.",
  "name_suffix" : "Merchant",
  "class" : "NC_EVAC_SHOPKEEP",
  "attitude" : 0,
  "mission" : 3,
  "chat" : "TALK_EVAC_MERCHANT",
  "mission_offered" : "MISSION_FREE_MERCHANTS_EVAC_1",
  "faction" : "free_merchants"
}

Relevant bits:

  • "type" must be "npc"
  • "id" can be anything, but it's the template's ID for mapgen spawn functions
  • "name_suffix" is a string appended to the NPC's randomly generated name.
  • "class" must be a valid NPC class "id", as described above.
  • "attitude" must be one of these numbers, with the corresponding attitude
    • 0 = null, NPC can do their own thing
    • 1 = talk, NPC will attempt to approach the player and talk to them
    • 3 = follow, NPC is a friend of the player and can be commanded
    • 7 = defend, NPC stays where they are at defends themselves
    • 10 = kill, NPC attempts to kill the player
    • 11 = flee, NPC flees from the player
  • "mission" must be one of these numbers, with corresponding behavior
    • 0 = null, NPC can do their own thing
    • 3 = shopkeep, NPC stays in one place but will attempt to trade with the player
    • 7 = guard, NPC stays exactly where it is
  • "chat" is the first talk_topic that the NPC will use when the player talks to them - after that, they'll use the talk_topic based on the player's response.
  • "mission_offered" is the first mission the NPC will offer if the player asks about missions. I'll talk about that more in the mission guide below.
  • "faction" is the faction "id" from data/json/npcs/factions.json. Factions determine how the NPC reacts to the player initially, and some factions will attack the player on sight.

How to add a completely new NPC

  1. Optionally, create an NPC class in data/json/npcs/classes.json, and create the item groups for the class' gear in data/json/npcs/NC_CLASSNAME.json
  2. Optionally, create the NPC template in data/json/npcs/npcs.json. Assign it the new class or an existing class. If you want the NPC to talk to the player and not run off, give it "attitude": 0 and "mission": 7.
  3. Optionally, create a sequence of talk_topics for the NPC's dialogue, and assign the first talk topic to the NPC template's chat.
  4. Optionally, create a mission quest chain, and assign the first mission to the NPC template's mission_offered.
  5. Really optionally, add a new faction to data/json/npcs/factions.npc and assign the new faction to the NPC template's faction.
  6. Put the NPC on some overmap terrain definition using "place_npcs" and specifying the template in the "class" entry.