Skip to content
Cataclysm: Bright Nights
GitHubDiscord

Creating missions

NPCs can assign missions to the player. There is a fairly regular structure for this:

{
  "id": "MISSION_GET_BLACK_BOX_TRANSCRIPT",
  "type": "mission_definition",
  "name": "Retrieve Black Box Transcript",
  "description": "Decrypt the contents of the black box using a terminal from a nearby lab.",
  "goal": "MGOAL_FIND_ITEM",
  "difficulty": 2,
  "value": 150000,
  "item": "black_box_transcript",
  "start": {
    "effect": { "u_buy_item": "black_box" },
    "assign_mission_target": { "om_terrain": "lab", "reveal_radius": 3 }
  },
  "origins": ["ORIGIN_SECONDARY"],
  "followup": "MISSION_EXPLORE_SARCOPHAGUS",
  "dialogue": {
    "describe": "With the black box in hand, we need to find a lab.",
    "offer": "Thanks to your searching we've got the black box but now we need to have a look'n-side her.  Now, most buildings don't have power anymore but there are a few that might be of use.  Have you ever seen one of those science labs that have popped up in the middle of nowhere?  Them suckers have a glowing terminal out front so I know they have power somewhere inside'em.  If you can get inside and find a computer lab that still works you ought to be able to find out what's in the black box.",
    "accepted": "Fuck ya, America!",
    "rejected": "Do you have any better ideas?",
    "advice": "When I was play'n with the terminal for the one I ran into it kept asking for an ID card.  Finding one would be the first order of business.",
    "inquire": "How 'bout that black box?",
    "success": "America, fuck ya!  I was in the guard a few years back so I'm confident I can make heads-or-tails of these transmissions.",
    "success_lie": "What?!  I out'ta whip you're ass.",
    "failure": "Damn, I maybe we can find an egg-head to crack the terminal."
  }
}

type

Must always be there and must always be “mission_definition”.

id

The mission id is required, but for new missions, it can be arbitrary. Convention is to start it with “MISSION” and to use a fairly descriptive name.

name

The name is also required, and is displayed to the user in the ‘m’issions menu.

description

Not required, but it’s strongly recommended that you summarize all relevant info for the mission. You may refer to mission end effects of the “u_buy_item” type, as long as they do not come at a cost to the player. See the example below:

"id": "MISSION_EXAMPLE_TOKENS",
"type": "mission_definition",
"name": "Murder Money",
"description": "Whack the target in exchange for <reward_item:FMCNote> c-notes and <reward_item:cig> cigarettes.",
"goal": "MGOAL_ASSASSINATE",
"end": {
  "effect": [
    { "u_buy_item": "FMCNote", "count": 999 },
    { "u_buy_item": "cig", "count": 666 } ]
}

This system may be expanded in the future to allow referring to other mission parameters and effects.

goal

Must be included, and must be one of these strings:

goal stringGoal conditions
MGOAL_GO_TOReach a specific overmap tile
MGOAL_GO_TO_TYPEReach any instance of a specified overmap tile type
MGOAL_COMPUTER_TOGGLEActivating the correct terminal will complete the mission
MGOAL_FIND_ITEMFind 1 or more items of a given type
MGOAL_FIND_ITEM_GROUPFind 1 or more items of a given item_group.
MGOAL_FIND_ANY_ITEMFind 1 or more items of a given type, tagged for this mission
MGOAL_FIND_MONSTERFind and retrieve a friendly monster
MGOAL_FIND_NPCFind a specific NPC
MGOAL_TALK_TO_NPCTalk to a specific NPC
MGOAL_RECRUIT_NPCRecruit a specific NPC
MGOAL_RECRUIT_NPC_CLASSRecruit an NPC of a specific class
MGOAL_ASSASSINATEKill a specific NPC
MGOAL_KILL_MONSTERKill a specific hostile monster
MGOAL_KILL_MONSTER_TYPEKill some number of a specific monster type
MGOAL_KILL_MONSTER_SPECKill some number of monsters from a specific species
MGOAL_CONDITIONSatisfy the dynamically created condition and talk to the mission giver

monster_species

For “MGOAL_KILL_MONSTER_SPEC”, sets the target monster species.

monster_type

