Skip to content

The quest system

Track mission objectives and quest states attached to any agent or shared globally.

Overview

Quests are data records stored on an agent's inventory under the key __quests__. Each quest has a unique string ID (supports /-separated nesting like "main/patrol"), a display name, a description, and a QuestState. When a quest changes state a signal is emitted (quest_activated or quest_completed) so other parts of the mission can react.

Quests can be attached to a specific player ship, a specific client console, or the shared game agent (Agent.SHARED_ID) for mission-wide tracking. quest_flatten_list() collects from all three sources and returns a flat list ready for display in a gui_property_list_box.

Quest states

State Value Meaning
QuestState.IDLE 0 Not yet started
QuestState.ACTIVE 1 In progress
QuestState.SECRET 2 Hidden from player
QuestState.POSTING 3 Job board posting
QuestState.FAILED 98 Failed
QuestState.COMPLETE 99 Completed

Quick example

== setup ==
    quest_add(ship_id, "patrol", "Patrol Sector 7", "Keep the peace in sector 7.")
    quest_set_key(ship_id, "patrol", "state", QuestState.ACTIVE)

== on_patrol_done ==
    quest_complete(ship_id, "patrol")
    quest_set_key(ship_id, "patrol", "state", QuestState.COMPLETE)
    ->END
from sbs_utils.procedural.quest import quest_add, quest_set_key, quest_complete, QuestState

quest_add(ship_id, "patrol", "Patrol Sector 7", "Keep the peace in sector 7.")
quest_set_key(ship_id, "patrol", "state", QuestState.ACTIVE)
# ... later ...
quest_complete(ship_id, "patrol")
quest_set_key(ship_id, "patrol", "state", QuestState.COMPLETE)

Displaying quests

items = quest_flatten_list()
gui_property_list_box(items, style="area:0,0,100,100;")

Loading quests from YAML

yaml_text = """
patrol:
  display_text: Patrol Sector 7
  description: Keep the peace.
  state: ACTIVE
rescue:
  display_text: Rescue the crew
  description: Find the survivors.
"""
quest_add_yaml(ship_id, yaml_text)

API

Quests modules

Quest are a data model for tracking various quests Quests are attached to an Agent. The tracking of quests are done by outside logic

When a quest is activated or completed a signal is sent

document_flatten(doc_obj, header=None, indent=0, data=None)

Flatten a nested quest/document tree into an ordered display list.

Recursively walks the tree and returns gui_list_box_header items sorted active → idle → complete → failed at each level. Used internally by quest_flatten_list.

Parameters:

Name Type Description Default
doc_obj MastDataObject | dict | None

The node to flatten.

required
header str

Display label for this node. Defaults to None.

None
indent int

Current nesting depth for visual indentation. Defaults to 0.

0
data optional

Data object attached to this node. Defaults to None.

None

Returns:

Name Type Description
list

Flat ordered list of gui_list_box_header items.

document_get_amd_file(file_path, root_display_text='', strip_comments=True, content=None)

Parse an AMD markdown file into a nested quest/document structure.

AMD files use # [Display Name](key) headings to define hierarchical sections. The heading level controls depth (# = level 1, ## = level 2, etc.). Lines between headings are accumulated as the section's description. Lines starting with // are stripped when strip_comments is True. Query-string parameters in the key URI (key?param=value&…) are parsed as extra attributes on the section.

Returns a dict with keys "key", "display_text", "description", and "children" (list of the same structure). On parse error the exception message is returned as the root "display_text".

Parameters:

Name Type Description Default
file_path str | None

Path to the .amd file to read. Ignored if content is provided.

required
root_display_text str

Label for the root node. Defaults to "".

''
strip_comments bool

Skip // lines. Defaults to True.

True
content str | None

Raw AMD text to parse instead of reading file_path. Defaults to None.

None

Returns:

Name Type Description
dict

Nested document tree rooted at "__root__".

Example

doc = document_get_amd_file("consoles/quest.amd", "Quests") items = document_flatten(doc)

quest_activate(agents, quest_id)

Emit a quest_activated signal for one or more agents.

Fires signal_emit("quest_activated", ...) for each agent. To also update the stored state, call quest_set_key(agent, quest_id, "state", QuestState.ACTIVE) or handle the signal in a //signal/quest_activated route that sets the state.

Parameters:

Name Type Description Default
agents

Agent ID, object, or list/set of either.

required
quest_id str

Quest to activate.

required
Example

quest_activate(SHIP_ID, "patrol") quest_set_key(SHIP_ID, "patrol", "state", QuestState.ACTIVE)

