Resources & Declarations¶
Global Variables¶
Level Memory¶
Level memory is defined with the @level_memory class decorator:
from sonolus.script.globals import level_memory
@level_memory
class LevelMemory:
value: int
Alternatively, it may be called as a function as well by passing the type as an argument:
from sonolus.script.globals import level_memory
from sonolus.script.vec import Vec2
level_memory_value = level_memory(Vec2)
Level memory may be modified in sequential callbacks:
preprocessupdate_sequentialtouch
and may be read in any callback.
Level Data¶
Level data is defined with the @level_data class decorator:
from sonolus.script.globals import level_data
@level_data
class LevelData:
value: int
Alternatively, it may be called as a function as well by passing the type as an argument:
from sonolus.script.globals import level_data
from sonolus.script.vec import Vec2
level_data_value = level_data(Vec2)
Level data may only be modified in the preprocess callback and may be read in any callback.
Archetype Variables¶
Imported¶
Imported fields are declared with imported():
from sonolus.script.archetype import PlayArchetype, imported
class MyArchetype(PlayArchetype):
field: int = imported()
field_with_explicit_name: int = imported(name="field_name")
Imported fields may be loaded from the level data. In watch mode, data may also be loaded from a corresponding exported field in play mode.
Imported fields may only be updated in the preprocess callback, and are read-only in other callbacks.
Exported¶
Exported fields are declared with exported():
from sonolus.script.archetype import PlayArchetype, exported
class MyArchetype(PlayArchetype):
field: int = exported()
field_with_explicit_name: int = exported(name="#FIELD")
This is only usable in play mode to export data to be loaded in watch mode. Exported fields are write-only.
Entity Data¶
Entity data fields are declared with entity_data():
from sonolus.script.archetype import PlayArchetype, entity_data
class MyArchetype(PlayArchetype):
field: int = entity_data()
Entity data is accessible from other entities, but may only be updated in the preprocess callback and is read-only in other callbacks.
It functions like imported() and shares the same underlying storage, except that it is not loaded from a level.
Entity Memory¶
Entity memory fields are declared with entity_memory():
from sonolus.script.archetype import PlayArchetype, entity_memory
class MyArchetype(PlayArchetype):
field: int = entity_memory()
Entity memory is private to the entity and is not accessible from other entities. It may be read or updated in any callback associated with the entity.
Entity memory fields may also be set when an entity is spawned using the spawn() method.
Shared Memory¶
Shared memory fields are declared with shared_memory():
from sonolus.script.archetype import PlayArchetype, shared_memory
class MyArchetype(PlayArchetype):
field: int = shared_memory()
Shared memory is accessible from other entities.
Shared memory may be read in any callback, but may only be updated by sequential callbacks (preprocess, update_sequential, and touch).
Streams¶
Streams are defined with the @streams decorator:
from sonolus.script.stream import streams, Stream, StreamGroup
from sonolus.script.num import Num
from sonolus.script.vec import Vec2
@streams
class Streams:
stream_1: Stream[Num] # A stream of Num values
stream_2: Stream[Vec2] # A stream of Vec2 values
group_1: StreamGroup[Num, 10] # A group of 10 Num streams
group_2: StreamGroup[Vec2, 5] # A group of 5 Vec2 streams
data_field_1: Num # A data field of type Num
data_field_2: Vec2 # A data field of type Vec2
Streams and stream groups are declared by annotating class attributes with Stream or StreamGroup.
Other types are also supported in the form of data fields. They may be used to store additional data to export from Play to Watch mode.
In either case, data is write-only in Play mode and read-only in Watch mode.
This should only be used once in most projects, as multiple decorated classes will overlap with each other and interfere when both are used at the same time.
For backwards compatibility, new streams and stream groups should be added to the end of existing ones, and lengths and element types of existing streams and stream groups should not be changed. Otherwise, old replays may not work on new versions of the engine.
Skins¶
Skins are defined with the @skin decorator:
from sonolus.script.sprite import skin, StandardSprite, sprite, Sprite, RenderMode
@skin
class Skin:
render_mode: RenderMode = RenderMode.DEFAULT
note: StandardSprite.NOTE_HEAD_RED
other: Sprite = sprite("other")
Standard sprites are defined by annotating the field with the corresponding value from StandardSprite.
Custom sprites are defined by annotating the field with Sprite and calling sprite with the sprite name.
To set the render mode for the skin, set the render_mode field to the desired value from RenderMode.
Sound Effects¶
Sound effects are defined with the @effects decorator:
from sonolus.script.effect import effects, StandardEffect, Effect, effect
@effects
class Effects:
tap_perfect: StandardEffect.PERFECT
other: Effect = effect("other")
Standard sound effects are defined by annotating the field with the corresponding value from StandardEffect.
Custom sound effects are defined by annotating the field with Effect and calling effect with the effect name.
Particles¶
Particles are defined with the @particles decorator:
from sonolus.script.particle import particles, StandardParticle, Particle, particle
@particles
class Particles:
tap: StandardParticle.NOTE_CIRCULAR_TAP_RED
other: Particle = particle("other")
Standard particles are defined by annotating the field with the corresponding value from StandardParticle.
Custom particles are defined by annotating the field with Particle and calling particle with the particle name.
Buckets¶
Buckets are defined with the @buckets decorator:
from sonolus.script.bucket import buckets, bucket_sprite, bucket, Bucket
from sonolus.script.text import StandardText
from my_engine.common.skin import Skin
@buckets
class Buckets:
note: Bucket = bucket(
sprites=[
bucket_sprite(
sprite=Skin.note,
x=0,
y=0,
w=2,
h=2,
)
],
unit=StandardText.MILLISECOND_UNIT,
)
Buckets are defined by annotating the field with Bucket and calling bucket with the bucket name.
Tutorial Instructions¶
Tutorial instructions are defined with the @instructions decorator:
from sonolus.script.instruction import instructions, StandardInstruction, Instruction, instruction
@instructions
class Instructions:
tap: StandardInstruction.TAP
other: Instruction = instruction("other")
Standard instructions are defined by annotating the field with the corresponding value from StandardInstruction.
Custom instructions are defined by annotating the field with Instruction and calling instruction with the instruction name.
Tutorial Instruction Icons¶
Tutorial instruction icons are defined with the @instruction_icons decorator:
from sonolus.script.instruction import instruction_icons, StandardInstructionIcon, InstructionIcon, instruction_icon
@instruction_icons
class InstructionIcons:
hand: StandardInstructionIcon.HAND
other: InstructionIcon = instruction_icon("other")
Standard instruction icons are defined by annotating the field with the corresponding value from StandardInstructionIcon.
Custom instruction icons are defined by annotating the field with InstructionIcon and calling instruction_icon with the icon name.
Options¶
Engine options are defined with the @options decorator:
from sonolus.script.options import options, select_option, slider_option, toggle_option
@options
class Options:
slider_option: float = slider_option(
name="Slider Option",
standard=True,
advanced=False,
default=0.5,
min=0,
max=1,
step=0.1,
unit="unit",
scope="scope",
)
toggle_option: bool = toggle_option(
name="Toggle Option",
standard=True,
advanced=False,
default=True,
scope="scope",
)
select_option: int = select_option(
name="Select Option",
standard=True,
advanced=False,
default="value",
values=["value"],
scope="scope",
)
There are three types of options available:
slider_option: A slider control for numeric valuestoggle_option: A toggle switch for boolean valuesselect_option: A dropdown menu for selecting from predefined values
UI¶
Ui configuration is defined with the UiConfig class:
from sonolus.script.ui import (
EaseType,
UiAnimation,
UiAnimationTween,
UiConfig,
UiJudgmentErrorPlacement,
UiJudgmentErrorStyle,
UiMetric,
UiVisibility,
)
ui_config = UiConfig(
scope="my_engine",
primary_metric=UiMetric.ARCADE,
secondary_metric=UiMetric.LIFE,
menu_visibility=UiVisibility(
scale=1.0,
alpha=1.0,
),
judgment_visibility=UiVisibility(
scale=1.0,
alpha=1.0,
),
combo_visibility=UiVisibility(
scale=1.0,
alpha=1.0,
),
primary_metric_visibility=UiVisibility(
scale=1.0,
alpha=1.0,
),
secondary_metric_visibility=UiVisibility(
scale=1.0,
alpha=1.0,
),
progress_visibility=UiVisibility(
scale=1.0,
alpha=1.0,
),
tutorial_navigation_visibility=UiVisibility(
scale=1.0,
alpha=1.0,
),
tutorial_instruction_visibility=UiVisibility(
scale=1.0,
alpha=1.0,
),
judgment_animation=UiAnimation(
scale=UiAnimationTween(
start=1.0,
end=1.0,
duration=0.0,
ease=EaseType.NONE,
),
alpha=UiAnimationTween(
start=1.0,
end=1.0,
duration=0.0,
ease=EaseType.NONE,
),
),
combo_animation=UiAnimation(
scale=UiAnimationTween(
start=1.2,
end=1.0,
duration=0.2,
ease=EaseType.IN_CUBIC,
),
alpha=UiAnimationTween(
start=1.0,
end=1.0,
duration=0.0,
ease=EaseType.NONE,
),
),
judgment_error_style=UiJudgmentErrorStyle.LATE,
judgment_error_placement=UiJudgmentErrorPlacement.TOP,
judgment_error_min=0.0,
)