Jump to content

Logging

From OpenBOR

OpenBOR maintains two text log files for diagnostic and development purposes. Although their names are similar, each log serves a different purpose.

OpenBOR Log

The primary operational log. It records engine initialization, resource loading, warnings, errors, script exceptions, shutdown information, and creator-defined messages written with the log() script function.

Script Log

A specialized development log containing script code generated internally from animation @cmd instructions. It is primarily useful when diagnosing animation-script compilation and command-conversion problems.

The Script Log is not a general record of script activity. Script compilation errors, runtime exceptions, and calls to log() appear in the OpenBOR Log.

Log Filename Primary purpose
OpenBOR Log OpenBorLog.txt Engine diagnostics, warnings, errors, and creator-defined log entries.
Script Log ScriptLog.txt Generated animation-script code created from animation @cmd instructions.

Location

OpenBOR stores both files in its Logs directory:

Logs/OpenBorLog.txt
Logs/ScriptLog.txt

On desktop platforms, the Logs directory ordinarily resides in the OpenBOR application directory. On Android, it resides beneath OpenBOR's external storage root.

OpenBOR creates the Logs directory automatically when necessary. Log filenames should be treated as case-sensitive on platforms with case-sensitive file systems.

OpenBOR Log

OpenBorLog.txt is OpenBOR's primary diagnostic record. Most native engine messages are routed to this file.

Typical contents may include:

  • OpenBOR version and build information.
  • Platform, display, memory, and initialization information.
  • Selected game and pack information.
  • Resource and model loading progress.
  • Missing or malformed file warnings.
  • Invalid command and property warnings.
  • Script compilation errors.
  • Script function exceptions.
  • Controlled shutdown reasons.
  • Creator-defined entries written with log().

Exact contents vary according to the platform, build, project, and events occurring during the session.

Lifecycle

The OpenBOR Log represents the current or most recent OpenBOR session. When OpenBOR first writes to the log during a session, it opens the file in overwrite mode and replaces its previous contents.

Each message is flushed to the file immediately. This helps preserve diagnostic information if OpenBOR subsequently encounters an error or performs a controlled shutdown.

OpenBOR does not use OpenBorLog.txt as a permanent history. Copy or rename the file before launching OpenBOR again when a particular session must be preserved.

Troubleshooting

When OpenBOR reports an error or closes unexpectedly, inspect the final section of OpenBorLog.txt first. Controlled shutdowns ordinarily record the immediate reason near the end of the file. Earlier warnings may provide additional context leading to the final error.

Script errors commonly identify some combination of:

  • Script host or event name.
  • Function producing the exception.
  • Source file.
  • Line and column.
  • Invalid arguments or values.

The supplied line and column refer to the script source as OpenBOR parsed it. When an error originates from a generated animation script, consult the Script Log as described below.

Script API

The log() function allows creators to add custom entries to the OpenBOR Log.

Write Log Entry

log({value});
  • {value} - Value to convert into text and write to OpenBorLog.txt.
  • Accepts exactly one parameter.
  • Returns no value.
  • Does not add a line break automatically.

Despite its historical description as log(string), the supplied value does not have to already be a string. OpenBOR converts the value to its text representation before writing it.

log("Level initialized.\n");

int phase = 3;

log("Current phase: " + phase + "\n");

Supplying no parameter or more than one parameter causes a script function exception. Concatenate multiple values into a single expression before calling log().

/* Correct. */
log("Position: " + position_x + ", " + position_z + "\n");

/* Incorrect - log() does not accept multiple parameters. */
log("Position: ", position_x, position_z);

Line Breaks

log() writes only the supplied text. It does not automatically place subsequent entries on a new line.

log("First");
log("Second");

The resulting output is:

FirstSecond

Include \n when the entry should end with a line break:

log("First\n");
log("Second\n");

The resulting output is:

First
Second

Formatting

log() is not a formatted-print function. Conversion placeholders such as %d and %s are not processed, and additional formatting arguments are not accepted.