For “MGOAL_KILL_MONSTER_TYPE”, sets the target monster type.

monster_kill_goal

For “MGOAL_KILL_MONSTER_SPEC” and “MGOAL_KILL_MONSTER_TYPE”, sets the number of monsters above the player’s current kill count that must be killed to complete the mission.

goal_condition

For “MGOAL_CONDITION”, defines the condition that must be satisified for the mission to be considered complete. Conditions are explained in more detail in NPCs.md, and are used here in exactly the same way.

dialogue

This is a dictionary of strings. The NPC says these exact strings in response to the player inquiring about the mission or reporting its completion. All these strings are required, even if they may not be used in the mission.

string IDUsage
describeThe NPC’s overall description of the mission
offerThe specifics of the mission given when the player selects that mission for consideration
acceptedThe NPC’s response if the player accepts the mission
rejectedThe NPC’s response if the player refuses the mission
adviceIf the player asks for advice on how to complete the mission, they hear this
inquireThis is used if the NPC asks the player how the mission is going
successThe NPC’s response to a report that the mission was successful
success_lieThe NPC’s response if they catch the player lying about a mission’s success
failureThe NPC’s response if the player reports a failed mission

start

Optional field. If it is present and a string, it must be name of a function in mission_start:: that takes a mission * and performs the start code for the mission. This allows missions other than the standard mission types to be run. A hardcoded function is currently necessary to set up missions with “MGOAL_COMPUTER_TOGGLE”.

Alternately, if present, it can be an object as described below.

start / end / fail effects

If any of these optional fields are present they can be objects with the following fields contained:

effect

This is an effects array, exactly as defined in NPCs.md, and can use any of the values from effects. In all cases, the NPC involved is the quest giver.

reveal_om_ter

This can be a string or a list of strings, all of which must be overmap terrain ids. A randomly selected overmap terrain tile with that id - or one of the ids from list, randomly selected - will be revealed, and there is a 1 in 3 chance that the road route to the map tile will also be revealed.

assign_mission_target

The assign_mission_target object specifies the criteria for finding (or creating if necessary) a particular overmap terrain and designating it as the mission target. Its parameters allow control over how it is picked and how some effects (such as revealing the surrounding area) are applied afterwards. The om_terrain is the only required field.

IdentifierDescription
om_terrainID of overmap terrain which will be selected as the target. Mandatory.
om_terrain_match_typeMatching rule to use with om_terrain. Defaults to TYPE. Details below.
om_specialID of overmap special containing the overmap terrain.
om_terrain_replaceID of overmap terrain to be found and replaced if om_terrain cannot be found.
reveal_radiusRadius in overmap terrain coordinates to reveal.
must_seeIf true, the om_terrain must have been seen already.
cant_seeIf true, the om_terrain must not have been seen already.
randomIf true, a random matching om_terrain is used. If false, the closest is used.
search_rangeRange in overmap terrain coordinates to look for a matching om_terrain.
min_distanceRange in overmap terrain coordinates. Instances of om_terrain in this range will be ignored.
origin_npcStart the search at the NPC’s, rather than the player’s, current position.
zIf specified, will be used rather than the player or NPC’s z when searching.
offset_x,<br>offset_y,<br>offset_zAfter finding or creating om_terrain, offset the mission target terrain by the offsets in overmap terrain coordinates.

example

{
  "assign_mission_target": {
    "om_terrain": "necropolis_c_44",
    "om_special": "Necropolis",
    "reveal_radius": 1,
    "must_see": false,
    "random": true,
    "search_range": 180,
    "z": -2
  }
}

If the om_terrain is part of an overmap special, it’s essential to specify the om_special value as well—otherwise, the game will not know how to spawn the entire special.

om_terrain_match_type defaults to TYPE if unspecified, and has the following possible values:

  • EXACT - The provided string must completely match the overmap terrain id, including linear direction suffixes for linear terrain types or rotation suffixes for rotated terrain types.

  • TYPE - The provided string must completely match the base type id of the overmap terrain id, which means that suffixes for rotation and linear terrain types are ignored.

  • PREFIX - The provided string must be a complete prefix (with additional parts delimited by an underscore) of the overmap terrain id. For example, “forest” will match “forest” or “forest_thick” but not “forestcabin”.

  • CONTAINS - The provided string must be contained within the overmap terrain id, but may occur at the beginning, end, or middle and does not have any rules about underscore delimiting.