quest_add(agents, quest_id, display_text, description, state=QuestState.IDLE, data=None)

Add a quest to one or more agents.

Creates a new quest entry in each agent's quest tree. If the agent has no quest tree yet, one is initialised automatically. The quest_id may use / separators for nested quests (e.g. "main/rescue"), but all parent levels must already exist.

Parameters:

Name Type Description Default
agents

Agent ID, object, or list/set of either.

required
quest_id str

Unique key for this quest, e.g. "patrol" or "main/patrol".

required
display_text str

Short label shown to the player.

required
description str

Longer description text.

required
state QuestState

Initial state. Defaults to QuestState.IDLE.

IDLE
data object

Arbitrary data attached to the quest and accessible via quest_get_data. Defaults to None.

None
Example

quest_add(SHIP_ID, "patrol", "Patrol Sector 7", "Keep the peace in sector 7.") quest_add(Agent.SHARED_ID, "rescue", "Rescue the crew", "Find the survivors.", state=QuestState.ACTIVE)

quest_add_object(agents, obj, quest_id=None)

Add a quest from a dictionary object to one or more agents.

Reads display_text, description, state, and data from obj. The state value may be a QuestState enum or a string name (e.g. "ACTIVE"); unknown strings default to QuestState.IDLE. Nested children are recursively added with /-separated IDs.

Parameters:

Name Type Description Default
agents

Agent ID, object, or list/set of either.

required
obj dict

Quest definition dict (typically from parsed YAML).

required
quest_id str

Override key. If None, uses obj["id"].

None
Example

quest_add_object(SHIP_ID, { "display_text": "Patrol", "description": "Patrol sector 7.", "state": "ACTIVE", }, "patrol")

quest_add_yaml(agents, yaml_text)

Parse a YAML string and add all quests defined in it to one or more agents.

The YAML should be a mapping of quest IDs to quest objects. Each quest object supports the same keys as quest_add_object (display_text, description, state, data, and nested children).

Parameters:

Name Type Description Default
agents

Agent ID, object, or list/set of either.

required
yaml_text str

YAML-formatted quest definitions.

required
Example

quest_add_yaml(SHIP_ID, ~~ patrol: display_text: "Patrol Sector 7" description: "Keep the peace." state: ACTIVE ~~)

quest_agent_quests(agent_id)

Return the raw quest tree stored on an agent, or None if none exist yet.

The tree is a MastDataObject with a children dict keyed by quest ID. Most scripts should prefer quest_get over accessing the tree directly.

Parameters:

Name Type Description Default
agent_id

Agent ID, object, or Agent.SHARED_ID for global quests.

required

Returns:

Type Description

MastDataObject | None: The root quest container, or None.

Example

tree = quest_agent_quests(SHIP_ID) if tree is not None: ~~ print(tree.get("children").keys()) ~~

quest_complete(agents, quest_id)

Emit a quest_completed signal for one or more agents.

Fires signal_emit("quest_completed", ...) for each agent. To also update the stored state, call quest_set_key(agent, quest_id, "state", QuestState.COMPLETE) or handle the signal in a //signal/quest_completed route that sets the state.

Parameters:

Name Type Description Default
agents

Agent ID, object, or list/set of either.

required
quest_id str

Quest to complete.

required
Example

quest_complete(SHIP_ID, "patrol") quest_set_key(SHIP_ID, "patrol", "state", QuestState.COMPLETE)

quest_console_enable(console, enable=True)

Mark one or more console types as quest-panel-enabled.

Controls which console types display the quest panel. Multiple console names can be passed as a comma-separated string. Names are normalised to lowercase before storage.

Parameters:

Name Type Description Default
console str

Console name(s) to update, e.g. "helm" or "helm,comms,science".

required
enable bool

True to enable, False to disable. Defaults to True.

True
Example

quest_console_enable("helm,comms") quest_console_enable("engineering", False)

quest_flatten_list()

Build a flat display list of all quests for the current client.

Collects quests from three sources — shared game quests (Agent.SHARED), client quests, and the client's assigned ship quests — and flattens each tree into a sorted list of gui_list_box_header items ready for display in a listbox.

Returns:

Name Type Description
list

Flat list of listbox header objects, ordered active → idle → complete → failed within each source group.

Example

items = quest_flatten_list() gui_property_list_box(items, style="area:0,0,100,100;")

quest_folder(agent_id, quest_id)

Return the parent container and child key for a quest path.

Navigates the quest tree along the /-separated components of quest_id, creating the root tree if it does not yet exist. Used internally by most other quest functions.

