Jump to content

Variables Overview: Difference between revisions

From OpenBOR
No edit summary
No edit summary
 
Line 172: Line 172:


The <code>message</code> local variable remains available to both functions because they execute within the same script instance.
The <code>message</code> local variable remains available to both functions because they execute within the same script instance.
== Cleanup ==
=== Clearing Variables ===
Assign <code>NULL()</code> to clear a variable's value and release any resources owned by the variant.
<syntaxhighlight lang="c" line>
setglobalvar("some_name", NULL());
</syntaxhighlight>
Clearing a pointer variable does not destroy the object it references. If no other pointer references the object, it may remain allocated but inaccessible.
=== Freeing Objects ===
Use <code>free()</code> to destroy a script-allocated object before clearing the variable containing its pointer.
<syntaxhighlight lang="c" line>
void load_sprite() {
    /*
    * Load a sprite and store its pointer so other
    * functions can access it.
    */
    void sprite = loadsprite("data/some_folder/some_sprite.png");
    setlocalvar("sprite_name", sprite);
}
void free_sprite() {
    /*
    * Retrieve and free the sprite.
    */
    void sprite = getlocalvar("sprite_name");
    free(sprite);
    /*
    * Clear the variable containing the old pointer.
    */
    setlocalvar("sprite_name", NULL());
}
</syntaxhighlight>
Clearing a pointer does not free the referenced object. Likewise, freeing an object does not automatically clear variables containing its pointer. Perform both operations when cleaning up a manually allocated object.
[[Category:Script]]
[[Category:Script]]
[[Category:Openbor]]
[[Category:Openbor]]

Latest revision as of 21:02, 21 July 2026

Introduction

Variables are named identifiers that store values. Anyone who has worked with algebra has already used variables. They are one of the fundamental building blocks of scripting.

Type

Variable type describes the kind of data a variable contains and how that data behaves in expressions and operations.

OpenBOR Script is weakly typed. Every variable is stored internally as a variant, and the engine may change its type automatically as values are assigned or operations are performed. Declaration prefixes such as int, float, and char indicate the intended type, but do not enforce it unless type guards are enabled.

Weak typing reduces the need for manual conversions, though creators should remain aware of the type a variable currently contains.

int value = 0;

value = value + " is a string";

// value = "0 is a string"

In a strongly typed C program, combining an integer and string this way would produce a type error. OpenBOR Script instead converts the result to a string and assigns both its value and type to value.

Type Inspection

Use typeof() to determine the current type of a variable. The function returns an integer constant representing the variant type.

mixed value = "Example";

int variable_type = typeof(value);

if (variable_type == openborconstant("VT_STR")) {
    log("The value is a string.");
}
Type Constant Example Notes
Decimal openborconstant("VT_DECIMAL") float value = 0.1; Floating-point numeric value stored internally as a C double. Decimal literals must include a leading digit, so 0.1 is valid while .1 is not. Current builds provide approximately 15-17 significant decimal digits and a maximum magnitude of approximately 1.7 × 10308.
Integer openborconstant("VT_INTEGER") int value = 1; Signed 32-bit whole number ranging from -2,147,483,648 to 2,147,483,647. Integers promote to a 64-bit carrier when an operation or literal exceeds this range.
Integer 64 openborconstant("VT_INTEGER64") int value = 1LL; Signed 64-bit whole number ranging from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. The LL suffix explicitly requests a 64-bit signed literal. Unsuffixed values also promote automatically when required.
Unsigned Integer 64 openborconstant("VT_UINTEGER64") int value = 1ULL; Unsigned 64-bit whole number ranging from 0 to 18,446,744,073,709,551,615. The ULL suffix explicitly requests an unsigned 64-bit literal.
Empty openborconstant("VT_EMPTY") mixed value = NULL(); Undefined variable or value containing no data.
Pointer openborconstant("VT_PTR") void entity = getlocalvar("self"); Reference to a memory address. Pointers commonly reference structured engine objects such as entities, models, animations, or collections.
String openborconstant("VT_STR") char value = "Example"; Collection of characters representing text.

Strings and Numeric Conversion

Strings are not implicitly parsed back into numeric values. Assigning a numeric value directly to a variable can change its type, but numeric text must be converted before it can participate in arithmetic.

Use string_to_float() or string_to_int() to convert numeric text:

char string_value = "5";

int integer_value = string_to_int(string_value);
float decimal_value = string_to_float(string_value);

After conversion, integer_value and decimal_value may be used in arithmetic expressions.

Scope

Scope determines where a variable is accessible and how long it remains available. Creators should generally use the narrowest scope suitable for a task.

Function Variables

Variables declared inside a function are visible only within that function call. They are created when execution enters the function and destroyed when the function returns.

These are commonly called local variables in other programming languages. OpenBOR documentation refers to them as function variables to distinguish them from the persistent script storage accessed through getlocalvar() and setlocalvar().

void some_function() {
    int value = 10;

    log(value);
}

Other functions cannot directly access value.

Global Variables

setglobalvar("identifier", value);

mixed value = getglobalvar("identifier");

Global variables are available to all scripts and functions through a shared identifier. They may also be stored with saved game data and restored during a later session.

Global variables are powerful, though excessive use can make state changes difficult to trace and debug. Prefer narrower scopes unless information genuinely needs to be shared throughout the entire game.

Entity Variables

setentityvar(entity, "identifier", value);

mixed value = getentityvar(entity, "identifier");

Entity variables associate a value with a specific entity. Any script with a pointer to that entity may access the value using its identifier.

Entity variables remain available until the associated entity is destroyed.

void main() {
    void entity = getlocalvar("self");

    setentityvar(entity, "birthdate", "2004-01-01");
}

Entity variables are useful for storing custom state without placing it in the global variable collection.

Local Variables

setlocalvar("identifier", value);

mixed value = getlocalvar("identifier");

OpenBOR local variables belong to an individual script instance. Every function executed by that instance may access them, and their values remain available across repeated executions. The engine destroys them automatically when the script instance is destroyed.

Local variables are useful for sharing information between functions without passing numerous parameters or using global storage.

void main() {
    setlocalvar("message", "Hello world!");

    print_message();
}

void print_message() {
    char message = getlocalvar("message");

    log(message);
}

The message local variable remains available to both functions because they execute within the same script instance.

Cleanup

Clearing Variables

Assign NULL() to clear a variable's value and release any resources owned by the variant.

setglobalvar("some_name", NULL());

Clearing a pointer variable does not destroy the object it references. If no other pointer references the object, it may remain allocated but inaccessible.

Freeing Objects

Use free() to destroy a script-allocated object before clearing the variable containing its pointer.

void load_sprite() {
    /*
    * Load a sprite and store its pointer so other
    * functions can access it.
    */
    void sprite = loadsprite("data/some_folder/some_sprite.png");

    setlocalvar("sprite_name", sprite);
}

void free_sprite() {
    /*
    * Retrieve and free the sprite.
    */
    void sprite = getlocalvar("sprite_name");

    free(sprite);

    /*
    * Clear the variable containing the old pointer.
    */
    setlocalvar("sprite_name", NULL());
}

Clearing a pointer does not free the referenced object. Likewise, freeing an object does not automatically clear variables containing its pointer. Perform both operations when cleaning up a manually allocated object.