Guide to adding new content to CDDA for first time modders

Getting Started

Here’s a bunch of links that contain more information about how set yourself up to make a change to CDDA: is an illustrated tutorial on setting up a github account, forking and cloning the repo, and pushing a PR. has the same information in th middle. You can 100% ignore all the stuff about compiling, but it’s the same process to share JSON and code changes, so set up a github account.

Technically, you can just edit the files in your game’s data/json folder, but if you do that while in a git repo, then git will automatically keep track of your changes.

This is mostly about the mod manager app, but it gives the basics of setting up a new mod:

There’s a fair bit of documentation in the game already:

Start with the modding guide:

then the general JSON format guide:

Before you contribute, make sure you read the JSON style guide and the manual of style for descriptive text:

More on adding specific types of content


Adding a new recipe

Recipes determine what you can craft. They’re relatively easy to add.

Recipes are stored in data/json/recipes . There are some subfolders there and subfiles like recipe_food.json. Just pick one that seems appropriate.

This is the JSON object for the salt (made from boiling water) recipe:

    "type": "recipe",
    "result": "salt",
    "id_suffix": "from_salt_water",
    "category": "CC_FOOD",
    "subcategory": "CSC_FOOD_OTHER",
    "skill_used": "cooking",
    "difficulty": 0,
    "time": 90000,
    "autolearn": true,
    "batch_time_factors": [ 80, 4 ],
    "qualities": [ { "id": "BOIL", "level": 1 } ],
    "tools": [ [ [ "water_boiling_heat", 3, "LIST" ] ] ],
    "components": [ [ [ "salt_water", 10 ], [ "saline", 50 ] ] ]

Important bits:

  • "type" has to be "recipe"
  • "result" is the "id" of the item that the recipe creates. items are defined in data/json/items/ and its subfolders.
  • "id_suffix" is used to differentiate two recipes that have the same results. It doesn’t really mean anything and you can put anything here as long as every recipe with the same result has a different id_suffix, but it’s good practice to use something that makes it easy to tell why each recipe is different.
  • "category" and "subcategory" are where the recipe will end up in the craft menu. You have to use a valid string in both cases, so look through the recipes to find one in the same category as your new recipe and use those values.
  • "skill_used" is the "ident" of the primary skill for the recipe. possible skills are in data/json/skills.json
  • "difficulty" is the number of the skill level where you have a high chance of automatically making this recipe.
  • “time” is the number of ticks to create a single result. 100 ticks is 1 turn or 6 seconds.
  • "autolearn" is true if you learn the recipe automatically when your skill reaches difficulty. Otherwise, there should be a "book_learn" entry, with a list of lists of references books and the skill level at which you get the recipe, like "book_learn": [ [ "cookbook_sushi", 3 ] ] for sushi veggy rolls. The books are refered to by “id” from data/json/items/ again.
  • "qualities" is a list of tool qualities you need to make the recipe. Available qualities are in data/json/tool_qualities.json and items define what tool qualities they provide. Items that provide qualities are not consumed by the recipe.
  • "tools' is a list of tool types you need, in addition to the qualities. While qualities is a list of objects, tools is a list of lists. Items that provide tools are not consumed by the recipe.
  • "components" is a list of lists of components that are consumed by the recipe. They break down like this:
    [ "water", 1] is a single component, where the first string is "id" of the item in the component, and the second number is the number of that item that is required.
    [ [ "water", 1 ], [ "water_clean", 1 ] ] is an options list. it’s a list of single components. either component can be used to satisfy the recipe. It can have as a single entry.
