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 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_ITEM_GROUP | Find 1 or more items of a given item_group. |
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_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 |
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 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:
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. |
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. |
om_terrain_replace | ID of overmap terrain to be found and replaced if om_terrain cannot be found. |
reveal_radius | Radius in overmap terrain coordinates to reveal. |
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 . |
min_distance | Range in overmap terrain coordinates. Instances of om_terrain in this range will be ignored. |
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. |
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.
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" } ] }
}
]
},