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 |
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 |
required |
root_display_text
|
str
|
Label for the root node.
Defaults to |
''
|
strip_comments
|
bool
|
Skip |
True
|
content
|
str | None
|
Raw AMD text to parse instead of
reading |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
Nested document tree rooted at |
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. |
required |
display_text
|
str
|
Short label shown to the player. |
required |
description
|
str
|
Longer description text. |
required |
state
|
QuestState
|
Initial state. Defaults to
|
IDLE
|
data
|
object
|
Arbitrary data attached to the quest and
accessible via |
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
|
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 |
required |
Returns:
| Type | Description |
|---|---|
|
MastDataObject | None: The root quest container, or |
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. |
required |
enable
|
bool
|
|
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. |
required |
Returns:
| Type | Description |
|---|---|
|
tuple[MastDataObject | None, str | None]: The parent container and the
final path component (the child key), or |
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. |
required |
Returns:
| Type | Description |
|---|---|
|
MastDataObject | None: The quest data object, or |
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 |
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 |
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 |
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
|
Returns:
| Name | Type | Description |
|---|---|---|
object |
The stored value, or |
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 |
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. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
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 |
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. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
|
Example
quest_transfer(SHIP_ID, Agent.SHARED_ID, "rescue_mission")