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",
    "deadline": [ "16 hours", "math": [ "time(' 16 h') * 2" ] ],
    "difficulty": 2,
    "value": 150000,
    "item": "black_box_transcript",
    "invisible_on_complete": false,
    "start": {
       "effect": { "u_buy_item": "black_box" },
       "assign_mission_target": { "om_terrain": "lab", "reveal_radius": 3 }
    },
    "urgent": false,
    "has_generic_rewards": true,
    "item": "pencil",
    "item_group": "pencil_box_with_pencil",
    "count": 6,
    "required_container": "pencil_box",
    "remove_container": true,
    "empty_container": "can_drink",
    "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 inside 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 yeah, America!",
      "rejected": "Do you have any better ideas?",
      "advice": "When I was playin' 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 yeah!  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 oughta whip your 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.

deadline

How long after being assigned this mission before it will automatically fail (if not already completed). Can be a pair of values, in which case a random value between the two is picked. If only a single value is given, always uses that value.

Supports variable objects and math expressions.

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.

urgent

If true, the NPC giving this mission will refuse to speak on any other topics besides completing this mission while it is active.

goal

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

Goal string Goal conditions
MGOAL_GO_TO Reach a specific overmap tile
MGOAL_GO_TO_TYPE Reach any instance of a specified overmap tile type
MGOAL_COMPUTER_TOGGLE Activating the correct terminal will complete the mission
MGOAL_FIND_ITEM Find 1 or more items of a given type
MGOAL_FIND_ANY_ITEM Find 1 or more items of a given type, tagged for this mission
MGOAL_FIND_MONSTER Find and retrieve a friendly monster
MGOAL_FIND_NPC Find a specific NPC
MGOAL_TALK_TO_NPC Talk to a specific NPC
MGOAL_RECRUIT_NPC Recruit a specific NPC
MGOAL_RECRUIT_NPC_CLASS Recruit an NPC of a specific class
MGOAL_ASSASSINATE Kill a specific NPC
MGOAL_KILL_MONSTER Kill a specific hostile monster
MGOAL_KILL_MONSTERS Kill a number of specific hostile monsters
MGOAL_KILL_MONSTER_TYPE Kill some number of a specific monster type
MGOAL_KILL_MONSTER_SPEC Kill some number of monsters from a specific species
MGOAL_CONDITION Satisfy the dynamically created condition and talk to the mission giver

Missions with goals MGOAL_GO_TO and MGOAL_GO_TO_TYPE behave differently depending on whether the player gets them from an NPC or from another source (e.g. from a starting scenario):

  • When given by an NPC the mission is an escort quest: to complete it the player has to talk to the quest giver while standing at the destination. Note: make sure to set the quest giver to follow the player or the mission will be impossible to complete.
  • Otherwise the mission is simple traversal - to complete it the player only has to reach the destination

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

invisible_on_complete

Optional bool, defaults to false. If true when this mission is finished it won’t show up on the missions completed or missions failed lists.

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 ID Usage
describe The NPC’s overall description of the mission
offer The specifics of the mission given when the player selects that mission for consideration
accepted The NPC’s response if the player accepts the mission
rejected The NPC’s response if the player refuses the mission
advice If the player asks for advice on how to complete the mission, they hear this
inquire This is used if the NPC asks the player how the mission is going
success The NPC’s response to a report that the mission was successful
success_lie The NPC’s response if they catch the player lying about a mission’s success
failure The 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:

origin

This determines how the player can be given this mission. There are a number of different options for this as follows.

String ID Usage
ORIGIN_GAME_START Given when the game starts
ORIGIN_OPENER_NPC NPC comes up to you when the game starts
ORIGIN_ANY_NPC Any NPC
ORIGIN_SECONDARY Given at the end of another mission
ORIGIN_COMPUTER Taken after reading investigation provoking entries in computer terminal

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.

Identifier Description
om_terrain ID of overmap terrain which will be selected as the target. Mandatory. String or or variable object
om_terrain_match_type Matching rule to use with om_terrain. Defaults to TYPE. Details below.
om_special ID of overmap special containing the overmap terrain. String or or variable object
om_terrain_replace ID of overmap terrain to be found and replaced if om_terrain cannot be found. String or or variable object
reveal_radius Radius in overmap terrain coordinates to reveal. Int or or variable object
must_see If true, the om_terrain must have been seen already.
cant_see If true, the om_terrain must not have been seen already.
random If true, a random matching om_terrain is used. If false, the closest is used.
search_range Range in overmap terrain coordinates to look for a matching om_terrain. Int or or variable object
min_distance Range in overmap terrain coordinates. Instances of om_terrain in this range will be ignored. Int or or variable object
origin_npc Start the search at the NPC’s, rather than the player’s, current position.
z If specified, will be used rather than the player or NPC’s z when searching. Int or or variable object
var A variable_object ( see variable_object in doc ), if set this variable’s value will be used.
offset_x,<br>offset_y,<br>offset_z After 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. If a multitile om_special is used it is important to specify the exact om_terrain that you would like the target to appear in.

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

Variable Object

Can be several differnet types of thing. See the NPCS document, section Variable Object for full details.

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 response 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" } ] }
    }
  ]
},