Play¶
Play mode is generally the most important mode of a Sonolus engine, as it defines the interactive gameplay experience.
Configuration¶
Play mode is configured using the PlayMode class:
from sonolus.script.engine import PlayMode
# ... import your archetypes, skin, effects, particles, and buckets
play_mode = PlayMode(
archetypes=[
Stage,
Note,
# etc.
],
skin=Skin,
effects=Effects,
particles=Particles,
buckets=Buckets,
)
Play Archetypes¶
Gameplay logic in play mode is defined via archetypes. Archetypes may correspond to individual notes, or other gameplay elements such as the stage. They may also be dedicated to special purposes such as initializing, input handing, and so forth depending on the needs of an engine.
In play mode, archetypes inherit from the PlayArchetype class:
from sonolus.script.archetype import PlayArchetype
class Note(PlayArchetype):
is_score = True
# All of these methods are optional
def preprocess(self):
...
def spawn_order(self) -> float:
...
def should_spawn(self) -> bool:
...
def initialize(self):
...
def update_sequential(self):
...
def touch(self):
...
def update_parallel(self):
...
def terminate(self):
...
Archetypes that correspond to notes and contribute to scoring should set the is_score attribute to True.
Entities¶
Entities are instances of archetypes. For example an engine may have a Note archetype, and each individual note is
considered an entity.
Callbacks¶
Callbacks determine the behavior of entities in play mode:
preprocess: Called as the level is loadedspawn_order: Called after preprocessing is done to determine which order entities. should be spawned in. Smaller values are spawned first; a common approach is to use the spawn time of the entity.should_spawn: Called to determine whether the entity should be spawned. Called each frame if the previous entity is spawned.initialize: Called when the entity is spawned at the start of the frame. Runs in parallel with otherinitializecalls.update_sequential: Called each frame an entity is active afterinitializecallbacks are done. Since it's called sequentially, it can update shared state.touch: Called sequentially each frame afterupdate_sequentialif there's touch input. Has access to touch input data.update_parallel: Called aftertouchandupdate_sequentialcallbacks are done. Runs in parallel with otherupdate_parallelcalls. Has better performance due to parallel execution, so most logic such as drawing sprites should be done here.terminate: Called afterupdate_parallelcallbacks are done when an entity is being despawned. Runs in parallel with otherterminatecalls.
If not defined in an archetype, the default behavior of each callback is to do nothing.