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 otherinitialize
calls.update_sequential
: Called each frame an entity is active afterinitialize
callbacks are done. Since it's called sequentially, it can update shared state.touch
: Called sequentially each frame afterupdate_sequential
if there's touch input. Has access to touch input data.update_parallel
: Called aftertouch
andupdate_sequential
callbacks are done. Runs in parallel with otherupdate_parallel
calls. Has better performance due to parallel execution, so most logic such as drawing sprites should be done here.terminate
: Called afterupdate_parallel
callbacks are done when an entity is being despawned. Runs in parallel with otherterminate
calls.
If not defined in an archetype, the default behavior of each callback is to do nothing.