Jump to content

Score Scripts

From OpenBOR
Revision as of 17:24, 20 August 2026 by Dcurrent (talk | contribs) (Execution)


Score scripts are automatic player-slot event hooks that execute whenever OpenBOR processes a score award through its native score routine. Four optional files are available, one for each player slot:

  • data/scripts/score1.c
  • data/scripts/score2.c
  • data/scripts/score3.c
  • data/scripts/score4.c

Each script receives the unsigned 64-bit amount submitted to the score routine. This makes score scripts useful for custom feedback, milestones, achievements, secondary reward systems, cooperative scoring, statistics, and any other mechanic that should react immediately to native score awards.

OpenBOR's score system supports values from 0 through 18446744073709551615. This provides enough range for extreme scoring systems, large multipliers, dense projectile bonuses, and other designs without requiring creators to split a score into manually carried pieces.

Score scripts are award events rather than general observers of the score property. Writing a player's score directly through script does not execute them.

Usage

Create the desired numbered script in data/scripts. OpenBOR loads it automatically, so no model, level, or project command is required.

score#.c is documentation shorthand in which # represents the player number. The literal filenames use 1 through 4.

File Player Player index
data/scripts/score1.c Player 1 0
data/scripts/score2.c Player 2 1
data/scripts/score3.c Player 3 2
data/scripts/score4.c Player 4 3

The basic structure is:

void main()
{
    unsigned long score = getlocalvar("score");

    // React to the score award here.
}

The filename identifies the player slot. OpenBOR does not supply player or self automatically.

Execution

The immediate score-award sequence is:

  1. OpenBOR receives a player slot and an amount to add.
  2. OpenBOR calculates applicable extra-life thresholds.
  3. The amount is added to the player's score. Any overflow caps at the maximum score value of 18,446,744,073,709,551,615.
  4. Applicable extra lives are awarded.
  5. OpenBOR stores the updated score total.
  6. The corresponding numbered score script executes with local variable score.

The player's updated score and any extra lives from the award are already available when the script executes. Native processing for that individual score award is otherwise complete.

Score scripts execute once for each call to the native score routine, not once per update and not once for an accumulated group of awards. Stage-completion counting may therefore produce a sequence of small events as bonuses are transferred into the player's total.

OpenBOR may also submit an amount of zero to the score routine. Scripts that only need positive awards should test score before producing effects.

Event Data

Variable Type Description
score Unsigned 64-bit integer (VT_UINTEGER64) Amount submitted to the native score routine for the player slot associated with the script file.

score is the award amount, not the player's new total. It is also not necessarily the actual increase in the stored total. For example, an award that reaches the unsigned 64-bit maximum still supplies its original amount to the event.

Changing the local score variable does not alter the award or the stored player score because the event executes after native score processing. The event supplies the award rather than the running total. Systems that need an independent total may accumulate the unsigned 64-bit awards in a global variable, as shown below.

Score Range

Native score awards and totals use unsigned 64-bit values.

Limit Value
Minimum 0
Maximum 18446744073709551615

The maximum is also known as UINT64_MAX, or 264 - 1. Score addition uses saturation: when an award would exceed this limit, OpenBOR stores the maximum instead of allowing the total to wrap back to a smaller value.

Player totals, model and level score values, saved scores, high-score entries, and the score event variable preserve this range. Model and level score commands accept unsigned 64-bit values; negative score values are invalid.

The scoreformat setting continues to pad short values to nine digits. Nine digits are a minimum display width rather than a limit, so larger totals remain visible in full.

What Triggers the Event

Native score awards include points generated by normal engine systems such as:

  • Damage and hit scoring.
  • Defeating entities with a configured score value.
  • Collecting items with a configured score value.
  • Damaging obstacles.
  • Reaching an end-level entity with a score value.
  • Clear, life, and rush bonuses awarded during stage completion.

The precise award depends on the applicable model, attack, level, and project configuration. Each native award runs the numbered script for the player receiving it.

Several operations can change a player's stored total without representing a new score award. Direct score-property writes, loading saved data, and internal score resets do not pass through the native addition routine and therefore do not execute score#.c. This separation prevents initialization, restoration, or scripted replacement of a total from being mistaken for gameplay scoring.

Example: Award Feedback

The following data/scripts/score1.c records Player 1's latest award and requests stronger feedback for large awards. An update, draw, or HUD script can consume the stored values and provide the desired presentation.

void main()
{
    unsigned long award = getlocalvar("score");

    if (award > 0)
    {
        setglobalvar("p1_last_score_award", award);

        if (award >= 1000)
        {
            setglobalvar("p1_score_flash", 2);
        }
        else
        {
            setglobalvar("p1_score_flash", 1);
        }
    }
}

The same pattern can be used in the other numbered files. The filename supplies the player identity. Keeping visual or timed behavior in an update or draw script allows the score event to remain focused on recording the award and starting the response.

Example: Shared Team Score

Individual score scripts may contribute to a common system. This compact score2.c example adds Player 2's positive awards to a shared team tally. It assumes team_score was initialized to 0 by a level-start or other setup script.

void main()
{
    unsigned long award = getlocalvar("score");
    unsigned long team_score = getglobalvar("team_score");

    if (award > 0)
    {
        setglobalvar("team_score", team_score + award);
    }
}

Equivalent handlers in score1.c, score3.c, and score4.c create a cooperative total without replacing each player's native score. The same arrangement can power team milestones, shared resources, competitive comparisons, or multiplayer challenge rules.

Other Uses

Quick applications include:

  • Presentation - Select sounds, flashes, text, particles, or camera effects according to the award size.
  • Milestones - Detect score thresholds and trigger ranks, unlocks, achievements, or rewards.
  • Secondary resources - Convert native points into meter, currency, experience, continues, or another custom value.
  • Cooperative systems - Combine awards from several player slots into a shared objective or team score.
  • Competitive systems - Track momentum, compare recent gains, or announce changes in player standing.
  • Challenge logic - Count qualifying awards, enforce score goals, or record progress for bonus conditions.
  • Statistics - Record award frequency, largest gains, stage totals, or player-specific performance data.

The numbered file identifies the player, and score provides the award amount, but the event supplies no dedicated source identifier. Systems that need to distinguish hits, defeats, pickups, or bonuses can combine the event with state recorded by the relevant attack, model, item, spawn, or level scripts.

See Also