Construct the complete message before passing it to log():

int health = 50;

/* Correct. */
log("Current health: " + health + "\n");

/* Incorrect. */
log("Current health: %d\n", health);

Diagnostic Example

Custom log entries are useful for confirming whether an event fires, recording state transitions, or preserving values immediately before an unexpected result.

void oncreate() {
    log("[Level] Level script created.\n");
}

void record_phase_change(int previous_phase, int current_phase){
    log("[Phase] " 
        + previous_phase
        + " -> "
        + current_phase
        + "\n"
    );
}

Prefixes such as [Level], [Entity], or [Combat] make creator-defined entries easier to locate among native engine messages.

Performance

Each log() call writes and flushes its output immediately. Persistent logging from frequently executed events can therefore create large files and introduce unnecessary file-system activity.

Use particular care with:

  • update.c and updated.c, which may execute once per outer update.
  • Entity update scripts, which may execute on every logical tick.
  • Loops processing multiple entities, frames, or collision items.
  • Repeated warnings without a suppression condition.

Temporary high-frequency logging can be useful during diagnosis, but should ordinarily be removed or disabled after the relevant behavior is verified.

A conditional diagnostic switch allows logging to remain available without producing output during normal play:

#define DEBUG_LOG_ENABLED 0

void debug_log(void value){
    if(DEBUG_LOG_ENABLED){
        log(value);
    }
}

Script Log

ScriptLog.txt contains animation-script code generated internally while OpenBOR loads model animation data.

Animation @cmd instructions provide a convenient way to call script functions from animation frames. OpenBOR implements this feature by constructing an animation-script main() function containing the required frame tests and function calls. The generated function is written to the Script Log before compilation.

Entries are separated by headers identifying the originating model file:

#### animationscript function main #####
# data/chars/example/example.txt
########################################

The generated function follows the header.

Purpose

The Script Log allows creators to inspect the code OpenBOR constructed from animation commands. This is especially useful when:

  • An animation @cmd call fails to compile.
  • OpenBOR cannot find the requested function.
  • An @cmd argument produces unexpected generated syntax.
  • Several animation commands interact within the generated main() function.
  • An error line refers to generated animation-script code rather than a standalone script file.

The Script Log should be read together with the corresponding error in OpenBorLog.txt. The OpenBOR Log reports the compilation or execution problem, while the Script Log shows the generated animation code involved.

Scope

ScriptLog.txt does not ordinarily contain:

  • Calls made with log().
  • General engine warnings or errors.
  • Runtime traces of script execution.
  • Complete copies of every loaded script.
  • Compilation output for ordinary script files.
  • Values returned by script functions.

Creator-defined log messages and script error reports belong to OpenBorLog.txt.

Lifecycle

The Script Log opens in overwrite mode when OpenBOR first writes generated animation-script content during a session. Additional generated functions from the same session are written to the same open file.

Each write is flushed immediately.

If the current project does not generate applicable animation-script content, OpenBOR may not open or replace ScriptLog.txt. An existing Script Log may therefore remain from an earlier session. Check its contents and modification time before assuming it represents the current launch.

Diagnostic Workflow

For a general engine or script problem:

  1. Reproduce the problem.
  2. Close OpenBOR, or allow its controlled shutdown to complete.
  3. Open Logs/OpenBorLog.txt.
  4. Inspect the final error and preceding warnings.
  5. Locate the referenced source file, function, line, or property.
  6. Correct the source and launch OpenBOR again.

For a problem involving animation @cmd instructions:

  1. Locate the error in OpenBorLog.txt.
  2. Note the model, script host, line, function, and invalid value.
  3. Open ScriptLog.txt.
  4. Find the header for the relevant model file.
  5. Inspect the generated animation-script function.
  6. Correct the original @cmd instruction or called script function.

When requesting assistance, provide OpenBorLog.txt and the relevant source files. Include ScriptLog.txt when the problem involves animation commands or generated animation-script code.

Log files may contain local file paths and basic platform information. Review their contents before sharing them publicly.