"components": [
  [ [ "scrap", 1 ] ],
  [ [ "water", 1 ], [ "water_clean", 1 ] ],

is the full components list, made up of options lists. So this recipe requires a piece of scrap metal and a unit of water or clean water.

So adding a new recipe requires that you have:

  • the id of resulting item
  • the ids of all components and tools
  • the qualities of any tools specified by quality
  • the ident of the skill
  • the difficulty of the crafting
  • the ids of any books used to learn the recipe
  • the time to make the recipe.

Is adding enemies or creatures something that can be done in JSON currently? If not, will it be in the future?

I had some ideas about tinkering with the Mi-go. They are supposed to be intelligent and have a society, albeit an evil axe murdering parody of one. I wanted to add marauding bands of Mi-go slavers, wielding cruel and exotic alien weapons.

Adding to the biodiversity of the game environment is something else I was considering. More wildlife, as well as mutant variants. Like tentacle deer or something.

1 Like

Monsters are JSON entities and can be added. I just forgot about them.

Vehicle parts are also JSON entities, but 90% of what people want to do with new vehicle parts require C++ coding so I’m going to address them last.


Someone - someone who doesn’t also have mountains of awesome code to write - should consider translating this to a doc on GitHub too.

1 Like

Adding a new items

Items are things in the game. They’re usually easy to add, but there are some subtle bits.

Items are stored in data/json/items/ . There are a lot of subfolders and subfiles, so try to pick the most appropriate one. Some guidelines:

  • melee weapons go in melee.json
  • guns go in the gun/ subfile for the gun’s ammo, while new ammo goes in ammo/, gun magazines go in magazine/
  • comestibles contains all food, drink, and medicine
  • vehicle parts go in vehicle/ but are a separate, complicated topic.
  • clothing and armor go in armor.json for the most part.

items have a lot of different fields in their objects, so I’m just going to highlight the most important ones. For everything else, read and

    "id": "hide_bag",
    "copy-from": "raw_leather",
    "type": "COMESTIBLE",
    "category": "clothing",
    "name": "hide bag",
    "description": "The raw skin of an animal, quickly turned into a makeshift bag for storage.  It will still rot, and needs to be cured and tanned.",
    "symbol": "[",
    "color": "pink",
    "looks_like": "swag_bag",
    "armor_data": {
      "covers": [ "ARM_EITHER", "HAND_EITHER" ],
      "coverage": 5,
      "encumbrance": 100,
      "storage": 60,
      "material_thickness": 1,

  • "id" is the internal reference string for the item, and must be unique among all other items.
  • "type" is the type of item. Items can have multiple types, like the hide_bag technically being edible (required so it will rot) but having armor data so you can wear it.
  • "category" is the category the item will be sorted in for inventory lists. It is unrelated to the item’s type - you can food in the clothing category, armor in the tool category, whatever makes sense.
  • "copy-from" is a special field. It references another item’s "id" and means use that item’s values except where they differ from this item’s. In general, you should use copy-from as much as possible because it reduces the number of things that future developers will need to change when making a change. For instance, almost all guns are copy-froms for a a single abstract gun, which means if there is a change made to how guns work, that single abstract gun gets changed and all the other guns get the change automatically.
  • "looks_like" contains the "id" of another item that the item might look like. If a tileset doesn’t have a tile for your new item, it will check if it has a tile for the looks_like and use that instead.

Special item considerations

  • an entirely new gun will need a new item for the gun, a new item for the ammunition, and a new item for the detachable magazine, if any. You’ll have to create all three. In general, please don’t create new ammunition until you have a solid understanding of adding items, but its more acceptable to create new guns and new magazines.
  • books with recipes don’t define the recipes they contain. Instead, the recipes reference the books. So if you want to create a Tex-Mex cookbook, you have to create an item for the book and then go through the food recipes and references to the book in the recipe’s "book_learn" fields.

Spawning items

Adding an item’s definition just defines the item. It doesn’t make it show up in the game. To do that, you’ll need to add the item to one or more item_groups.

Item_groups mostly live in data/json/itemgroups/ and data/json/item_groups. There’s an entire doc on item groups that explains it very well:
Some locations have their own item groups that are defined in the location’s definition in data/json/mapgen/ , so you may need to add stuff there, too.

Don’t forget the recipes

If an item should be craftable, you should also add a recipe for it. See the previous post.

Sample process: Adding a new gun

  1. Add the new gun to the gun’s caliber JSON file in data/json/items/gun/
  2. Add the new gun’s new magazines (if any) to the gun’s caliber JSON file in data/json/items/magazine/
  3. Add the gun and magazine to one or more item groups in data/json/item_groups.json, data/json/itemgroups/, and/or data/json/mapgen/
  4. If the gun or magazine can be crafted, add recipes for them in data/json/recipes/

How do I give you one million hearts?


I would like to second AskaHope on this.

I volunteer as tribute. @Mlangsdorf if you message me once you have everything you want posted, I would be willing to compile it into a single document.

If you want to express your appreciation, use these documents to add new, interesting content to the game. I’m putting recipes and items first because they’re easy to define and describe, but I would so much rather see more missions and quests and NPC dialogue than another gun or piece of armor.


I surely will! I’ve been trying to mess with JSONs for quite a while, but this will help a lot!

Just wanted to say I appreciate what you’re doing here. So much of what I learned about modding Cata was trial and lots of error. The old modding docs are helpful but also out of date.


Adding a new map locations

Map locations can be added to the game in JSON. I’m not a maps guy, so I’m mostly going to point people to the docs and offer some advice. Also, lots of people figure out how to add new locations so it may not be too difficult.

A map location is defined across multiple files.

  • The basic map, including monsters, NPCs, vehicles, traps, and items, is defined in a file in data/json/mapgen/ . data/json/mapgen/fire_station.json is the fire station, for instance, and it’s a good reference because it’s a moderately complicated, single tile design that only has one variant so you can look at the JSON and compare it to the game and make sense of it.
  • Maps can have their palettes defined in the mapgen/ JSON file, or in a separate file that is customarily stored in data/json/mapgen_palettes/
  • One or more maps can be collected into an overmap special, defined in data/json/overmap/specials.json. The JSON objects in this file control how a map spawns, where it is relation to a city, etc.
  • data/json/overmap_connections.json and data/json/overmap_terrain.json also deal with mapgen, but frankly I don’t understand how and you should not mess with them absent better information.

The main document for mapgen is It’s a little confusing at places, but you can basically ignore the sections on LUA and focus on the JSON sections.

More on data/json/specials.json

  • "sym" represents the symbol used. You can look at other mapgen entries to match up ‘correct’ symbols.
  • "color" is the color.
  • "see_cost" determines how far away you can spot the location, though I’m not 100% on how it works. I think you have a maximum number of tile-equivalents you can see, and a tile with a higher “see_cost” counts as more tile-equivalents.
  • "mon_density" affects the density of creatures you place in your mapgen entry.
  • "flags" are special tags that have particular effects. For example, I believe the flag “SIDEWALK” will attempt to attach your location to a sidewalk. So if you’re making a house or readily accessible building, you want that flag.
  • Important Note! There is an "occurrences" field in each object in specials.json, which is a list of two numbers like this [ 0, 4 ]. The first number is the minimum number of times your special will appear on an overmap, and the correct value for that number is always 0. Not 1, not 2, not 4, it should be 0. I know your overmap special is extra special and you want to see it on every map, but nevertheless, the minimum number of occurrences is 0.
    The second number is the maximum number of occurrences, which can be any number greater than 0.

Also, I’m going to take this moment to admit that I am not much of a JSON developer, so if other people have additional ideas, comments, or suggestions, please correct my mistakes and bad advice.


Well, regarding overmap_terrain – as far as I’m aware (though I’m also not terribly experienced), this file mainly determines how your new location will look on the map.

IE: name determines what is displayed when that maptile is selected.
“sym” represents the symbol used. You can look at other mapgen entries to match up ‘correct’ symbols.
“color” is the color.
I believe “see_cost” determines how far away you can spot the location, though I’m not 100% on how it works.
“mon_density” affects the density of creatures you place in your mapgen entry.
“flags” are special tags that have particular effects. For example, I believe the flag “SIDEWALK” will attempt to attach your location to a sidewalk. So if you’re making a house or readily accessible building, you want that flag.

These flags can do wonky things depending on how you set up your mapgen entry and will probably require some trial and error.

I believe the “NO_ROTATE” flag will always spawn your mapgen oriented in the way you design it in your entry.

I can’t be super-specific, but this information would have been helpful to know when I started out, so, there it is. I read a lot of this somewhere but I don’t know where. x_x


Adding more NPC dialogue

NPC dialogue is partially implemented in JSON and partially implemented in C++ code. Most of the dialogue to command an NPC companion such as faction camp missions or setting combat priorities is still hardcoded. But almost all general dialogue, including assigning missions to the player, can be done through JSON.

NPC dialogue is stored in data/json/npcs/ , specifically the TALK_*.json files and talk_tags.json. The dialogue system is extensively documented in, but it’s one of the things I maintain so I’ll talk about it a little more.

Dialogue consists of talk_topics, where each talk_topic has a "dynamic_line" that the NPC says, and then a "responses" list of things that the player can say in response. This is the talk_topic object for the Old Guard Rep at the evacuee center:

    "id": "TALK_OLD_GUARD_REP",
    "type": "talk_topic",
    "dynamic_line": { "u_has_any_trait": [ "PROF_FED" ], "yes": "Marshal...", "no": "Citizen..." },
    "responses": [
      { "text": "Who are you?", "topic": "TALK_OLD_GUARD_REP_NEW" },
      { "text": "Heard anything about the outside world?", "topic": "TALK_OLD_GUARD_REP_WORLD" },
      { "text": "Is there any way I can join the 'Old Guard'?", "topic": "TALK_OLD_GUARD_REP_ASK_JOIN" },
      { "text": "Does the Old Guard need anything?", "topic": "TALK_MISSION_LIST" },
      { "text": "Well, bye.", "topic": "TALK_DONE" }
    "//": "TODO: The rep should know whether you're actually a sworn officer: Wearing the badge without the trait => Bad idea"

Dynamic Lines

Dynamic lines can be strings, lists, or objects, and any string can be replaced by a list or objected repeatedly. So that dynamic line could be expanded to provide a lot more variety like this:

"dynamic_line": {
  "u_has_any_trait": [ "PROF_FED" ], 
  "yes": [
    "Marshal, it's good to see you."
    "What can I do for you, Marshal?"
  "no": {
    "u_is_wearing": "badge_marshal",
      "yes": [
        "Where did you get that badge?",
        "Why are you pretending to be a US Marshal?",
        "Explain yourself!  You're no <swear> Marshal, but you're wearing the badge!"
      "no": [
        "Can I help you?",
        "Is there something you need?",
          "u_male": [
            "You look capable, I may have some work for you."
          "u_female": [ 
            "Hello miss, the US government is an equal opportunity employer."


"<greet>" and "<swear" are examples of snippets. Snippets are stored in data/json/npcs/talk_tags.json, and are lists of strings. When the dialogue system gets ready to display text that includes a snippet, it randomly selects a snippet from the list and inserts it in the text. So that "<greet>" would reference the greet snippet:

  "type" : "snippet",
  "category" : "<greet>",
  "text" : [
    "Hey <name_g>.",
    "Greetings <name_g>.",
    "Hi <name_g><punc> You okay?",
    "<name_g><punc>  Let's talk.",
    "Well hey there.",
    "<name_g><punc>  Hello.",
    "What's up, <name_g>?",
    "You okay, <name_g>?",
    "Hello, <name_g>.",
    "Hi <name_g>"

and the Old Guard Rep would have 12 new lines that he would randomly say to you.
Snippets can also reference other snippets, such as the references to which is a snippet for punctuation or to <name_g> which are various friendly references.

Existing talk_topics don’t take nearly as much advantage of snippets as they could, and a good learning project for someone who wanted to get started contributing would be to add a bunch of snippet references and new snippets to the existing dialogue.


Responses are the options for things that the player can say in response to the NPC. There is a whole system for deciding which responses to display, and then having various changes to the game get triggered when the player chooses them. It’s all documented in, linked above.

Also, the "text" section of a response is a bit of dialogue, and can use snippets just like dynamic lines do. Player responses could also use more snippets.

A friendly offer

The existing filters for dynamic lines and responses were the ones necessary to get the game’s existing dialogue out of the C++ hardcode into JSON. They are by no means all the filters that you might want for some piece of dialogue you’re working on. Similarly for response effects.

If you are working on NPC dialogue for vanilla game, or for a mod that is included in the game’s CleverRaven repo at github, and find you need a filter or effect that doesn’t exist, please PM me here or on reddit or on the CDDA Discord or open a github issue and I’ll try to add it in a reasonably timely manner.


New missions can mostly be added in JSONs, but it’s another large topic.


Adding more NPC dialogue part 2: New NPCs

In addition to normal dialogue, NPCs have mission dialogue and class information. I’m going to start with the class information first.

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_JUNK_SHOPKEEP",
    "name": "Shopkeep",
    "job_description": "I'm a local shopkeeper.",
    "common": false,
    "bonus_per": { "one_in": 4 },
    "shopkeeper_item_group": "NC_JUNK_SHOPKEEP_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 ] ]

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.

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/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.

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 are mostly nonsense, but they determine how the NPC reacts to the player initially, and some factions will attack the player on sight.

How to 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.

Adding more NPC dialogue part 3: New Missions

NPCs can give the player missions. Mission structure is fairly complicated and some parts of it aren’t in JSON yet, but you can add simple fetch quests and monster kill quests in JSON.

Mission data is stored in data/json/npcs/missiondef.json. There’s some documentation at but I’m going to expand on it. Each mission looks like this:

    "id": "MISSION_RANCH_NURSE_9",
    "type": "mission_definition",
    "name": "Find Advanced Emergency Care",
    "goal": "MGOAL_FIND_ITEM",
    "difficulty": 5,
    "value": 50000,
    "item": "emergency_book",
    "start": "ranch_nurse_8",
    "origins": [ "ORIGIN_SECONDARY" ],
    "followup": "MISSION_RANCH_NURSE_10",
    "dialogue": {
      "describe": "We need help...",
      "offer": "Have you heard of a book called the 'Guide to Advanced Emergency Care?'  I really need a copy.  The doctor is requesting a lot of supplies that I'm not familiar with but I believe I could make if I could get a copy of the book.",
      "accepted": "I'm counting on you.",
      "rejected": "Come back when you get a chance, we need skilled survivors.",
      "advice": "Libraries are the only place I'd think to look.",
      "inquire": "Do you have the Guide to Advanced Emergency Care?",
      "success": "Thank you for your assistance.",
      "success_lie": "What good does this do us?",
      "failure": "It was a lost cause anyways..."

Relevant bits:

  • "id" is the internal mission ID
  • "type" must be “mission_definition”
  • "name" is the sentence displayed when you look up your missions, so make it as clear as possible
  • "value" is the cash value of the mission, in cents. So a mission worth $500 in goods on completion has a value of 50000
  • "goal" is a special string. Currently, JSON only missions can only really take “MGOAL_FIND_ITEM”, “MGOAL_KILL_MONSTER_TYPE”, and “MGOAL_KILL_MONSTER_SPEC”.
    • MGOAL_FIND ITEM means the player must find any copy of an item and bring it back.
    • MGOAL_KILL_MONSTER_TYPE means the player must kill a number of a specific type of monster, like shocker brutes.
    • MGOAL_KILL_MONSTER_SPEC means the player must kill a number of a specific monster species, like MUTANTS
  • "item" is the "id" of the item to retrieve, from data/json/items/
  • "count" is an optional number that is number of items to retrieve. if it is absent, only 1 item is needed.
  • "monster_species" is the monster "species" to kill for MGOAL_KILL_MONSTER_SPEC. You can find a list of species in data/json/species.json.
  • "monster_type" is the monster "id" for MGOAL_KILL_MONSTER_TYPE, from data/json/monsters.json and data/json/monsters/
  • "monster_kill_goal" is the number of monsters to kill
  • "start" can either be
    • an optional reference to a hardcoded, C++ function that sets up the mission at its start. “start” is optional, and existing start functions often don’t have anything to do with the mission - for instance, almost all the Tacoma Commune/Refugee Ranch start functions involve building up the ranch, and the mission is still valid even if they didn’t run.
    • an object containing information on a target overmap special and target terrain. See the doc for details.
  • "end" is an optional reference to a hardcoded, C++ function that concludes the mission. See above.
  • "origins" is a list of types of NPCs that can generate the mission.
    • “ORIGIN_SECONDARY” means that it comes from the "followup" of another mission.
    • “ORIGIN_OPENER_NPC” means that the starting NPC can have this mission
    • “ORIGIN_ANY_NPC” means that any random NPC can have this mission
  • "followup" is a mission "id" that the NPC will offer after the player completes this mission successfully.
  • "dialogue" is an object, with each value being a dynamic line that the NPC says in response to the player asking about the mission. These are normal dynamic lines, as described above, and can use dynamic line filters and snippets
    • "describe" is what the NPC says to indicate they have a mission
    • "offer" is what the NPC says to further describe the mission, specify what the player needs to do, and indicate how the NPC will reward the player
    • "advice" is what the NPC will say if the player asks for advice on the quest
    • the other values have fairly self-explanatory names

Any NPC that has missions needs to either have their "chat" talk_topic added to the first talk_topic in data/json/npcs/TALK_COMMON_MISSION.json, or have a responses entry like this:

      { "text": "Can I do anything for you?", "topic": "TALK_MISSION_LIST" },

Reaching the TALK_MISSION_LIST talk_topic will cause CDDA to display the data/json/missiondef.json data for the NPC’s current missions. It’s not necessary for you do anything other than make sure that your missions have valid "dialogue" objects.


Adding New Monsters

You can add new monsters in JSON. I’ve never really done it, so I’m mostly going to point you to the documentation at but I’ll throw in a few more notes.

Monster JSON is stored in data/json/monsters/ and data/json/monsters.json.
Monster special attacks are stored in data/json/monsterattacks.json, but a lot of monster special attacks are hardcoded in C++ so I believe that file is really sparse.

Monsters have two sets of item_groups associated with them. First are data/json/monsterdrops/ and data/json/monster_drops.json, which contain the items that monsters such as zombies drop when they die, and are standard item groups defined by data/json/harvest.json contains information on what you get when you butcher a creature. This file is under very active development right at this moment, and I really have no idea how it works and as far as I know it’s not documented yet. You can look through it and try to figure it out.

monsters also have a monstergroups JSON object, which controls what monsters spawn where in a random function. This is partially documented in doc/, so I refer you back to that.

Finally, monsters have factions, which are defined in data/json/monster_factions.json. These objects are described in


Adding new effects

Effects are things like sickness, poison, or drug effects. They’re also generally useful for applying a status condition on a monster or NPC that you go back and check later.

Effects are mostly stored in data/json/effects.json, and described in

Books and comestible (food/drink/medicine) items can have morale modifiers. I’m not sure if there’s a general system for morale modifiers or not.


Adding new vehicle parts

New vehicle parts can be added in JSON. Most interactions between vehicle parts and the rest of the game unfortunately have to be hardcoded, but there’s still a fair bit you can do only in JSON.

Vehicle parts are stored in data/json/vehicle_parts.json and data/json/vehicleparts/ . Please try to put new things in the appropriate file inside of data/json/vehicleparts/ instead of the generic file at data/json/vehicle_parts.json.
Vehicle parts are mostly documented in the general JSON document at

A vehicle part JSON looks like this:

    "type": "vehicle_part",
    "id": "folding_seat",
    "name": "foldable seat",
    "symbol": "#",
    "color": "red",
    "broken_symbol": "*",
    "broken_color": "red",
    "damage_modifier": 10,
    "durability": 20,
    "description": "A crude seat, too uncomfortable to sleep in.",
    "item": "sheet",
    "folded_volume": 10,
    "location": "anywhere",
    "requirements": {
      "install": { "time": 20000, "skills": [ [ "mechanics", 2 ] ], "qualities": [ { "id": "WRENCH", "level": 2 } ] },
      "repair": { "skills": [ [ "mechanics", 2 ] ], "time": 2000, "using": [ [ "welding_standard", 5 ] ] },
      "removal": { "skills": [ [ "mechanics", 2 ] ], "qualities": [ { "id": "WRENCH", "level": 2 } ] }
    "flags": [ "SEAT", "BOARDABLE", "FOLDABLE" ],
    "breaks_into": [ { "item": "rag", "count": [ 1, 6 ] } ]

Some key bits:

  • "type" must be “vehicle_part”
  • "id" must be unique among all vehicle parts, but a vehicle_part and an item can share the same "id".
  • "item" is the part that is required to install the vehicle_part. Vehicle parts inherit their weight and storage capacity from their item.
  • "flags" are special keywords that tell the vehicle code how to interact with an item. They are generally documented in
  • "location" controls where the vehicle part can be installed. No vehicle can have two items in the same location of the same tile, unless the location is “ANYWHERE”. Valid locations include:
    • “under” - wheels and things under the chassis
    • “structure” - the frame of the vehicle
    • “center” - on top of the fame, used for major items like seats, welding rigs, windshields, and aisles
    • “engine_block”, “fuel_source” - beneath the center item, used for engines and fuel storage respectively
    • “on_ceiling” - hanging from the vehicle’s roof
    • “on_roof” - on the vehicle’s roof, used for turrets and solar panels
    • “armor” - on the vehicle’s outer frame, protecting other components

Spawning vehicle parts

vehicle_parts only exist while they’re on a vehicle. If you want to a add a vehicle_part to the game and have it spawn, you need to either add it to a vehicle that spawns, or add the vehicle_part’s "item" to an item_group.

Engines and fuel

You can add entirely new engines that consume arbitrary solid or liquid fuels. If you want to add a super-engine that consumes water, you can do that.

Fuels are items, and have JSON that looks like this:

    "id": "chem_ethanol",
    "type": "AMMO",
    "name": "ethanol",
    "name_plural": "ethanol",
    "description": "Extremely pure alcohol suitable for use as a component in chemical reactions.  You could also water it down and drink it, or use it as fuel in alcohol-burning stoves.",
    "weight": 1,
    "volume": "200ml",
    "count": 250,
    "stack_size": 200,
    "category": "chems",
    "phase": "liquid",
    "symbol": "~",
    "color": "white",
    "ammo_type": "conc_alcohol",
    "fuel": {
      "energy": 15.6,
      "explosion_data": { "chance_hot": 5, "chance_cold": 10, "factor": 0.2, "fiery": true, "size_factor": 0.1 }

The important bit here is the "fuel" object at the end, and the really important bit is the "energy" value, which is the energy in MJ/L that the fuel provides. For real world fuels, you can look that number up on wikipedia; for imaginary fuels, just know that gasoline has an energy around 35.

Engines look (more or less, the in game engines use a lot of copy-from to simplify) like this:

    "id": "engine_steam_makeshift",
    "type": "vehicle_part",
    "location": "engine_block",
    "symbol": "*",
    "color": "light_red",
    "broken_color": "red",
    "damage_modifier": 80,
    "item": "steam_watts_small",
    "difficulty": 4,
    "durability": 200,
    "fuel_type": "coal_lump",
    "fuel_options": [ "coal_lump", "charcoal" ],
    "cold_affects_start": true,
    "backfire_threshold": 0.25,
    "backfire_freq": 20,
    "noise_factor": 15,
    "damaged_power_factor": 0.25,
    "m2c": 65,
    "epower": 0,
    "power": 55950,
    "energy_consumption": 150000,
    "description": "A closed cycle, external combustion steam engine.  Burns coal or charcoal from a bunker in the vehicle to produce steam."

relevant bits:

  • "flags" must include “ENGINE”, and if you can power an alternator off this engine, “E_ALTERNATOR”.
  • "m2c" is the ratio of the engine’s safe power to the engine’s maximum power - the higher this value, the faster the vehicle’s safe velocity
  • "epower" is how much electrical power in watts it takes to operate the engine. This represents spark plugs in most combustion engines. It should be a negative value, because a positive value means the engine generates electrical power independent of an alternator.
  • "power" is how much motive power in watts the engine produces at maximum output. 1 HP = 746 watts, so this is an 80 HP engine.
  • "energy_consumption" is how much fuel the engine consumes at maximum power, again measured in watts. Each turn an engine is operating, it consumes energy_consumption * 1 second * strain joules of energy, where strain is current acceleration / maximum acceleration (plus some idle consumption to power any alternators). Every liter of fuel provides its "energy" * 1,000,000 joules of energy, so energy_consumption * strain / 1000 / energy is the number of liquid fuel charges consumed each turn.
    Energy_consumption should be a number that is larger than power, because that’s how real life physics works.
  • "fuel_type" and "fuel_opts" - the "id" of the engine’s preferred fuel type, and a list of "id"s of any alternate fuel types. So this steam engine prefers coal but can burn charcoal.