Parameters:

Name Type Description Default
agent_id

Agent ID or object that owns the quest tree.

required
quest_id str

Quest path, e.g. "main/patrol".

required

Returns:

Type Description

tuple[MastDataObject | None, str | None]: The parent container and the final path component (the child key), or (None, None) if the agent does not exist.

quest_get(agent, quest_id)

Return a quest object by ID, or None if it does not exist.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier, e.g. "patrol" or "main/patrol".

required

Returns:

Type Description

MastDataObject | None: The quest data object, or None.

Example

q = quest_get(SHIP_ID, "patrol") if q is not None: "Patrol state: {q.get('state')}"

quest_get_data(agent, quest_id)

Return the data value attached to a quest.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier.

required

Returns:

Type Description

object | None: The data value passed to quest_add, or None.

Example

d = quest_get_data(SHIP_ID, "patrol")

quest_get_description(agent, quest_id)

Return the description of a quest.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier.

required

Returns:

Type Description

str | None: The description string, or None if the quest does not exist.

Example

desc = quest_get_description(SHIP_ID, "patrol") "Objective: {desc}"

quest_get_display_name(agent, quest_id)

Return the display name of a quest.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier.

required

Returns:

Type Description

str | None: The display name, or None if the quest does not exist.

Example

name = quest_get_display_name(SHIP_ID, "patrol") "Mission: {name}"

quest_get_key(agent, quest_id, key, defa=None)

Return an arbitrary attribute from a quest object.

Reads any key stored on the quest's MastDataObject. Built-in keys are "state", "display_text", "description", and "data". Custom keys can be set with quest_set_key.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier.

required
key str

Attribute name to read.

required
defa optional

Value returned when the quest is missing or the key has not been set. Defaults to None.

None

Returns:

Name Type Description
object

The stored value, or defa.

Example

difficulty = quest_get_key(SHIP_ID, "patrol", "difficulty", "normal")

quest_get_parent(agent, quest_id)

Return the parent container of a quest without the child itself.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier whose parent to retrieve.

required

Returns:

Type Description

MastDataObject | None: The parent container, or None.

quest_get_state(agent, quest_id)

Return the current state of a quest.

Returns QuestState.IDLE both when the quest does not exist and when its state has never been explicitly set.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier.

required

Returns:

Name Type Description
QuestState

Current state value.

Example

if quest_get_state(SHIP_ID, "patrol") == QuestState.COMPLETE: "Patrol complete!"

quest_is_console_enabled(console)

Return whether a console type has quest-panel display enabled.

Parameters:

Name Type Description Default
console str

Console name to check, e.g. "helm".

required

Returns:

Name Type Description
bool

True if enabled via quest_console_enable.

Example

if quest_is_console_enabled("helm"): ~~ show_quest_panel() ~~

quest_remove(agent, quest_id)

Remove a quest from an agent and return it.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier to remove.

required

Returns:

Type Description

MastDataObject | None: The removed quest, or None if not found.

Example

removed = quest_remove(SHIP_ID, "patrol")

quest_set_key(agent, quest_id, key, value)

Set an arbitrary attribute on a quest object.

Use this to write any key — including "state" when you want to update it directly. quest_activate and quest_complete only emit signals; call this to actually store the new state.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier.

required
key str

Attribute name to write.

required
value

Value to store.

required
Example

quest_set_key(SHIP_ID, "patrol", "state", QuestState.ACTIVE) quest_set_key(SHIP_ID, "patrol", "difficulty", "hard")

quest_set_state(agent, quest_id, state)

Set the state of a quest and emit the appropriate signal.

Emits quest_activated when state is QuestState.ACTIVE and quest_completed when state is QuestState.COMPLETE. Does nothing if the quest is already in the requested state.

Parameters:

Name Type Description Default
agent

Agent ID or object that owns the quest.

required
quest_id str

Quest identifier.

required
state QuestState

The new state to assign.

required

quest_transfer(from_agent_id, to_agent_id, quest_id)

Move a quest from one agent to another.

Removes the quest from from_agent_id and adds it to to_agent_id under the same quest_id. Returns False if the quest does not exist on the source agent.

Parameters:

Name Type Description Default
from_agent_id

Source agent ID or object.

required
to_agent_id

Destination agent ID or object.

required
quest_id str

The quest to transfer, e.g. "patrol/sector7".

required

Returns:

Name Type Description
bool

True if the quest was found and transferred, False otherwise.

Example

quest_transfer(SHIP_ID, Agent.SHARED_ID, "rescue_mission")