Skip to content

05 Blocks and Sharing Immutable Data

This chapter introduces blocks and uses them to share immutable data between archetypes.

Blocks

In the previous chapter, Initialization configured the sprite and particle coordinate system. The other archetypes now need information about that coordinate system to render correctly. For example, Stage needs the screen's left and right edges expressed in the engine coordinate system.

Initialization must share these values with the other archetypes.

Blocks are Sonolus's memory-sharing mechanism. Sonolus.py provides typed interfaces to the blocks an engine commonly uses, so engine code can work with fields instead of low-level block addresses.

Level Data Block

For values derived from the engine coordinate system, we need storage that can be written during initialization and read by every archetype. Level Data is designed for this purpose.

Level Data can only be written during a preprocess callback. It can be read from other callbacks, and its values remain unchanged after preprocessing. This makes it suitable for values that are calculated once and shared for the rest of the level.

Declaring

Stage needs the transformed left and right coordinates of the judgment line, while Note needs the transformed note radius. In guide/lib/layout.py, add the level_data import and declare Config above init_layout:

python
from sonolus.script.globals import level_data


@level_data
class Config:
    judge_line_l: float
    judge_line_r: float
    note_radius: float

The level_data decorator places the fields in Level Data. Use Config directly. Do not instantiate it.

Accessing

We can now access the fields like regular class attributes. In init_layout, add these assignments after calculating h and before creating transform:

python
def init_layout(note_size: float):
    # ...

    Config.judge_line_l = screen().l / h
    Config.judge_line_r = screen().r / h

    Config.note_radius = note_radius / h

    # ...

After preprocessing is complete, Stage and Note can read the stored values from Config in their own callbacks.