gale.sequence module
This file contains a small, generic toolkit for anything that plays out as an ordered series of steps, each one active for a while before handing off to the next: Step (one step, complete after a fixed duration, in response to a specific input, or by whatever custom condition a subclass implements), StepGroup (several Steps run side by side, complete once all of them are – or any one of them, with require_all=False), and Sequence (drives a list of Steps one at a time, forwarding update/on_input/render to whichever is currently active).
This is the shared engine behind both gale.quest (a quest’s stages and objectives) and gale.cutscene (a cutscene’s beats): both are, at their core, “do this until it’s done, then do the next thing,” and only differ in what “done” means and what a step actually shows/does on screen.
See docs/examples/sequence.rst for a walkthrough.
Author: Alejandro Mujica (aledrums@gmail.com)
- class gale.sequence.Step(duration=None, advance_on_input=None)[source]
Bases:
objectOne step of a Sequence. A step becomes active when the Sequence reaches it (enter() is called), runs update(dt) every tick while active, and is dropped in favor of the next step once is_complete() returns True.
The two most common ways a step finishes on its own are already built in – after a fixed duration, or as soon as a specific input is pressed – since that’s exactly the choice a cutscene beat, a line of dialogue, or a tutorial prompt usually needs (“show this for 2 seconds, or let the player press a key to skip ahead”). Passing neither leaves is_complete() at its default of “never, on its own”, meaning a subclass is expected to override it with its own condition instead (a quest objective’s progress, a scripted event finishing, …) – call super().is_complete() too if duration/advance_on_input should still be able to force it, the same way gale.state.HierarchicalState expects overrides of enter/update/render to call through to keep its own delegation working.
Usage example:
- class ShowBanner(Step):
# Shown for 2 seconds, or skipped early with the “confirm” input. ShowBanner(“Chapter 1”, font, duration=2.0, advance_on_input=”confirm”)
- Parameters:
duration (float | None)
advance_on_input (str | None)
- enter(*args, **kwargs)[source]
Called once when the Sequence makes this step the active one. Resets the bookkeeping duration/advance_on_input rely on.
- Parameters:
kwargs (Any) – Accepted for subclasses that need extra setup data; unused by the base implementation.
args (Any)
kwargs
- Return type:
None
- update(dt)[source]
Override to do this step’s per-frame work. Called every tick while this step is active, after elapsed has already been advanced by dt.
- Parameters:
dt (float) – Time elapsed (in seconds) since the last update.
- Return type:
None
- render(surface)[source]
Override to draw whatever this step shows while active.
- Parameters:
surface (Surface) – The surface to draw on.
- Return type:
None
- on_input(input_id, input_data)[source]
Reacts to input while this step is active. The default implementation is what makes advance_on_input work – call super().on_input(…) first if you override it and still want that.
- Parameters:
input_id (str) – The string that describes the input.
input_data (InputData) – Data associated to the input type.
- 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.sequence.StepGroup(steps, require_all=True, **kwargs)[source]
Bases:
StepRuns several Steps side by side (e.g. a character walking across the screen while a line of dialogue plays over it, or a quest stage’s several objectives tracked at once), completing once all – or any one, with require_all=False – of them report is_complete(). Also accepts its own duration/advance_on_input (inherited from Step), which forcibly completes the whole group regardless of its children, e.g. a hard timeout.
Usage example:
- StepGroup([
MoveActor(hero, target=(400, 200), duration=1.5), Dialogue(“Hero”, “This way!”, font),
])
- Parameters:
steps (List[Step])
require_all (bool)
kwargs (Any)
- enter(*args, **kwargs)[source]
Called once when the Sequence makes this step the active one. Resets the bookkeeping duration/advance_on_input rely on.
- Parameters:
kwargs (Any) – Accepted for subclasses that need extra setup data; unused by the base implementation.
args (Any)
kwargs
- Return type:
None
- update(dt)[source]
Override to do this step’s per-frame work. Called every tick while this step is active, after elapsed has already been advanced by dt.
- Parameters:
dt (float) – Time elapsed (in seconds) since the last update.
- Return type:
None
- render(surface)[source]
Override to draw whatever this step shows while active.
- Parameters:
surface (Surface) – The surface to draw on.
- Return type:
None
- on_input(input_id, input_data)[source]
Reacts to input while this step is active. The default implementation is what makes advance_on_input work – call super().on_input(…) first if you override it and still want that.
- Parameters:
input_id (str) – The string that describes the input.
input_data (InputData) – Data associated to the input type.
- 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.sequence.Sequence(steps, on_finished=None)[source]
Bases:
objectDrives a list of Steps one at a time: enters the first, keeps ticking/rendering/forwarding input to whichever is active, and moves on to the next one as soon as the active step’s is_complete() turns True, until none are left.
Usage example:
- sequence = Sequence(
[Step(duration=1.0), Step(advance_on_input=”confirm”)], on_finished=lambda: print(“done”),
)
# In the game loop: sequence.update(dt) sequence.render(surface) # And forward input from wherever your game dispatches it: sequence.on_input(input_id, input_data)
- Parameters:
steps (List[Step])
on_finished (Callable[[], None] | None)
- update(dt)[source]
- Parameters:
dt (float) – Time elapsed (in seconds) since the last update.
- Return type:
None