gale.quest module

This file contains a generic, customizable-per-game quest system built on top of gale.sequence: Objective (one trackable goal, completed by progress events, a duration, an input, or a custom condition – pick whichever combination fits), Stage (a StepGroup of Objectives, one phase of a quest), Quest (a Sequence of Stages), and QuestLog (tracks every quest a game has registered, starts/advances them, and broadcasts progress events to whichever are active).

None of this hardcodes what an objective actually means: a game defines its own objective keys (“wolves_killed”, “herbs_collected”, …) and reports progress by calling QuestLog.notify(key, amount) from wherever that event actually happens (an enemy’s on_death, a pickup’s on_collected, …) – exactly the “coordinate through shared state, not direct references” shape gale.ai.blackboard already names a quest system as an example user of, and the two compose naturally (a Blackboard observer can call notify() to bridge the two). Objectives that don’t fit a simple progress counter (checking an inventory, a Blackboard flag, …) are just a matter of subclassing Objective and overriding is_complete.

See docs/examples/quest.rst for a walkthrough.

Author: Alejandro Mujica (aledrums@gmail.com)

class gale.quest.Objective(key=None, description='', target=1, **kwargs)[source]

Bases: Step

One trackable goal within a quest Stage. By default it completes once enough matching progress events have been reported (see notify), but it’s a Step underneath, so duration/advance_on_input work here too (an objective that’s just “wait a moment” or “press a key to confirm” needs no progress tracking at all), and subclassing to override is_complete covers anything else.

Usage example:

Objective(“wolves_killed”, “Defeat 3 wolves in the forest”, target=3)

Parameters:
  • key (str | None)

  • description (str)

  • target (int)

  • kwargs (Any)

notify(key, amount)[source]
Parameters:
  • key (str) – The progress-event name being reported.

  • amount (int) – How much progress to add if key matches this objective’s own key.

Return type:

None

is_complete()[source]
Returns:

Whether this step is done and the Sequence should move to the next one. The default implementation is True once duration has elapsed or advance_on_input has been pressed, and False otherwise – override (calling super() too, if duration/advance_on_input should still apply) to add a custom condition.

Return type:

bool

class gale.quest.Stage(steps, require_all=True, **kwargs)[source]

Bases: StepGroup

One phase of a Quest: a group of Objectives (or nested Stages) tracked together, completed once all of them are – or any one, with require_all=False (e.g. “reach the gate OR find the secret passage”).

Parameters:
  • steps (List[Step])

  • require_all (bool)

  • kwargs (Any)

notify(key, amount)[source]
Parameters:
  • key (str) – The progress-event name being reported.

  • amount (int) – How much progress to report to every Objective (or nested Stage) in this stage.

Return type:

None

class gale.quest.Quest(quest_id, title, stages, on_completed=None)[source]

Bases: Sequence

A questline: a Sequence of Stages, tracked as a whole under a quest_id/title a game’s quest log UI can show. Not meant to be driven directly most of the time – see QuestLog, which manages every quest a game has and routes notify()/update()/on_input() to whichever are active.

Usage example:

Quest(

“defeat_the_wolves”, “Wolf Trouble”, [Stage([Objective(“wolves_killed”, “Defeat 3 wolves”, target=3)])],

)

Parameters:
  • quest_id (str)

  • title (str)

  • stages (List[Stage])

  • on_completed (Callable[[], None] | None)

notify(key, amount)[source]
Parameters:
  • key (str) – The progress-event name being reported.

  • amount (int) – How much progress to report to the current stage.

Return type:

None

property current_stage: Stage | None

The stage currently in progress, or None once the quest is finished.

Type:

returns

class gale.quest.QuestLog[source]

Bases: object

Tracks every quest a game has registered: which are active, completed, or not yet started, and broadcasts progress events (see notify) to whichever are currently active. A game usually keeps one QuestLog for the whole session/save file.

Usage example:

log = QuestLog() log.register(Quest(“defeat_the_wolves”, “Wolf Trouble”, […])) log.start(“defeat_the_wolves”)

# Wherever a wolf dies: log.notify(“wolves_killed”, 1)

# Every frame (only active quests actually do anything): log.update(dt)

register(quest)[source]
Parameters:

quest (Quest) – The quest to make available to start() later.

Return type:

None

start(quest_id)[source]

Activates a registered quest. Does nothing if it’s already active or completed.

Parameters:

quest_id (str) – A previously registered quest to activate.

Raises:

KeyError – If quest_id was never registered.

Return type:

None

get(quest_id)[source]
Parameters:

quest_id (str) – A previously registered quest.

Returns:

That Quest, whatever its current status.

Raises:

KeyError – If quest_id was never registered.

Return type:

Quest

is_active(quest_id)[source]
Parameters:

quest_id (str) – A previously registered quest.

Returns:

Whether it’s currently in progress.

Return type:

bool

is_completed(quest_id)[source]
Parameters:

quest_id (str) – A previously registered quest.

Returns:

Whether it has already finished.

Return type:

bool

active_quests()[source]
Returns:

Every currently active quest, in the order they were started.

Return type:

List[Quest]

notify(key, amount=1)[source]

Reports progress on an event to every currently active quest.

Parameters:
  • key (str) – The progress-event name being reported (e.g. “wolves_killed”).

  • amount (int) – How much progress to add. The default value is 1.

Return type:

None

update(dt)[source]

Updates every active quest, moving any that just finished their last stage into the completed list.

Parameters:

dt (float) – Time elapsed (in seconds) since the last update.

Return type:

None

on_input(input_id, input_data)[source]

Forwards input to every currently active quest (for objectives using advance_on_input).

Parameters:
  • input_id (str) – The string that describes the input.

  • input_data (InputData) – Data associated to the input type.

Return type:

None