16 Arcade Score
In this chapter, we will set up arcade score and primary metric UI.
Configure Judgment Multipliers
The level score stores scoring settings shared by every scored archetype. Create guide/lib/note.py and add an init_score helper. A Perfect receives the full base multiplier. Great and Good receive smaller multipliers:
python
from sonolus.script.runtime import level_score
def init_score():
level_score().update(
perfect_multiplier=1,
great_multiplier=0.75,
good_multiplier=0.5,
)Sonolus normalizes the maximum arcade score to 1,000,000. The values above are relative weights in that calculation, not points added to the score.
Add a Consecutive Great Bonus
A consecutive Great bonus counts consecutive judgments graded Great or better. Add these fields to the existing level_score().update call in init_score: every 10 such judgments adds 0.01 to the multiplier. The bonus uses at most 50 consecutive judgments, so it stops increasing at 0.05.
python
def init_score():
level_score().update(
# ...
consecutive_great_multiplier=0.01,
consecutive_great_step=10,
consecutive_great_cap=50,
)Open guide/play/initialization.py and call init_score() once from Initialization.preprocess:
python
from guide.lib.note import init_score
class Initialization(PlayArchetype):
def preprocess(self):
# ...
init_score()
# ...Show Arcade Score
The primary metric bar shows progress toward the maximum score, while the primary metric value shows the current raw score.
Add UiMetric to the existing sonolus.script.ui import in guide/lib/ui.py, then select arcade score explicitly while preserving the other UiConfig arguments:
python
from sonolus.script.ui import UiConfig, UiMetric
ui_config = UiConfig(
primary_metric=UiMetric.ARCADE,
# ...
)In the same file, add both layouts to init_ui immediately after ui.combo_text.update(...). Place the metric value inside the metric bar:
python
from sonolus.script.runtime import HorizontalAlign, runtime_ui, safe_area, screen
from sonolus.script.vec import Vec2
def init_ui():
ui = runtime_ui()
# ...
ui.primary_metric_bar.update(
anchor=safe_area().tr - Vec2(0.05, 0.05),
pivot=Vec2(1, 1),
dimensions=Vec2(0.75, 0.15) * ui.primary_metric_config.scale,
rotation=0,
alpha=ui.primary_metric_config.alpha,
horizontal_align=HorizontalAlign.LEFT,
background=True,
)
ui.primary_metric_value.update(
anchor=(
safe_area().tr
- Vec2(0.05, 0.05)
- Vec2(0.035, 0.035) * ui.primary_metric_config.scale
),
pivot=Vec2(1, 1),
dimensions=Vec2(0, 0.08) * ui.primary_metric_config.scale,
rotation=0,
alpha=ui.primary_metric_config.alpha,
horizontal_align=HorizontalAlign.RIGHT,
background=False,
)
# ...Checkpoint
Run the level and hit several Notes. The primary metric value and bar should update as Sonolus records each result.