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: object

One 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):
def __init__(self, text, font, **kwargs):

super().__init__(**kwargs) self.text = text self.font = font

def render(self, surface):

render_text(surface, self.text, self.font, 400, 300, “white”, center=True)

# 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

exit()[source]

Called once when the Sequence moves on from this step.

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: Step

Runs 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

exit()[source]

Called once when the Sequence moves on from this step.

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: object

Drives 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

render(surface)[source]
Parameters:

surface (Surface) – The surface to draw on.

Return type:

None

on_input(input_id, input_data)[source]
Parameters:
  • input_id (str) – The string that describes the input.

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

Return type:

None

skip_current()[source]

Force the current step to end right now and move to the next one, regardless of its own is_complete(). Useful for a “skip”/”hold to fast-forward” input on top of whatever a step’s own duration/advance_on_input already allow.

Return type:

None