If an om_special must be placed, it will follow the same placement rules as defined in its overmap special definition, respecting allowed terrains, distance from cities, road connections, and so on. Consequently, the more restrictive the rules, the less likely this placement will succeed (as it is competing for space with already-spawned specials).

om_terrain_replace is only relevent if the om_terrain is not part of an overmap special. This value is used if the om_terrain cannot be found, and will be used as an alternative target which will then be replaced with the om_terrain value.

If must_see is set to true, the game will not create the terrain if it can’t be found. It tries to avoid having new terrains magically appear in areas where the player has already been, and this is a consequence.

reveal_radius, min_distance, and search_range are all in overmap terrain coordinates (an overmap is currently 180 x 180 OMT units). The search is centered on the player unless origin_npc is set, in which case it centered on the NPC. Currently, there is rarely a difference between the two, but it is possible to assign missions over a radio. The search gives preference to existing overmaps (and will only spawn new overmaps if the terrain can’t be found on existing overmaps), and only executes on the player’s current z-level. The z attribute can be used to override this and search on a different z-level than the player—this is an absolute value rather than relative.

offset_x, offset_y, and offset_z change the final location of the mission target by their values. This can change the mission target’s overmap terrain type away from om_terrain.

update_mapgen

The update_mapgen object or array provides a way to modify existing overmap tiles (including the ones created by “assign_mission_target”) to add mission specific monsters, NPCs, computers, or items.

As an array, update_mapgen consists of two or more update_mapgen objects.

As an object, update_mapgen contains any valid JSON mapgen objects. The objects are placed on the mission target terrain from “assign_mission_target” or optionally the closest overmap terrain specified by the om_terrain and om_special fields. If “mapgen_update_id” is specified, the “mapge_update” object with the matching “mapgen_update_id” will be executed.

See doc/MAPGEN.md for more details on JSON mapgen and update_mapgen.

An NPC, monster, or computer placed using update_mapgen will be the target of a mission if it has the target boolean set to true in its place object in update_mapgen.

Adding new missions to NPC dialogue

In order to assign missions to NPCs, the first step is to find that NPC’s definition. For unique NPCs this is usually at the top of the npc’s JSON file and looks something like this:

{
  "type": "npc",
  "id": "refugee_beggar2",
  "//": "Schizophrenic beggar in the refugee center.",
  "name_unique": "Dino Dave",
  "gender": "male",
  "name_suffix": "beggar",
  "class": "NC_BEGGAR_2",
  "attitude": 0,
  "mission": 7,
  "chat": "TALK_REFUGEE_BEGGAR_2",
  "faction": "lobby_beggars"
},

Add a new line that defines the NPC’s starting mission, eg:

"mission_offered": "MISSION_BEGGAR_2_BOX_SMALL"

Any NPC that has missions needs to have a dialogue option that leads to TALK_MISSION_LIST, to get the player started on their first mission for the NPC, and either:

  • Add one of their talk_topic IDs to the list of generic mission reponse IDs in the first talk_topic of data/json/npcs/TALK_COMMON_MISSION.json, or
  • Have a similar talk_topic with responses that lead to TALK_MISSION_INQUIRE and TALK_MISSION_LIST_ASSIGNED.

Either of these options will allow the player to do normal mission management dialogue with the NPC.

This is an example of how a custom mission inquiry might appear. This will only appear in the NPC’s dialogue options if the player has already been assigned a mission.

{
    "type": "talk_topic",
    "//": "Generic responses for Old Guard Necropolis NPCs that can have missions",
    "id": [ "TALK_OLD_GUARD_NEC_CPT", "TALK_OLD_GUARD_NEC_COMMO" ],
    "responses": [
      {
        "text": "About the mission...",
        "topic": "TALK_MISSION_INQUIRE",
        "condition": { "and": [ "has_assigned_mission", { "u_is_wearing": "badge_marshal" } ] }
      },
      {
        "text": "About one of those missions...",
        "topic": "TALK_MISSION_LIST_ASSIGNED",
        "condition": { "and": [ "has_many_assigned_missions", { "u_is_wearing": "badge_marshal" } ] }
      }
    ]
},