Sonolus Wiki

16. Arcade Score

In this chapter, we will set up arcade score and primary metric UI.

Judgment Type Base Score Multiplier

Each judgment type can have their own base score multipliers, typically set to 1 for Perfect and lower for Great and Good:

export class Initialization extends Archetype {
    preprocess() {
        // ...

        score.base.set({
            perfect: 1,
            great: 0.75,
            good: 0.5,
        })

        // ...
    }

    // ...
}
export class Initialization extends Archetype {
    preprocess() {
        // ...

        score.base.set({
            perfect: 1,
            great: 0.75,
            good: 0.5,
        })

        // ...
    }

    // ...
}

Judgment Type Consecutive Score Multiplier

Judgment type consecutive score multiplier refers to score multiplier that accumulates as you hit with equal or higher than the target judgment.

To explain with an example, we are going to set the consecutive Great score multiplier to accumulate 0.01 every 10, capped at 50. That means for every 10 consecutive Greats you hit, you get 0.01 additional score multiplier, up to 50 consecutive Greats (so you can get up to 0.05 increased score).

export class Initialization extends Archetype {
    preprocess() {
        // ...
        score.consecutive.great.set({
            multiplier: 0.01,
            step: 10,
            cap: 50,
        })

        // ...
    }

    // ...
}
export class Initialization extends Archetype {
    preprocess() {
        // ...
        score.consecutive.great.set({
            multiplier: 0.01,
            step: 10,
            cap: 50,
        })

        // ...
    }

    // ...
}

Primary Metric UI

There are primary metric bar and primary metric value UI for displaying a primary metric of player's choice, most commonly arcade score. Primary metric bar shows a progress bar showing percentage, while primary metric value shows the raw value.

It is recommended to stack them on top of each other to show both information at once:

export class Initialization extends Archetype {
    preprocess() {
        // ...

        ui.metric.primary.bar.set({
            anchor: screen.rect.rt.sub(new Vec(0.05, 0.05)),
            pivot: { x: 1, y: 1 },
            size: new Vec(0.75, 0.15).mul(ui.configuration.metric.primary.scale),
            rotation: 0,
            alpha: ui.configuration.metric.primary.alpha,
            horizontalAlign: HorizontalAlign.Left,
            background: true,
        })
        ui.metric.primary.value.set({
            anchor: screen.rect.rt
                .sub(new Vec(0.05, 0.05))
                .sub(new Vec(0.035, 0.035).mul(ui.configuration.metric.primary.scale)),
            pivot: { x: 1, y: 1 },
            size: new Vec(0, 0.08).mul(ui.configuration.metric.primary.scale),
            rotation: 0,
            alpha: ui.configuration.metric.primary.alpha,
            horizontalAlign: HorizontalAlign.Right,
            background: false,
        })

        // ...
    }

    // ...
}
export class Initialization extends Archetype {
    preprocess() {
        // ...

        ui.metric.primary.bar.set({
            anchor: screen.rect.rt.sub(new Vec(0.05, 0.05)),
            pivot: { x: 1, y: 1 },
            size: new Vec(0.75, 0.15).mul(ui.configuration.metric.primary.scale),
            rotation: 0,
            alpha: ui.configuration.metric.primary.alpha,
            horizontalAlign: HorizontalAlign.Left,
            background: true,
        })
        ui.metric.primary.value.set({
            anchor: screen.rect.rt
                .sub(new Vec(0.05, 0.05))
                .sub(new Vec(0.035, 0.035).mul(ui.configuration.metric.primary.scale)),
            pivot: { x: 1, y: 1 },
            size: new Vec(0, 0.08).mul(ui.configuration.metric.primary.scale),
            rotation: 0,
            alpha: ui.configuration.metric.primary.alpha,
            horizontalAlign: HorizontalAlign.Right,
            background: false,
        })

        // ...
    }

    // ...
}