Jump to content

Updatescript

From OpenBOR
Revision as of 18:51, 20 August 2026 by Dcurrent (talk | contribs)


updatescript is a level-specific recurring event hook. It executes near the beginning of each eligible outer update cycle while its level is loaded, after the global data/scripts/update.c hook but before key events, logical-time advancement, scrolling, entity simulation, and display preparation.

This early position makes updatescript a powerful level controller. It can coordinate encounters, advance objectives, apply stage-specific rules, prepare environmental state, synchronize multiplayer systems, and make decisions that affect the rest of the same update cycle without placing project-wide logic in the global update script.

Usage

Add updatescript to a level definition and provide the path to the script file:

updatescript data/scripts/levels/storm_docks_update.c

The referenced script uses a main() entry point and receives no automatic event variables.

void main()
{
    // Perform recurring level-specific logic here.
}

OpenBOR loads the script with the level and executes it only while that level remains available. No project-wide file or model command is required.

Only one updatescript command is available to a level. Multiple recurring tasks may be organized into functions and called from the script's main().

Inline Script

The command also supports an inline script block:

updatescript @script
void main()
{
    int state = getglobalvar("storm_docks_state");

    if (state == 1)
    {
        setglobalvar("storm_docks_active", 1);
    }
}
@end_script

Inline form is useful for concise level-only behavior. External files are easier to reuse and organize when the level controller contains several systems or helper functions.

Execution

The relevant outer update sequence is:

  1. OpenBOR refreshes timing and player input state.
  2. Global data/scripts/update.c executes when present.
  3. The current level's updatescript executes when declared.
  4. OpenBOR processes applicable key-script events.
  5. OpenBOR advances logical time and performs scrolling, timer, and entity simulation work as required.
  6. OpenBOR clears the working screen and constructs the background, interface, text, and entity display queues.
  7. Global data/scripts/updated.c executes when present.
  8. The current level's updatedscript executes when declared.
  9. OpenBOR continues with the remaining presentation and control work for the cycle.

The global update script always executes before the level update script. The level script can therefore build on common project state established by update.c, specialize it for the current stage, or replace values before downstream systems use them.

Changes made by updatescript are visible to key scripts, entities, scrolling logic, timers, display preparation, and later update hooks during the same cycle. This makes it an effective coordination point when several independent systems must agree on the level's current state.

Execution Frequency

updatescript executes once per eligible outer update cycle. Outer update frequency is independent of OpenBOR's logical clock and may vary with the selected update limit, display synchronization, platform timing, and runtime conditions.

One script execution therefore does not necessarily represent one logical tick. Logic that measures gameplay duration can compare openborvariant("elapsed_time") or another suitable time source instead of treating execution count as elapsed time.

By default, the early update hooks execute while gameplay is active and not paused. Enabling alwaysupdate expands the global update condition. The level-specific updatescript can then continue executing during other update calls when its level remains loaded, including paused gameplay.

Level Scope

Global update.c is appropriate for systems used throughout a project. Level updatescript provides the same early-cycle phase with a narrower lifetime and direct ownership by one level.

This separation keeps stage-specific rules with the stage that uses them. Projects can maintain universal managers in update.c, while individual levels supply their own objectives, encounter sequencing, weather, camera behavior, hazards, scoring conditions, cooperative rules, or presentation state without accumulating every stage's logic in one global file.

Example: Encounter Coordinator

The following compact controller advances an encounter when other scripts report that the first wave is clear:

void main()
{
    int phase = getglobalvar("dock_encounter_phase");
    int wave_clear = getglobalvar("dock_wave_clear");

    if (phase == 1 && wave_clear)
    {
        setglobalvar("dock_encounter_phase", 2);
        setglobalvar("dock_release_wave", 2);
        setglobalvar("dock_wave_clear", 0);
    }
}

Spawn scripts, model scripts, or other encounter components can consume dock_release_wave later in the same cycle. The update script remains focused on coordination while each participating system handles its own work.

Example: Timed Environment State

This example starts a recurring storm pulse using logical time. An updated, draw, animation, or entity script can consume storm_pulse to provide the desired presentation or gameplay effect.

void main()
{
    long elapsed = openborvariant("elapsed_time");
    long next_pulse = getglobalvar("storm_next_pulse");

    if (!next_pulse)
    {
        setglobalvar("storm_next_pulse", elapsed + 400);
    }
    else if (elapsed >= next_pulse)
    {
        setglobalvar("storm_pulse", 1);
        setglobalvar("storm_next_pulse", elapsed + 400);
    }
}

The comparison remains tied to logical time even when several outer update cycles occur without a logical tick or when the outer update rate changes.

Choosing an Update Hook

Hook Scope Phase Typical responsibility
data/scripts/update.c Project-wide First recurring script in the outer update cycle Universal managers and common project state
level updatescript Current level After global update.c, before key events and simulation Stage-specific rules, objectives, encounters, and environment state
model script Individual active entity Entity simulation Per-entity recurring behavior
data/scripts/updated.c Project-wide After simulation and display queue construction Universal late-cycle logic and presentation
level updatedscript Current level After global updated.c Stage-specific late-cycle logic and presentation

The hooks complement one another. Projects can distribute work according to ownership and timing instead of forcing unrelated systems into a single recurring script.

Other Uses

Quick applications include:

  • Encounter management - Advance waves, coordinate reinforcements, track groups, release exits, or control multi-part battles.
  • Objectives - Evaluate success, failure, escorts, survival conditions, collectibles, timers, or optional challenges.
  • Environment control - Prepare weather, lighting, palette, hazard, scrolling, camera, or audio state for the current cycle.
  • Level rules - Apply stage-specific movement, resource, scoring, faction, damage, or cooperative conditions.
  • Pacing - Open routes, activate controllers, change intensity, or transition between level phases.
  • Multiplayer coordination - Track team state, synchronize roles, manage shared objectives, or respond to participating players.
  • Presentation state - Prepare values consumed later by updated, drawing, HUD, animation, or entity scripts.
  • Development tools - Monitor stage systems, expose debugging state, collect timing data, or test encounter transitions.
Script Relationship
update.c Global early-cycle hook that executes before the level's updatescript.
updatescript Level-specific early-cycle hook that executes before key events and simulation.
updated.c Global late-cycle hook that executes after simulation and display queue construction.
updatedscript Level-specific late-cycle hook that executes after global updated.c.
updateentityscript Recurring model hook executed as part of entity simulation.
levelscript One-time level-start hook used to establish initial state before recurring updates begin.
endlevelscript One-time level-end hook used to finalize state after recurring updates stop.

See Also