# Lighthouse Engine Logging and Debugging Capabilities: Complete Guide

> Explore Lighthouse's logging and debugging capabilities. Inspect game state with on-screen debug text, module stubs, audio flags, and compile-time toggles. No external tools needed.

- Repository: [Harbour Masters/Lighthouse](https://github.com/HarbourMasters/Lighthouse)
- Tags: complete-guide
- Published: 2026-08-04

---

**Lighthouse provides built-in on-screen debug text, per-module debug stubs, audio-specific flags, and compile-time toggles to inspect game state without external tools.**

The HarbourMasters Lighthouse project is an open-source N64-style game engine that ships with lightweight, runtime-visible debugging utilities. These capabilities are designed for target hardware and emulators, offering `printf`-style diagnostics where a conventional console does not exist. This guide covers every logging and debugging facility available in the codebase.

## On-Screen Debug Text Overlay

The primary debugging interface is a small console rendered directly on the game screen. It can display integers, floats, and strings in real time.

### Core Functions in [`src/core1/debugtext.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core1/debugtext.c)

The debug text system centers on three key functions:

- **`gcdebugText_showLargeValue(int slot, s32 value)`** — Prints a 32-bit integer to a numbered on-screen slot.
- **`gcdebugText_pauseThread(void)`** — Halts execution so you can read the value before it updates.
- **`gcdebugText_isThreadLocked(void)`** — Returns whether the debug thread lock is active, useful for race-condition detection.

### Example: Displaying a Large Integer

```c
/* Print 12345678 to debug slot 1 */
gcdebugText_showLargeValue(1, 12345678);
gcdebugText_pauseThread();   /* Halt to inspect in emulator */

```

This pattern appears throughout the engine when developers need immediate visual feedback without serial output.

## Per-Module Debug Stubs

Most core modules expose a `*_debug` or `*_debugN` function that prints internal state when invoked. These stubs are empty in release builds but activate when compiled with `DEBUG` or `_DEBUG_INTERNAL` macros.

### Key Debug Stubs by Module

| Function | Source File | Purpose |
|----------|-------------|---------|
| `viewport_debug` | [`src/core1/viewport.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core1/viewport.c) | Visualizes viewport transform matrices and clipping planes. |
| `overlayManager_debug` | [`src/core1/overlaymanager.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core1/overlaymanager.c) | Lists active memory overlays and their load states. |
| `mumboscore_debug` | [`src/core2/mumboscore.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core2/mumboscore.c) | Dumps Mumbo token counts and unlock flags. |
| `jiggyscore_debug` | [`src/core2/jiggyscore.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core2/jiggyscore.c) | Prints Jiggy piece collection state. |
| `honeycombscore_debug` | [`src/core2/honeycombscore.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core2/honeycombscore.c) | Shows health upgrade progress. |

### Example: Invoking Module Debug Output

```c
void mySpecialFunction(void) {
    /* ... normal game logic ... */

    viewport_debug();   /* Prints viewport state (DEBUG builds only) */
}

```

These stubs follow a consistent naming convention: module name suffixed with `_debug`, returning `void` and taking no parameters in most cases.

## Audio Subsystem Debug Flags

The `n_audio` subsystem includes specialized diagnostics for tracking sound engine failures. Two files implement these checks:

- **[`src/core1/n_audio/n_seqplayer.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core1/n_audio/n_seqplayer.c)** — Sequence player diagnostics.
- **[`src/core1/n_audio/n_csplayer.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core1/n_audio/n_csplayer.c)** — Compressed sound player diagnostics.

Both use a `debugFlags` field with macros like `ALFlagFailIf` to assertion-fail or print when specific error conditions occur.

### Example: Checking Audio Debug Flags

```c
/* From n_seqplayer.c: flag missing sound errors */
if (seqp->debugFlags & NO_SOUND_ERR_MASK) {
    gcdebugText_showLargeValue(2, 2002);   /* Error code 2002 = missing sound */
}

```

The `NO_SOUND_ERR_MASK` and similar constants allow granular control over which audio errors surface to the debug overlay.

## Compile-Time Debug Toggles

All debug functionality is gated by preprocessor macros. Enabling these at build time activates the entire debugging surface without source changes.

### Build Configuration Macros

| Macro | Effect | Typical Location |
|-------|--------|----------------|
| `DEBUG` | Legacy toggle; enables basic debug stubs. | Compiler command line or [`CMakeLists.txt`](https://github.com/HarbourMasters/Lighthouse/blob/main/CMakeLists.txt) |
| `_DEBUG_INTERNAL` | Modern replacement; activates verbose logging and on-screen text. | [`CMakeLists.txt`](https://github.com/HarbourMasters/Lighthouse/blob/main/CMakeLists.txt) or header predefines |

In [`CMakeLists.txt`](https://github.com/HarbourMasters/Lighthouse/blob/main/CMakeLists.txt), you might define:

```cmake
target_compile_definitions(lighthouse PRIVATE _DEBUG_INTERNAL)

```

When neither macro is defined, debug stubs compile to empty functions and `gcdebugText_*` calls become no-ops, ensuring zero runtime overhead in release builds.

## Thread-Safety Verification

The debug text system includes primitives for detecting concurrent access to critical sections.

### Functions for Race-Condition Detection

- **`gcdebugText_isThreadLocked(void)`** — Query whether the debug system holds its internal lock.
- **`gcdebugText_pauseThread(void)`** — Explicitly acquire the lock and halt; serves as a breakpoint substitute.

### Example: Verifying Thread Safety

```c
if (gcdebugText_isThreadLocked()) {
    /* Another context already holds the lock — potential race */
    gcdebugText_showLargeValue(3, 0xDEAD);
}
gcdebugText_pauseThread();   /* Safe inspection point */

```

This pattern helps catch main thread violations on N64 hardware where traditional debuggers are unavailable.

## Summary

- **On-screen debug text** in [`src/core1/debugtext.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core1/debugtext.c) provides `gcdebugText_showLargeValue`, `gcdebugText_pauseThread`, and `gcdebugText_isThreadLocked` for runtime visualization.
- **Per-module stubs** like `viewport_debug`, `overlayManager_debug`, and `mumboscore_debug` offer state dumps when `_DEBUG_INTERNAL` is defined.
- **Audio debug flags** in [`n_seqplayer.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/n_seqplayer.c) and [`n_csplayer.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/n_csplayer.c) expose `debugFlags` fields for sound engine diagnostics.
- **Compile-time toggles** via `DEBUG` or `_DEBUG_INTERNAL` macros enable or strip all debug code at build time.
- **Thread-safety helpers** allow rudimentary race condition detection without external tooling.

These capabilities make Lighthouse logging and debugging practical for N64 hardware development where conventional debugging infrastructure is absent.

## Frequently Asked Questions

### How do I enable debug output in a Lighthouse build?

Define `_DEBUG_INTERNAL` in your build configuration, typically by adding `target_compile_definitions(lighthouse PRIVATE _DEBUG_INTERNAL)` to [`CMakeLists.txt`](https://github.com/HarbourMasters/Lighthouse/blob/main/CMakeLists.txt) or passing `-D_DEBUG_INTERNAL` to your compiler. This activates all debug stubs and the on-screen text overlay.

### Where is the on-screen debug console implemented?

The debug text overlay lives in [`src/core1/debugtext.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/core1/debugtext.c). It provides `gcdebugText_showLargeValue` for printing integers, `gcdebugText_pauseThread` for execution halts, and `gcdebugText_isThreadLocked` for thread-safety checks.

### Do debug features impact release build performance?

No. When `DEBUG` and `_DEBUG_INTERNAL` are undefined, all debug functions compile to empty bodies or no-ops. The linker typically eliminates them entirely, resulting in zero runtime overhead.

### Can I add custom debug output to my own Lighthouse module?

Yes. Follow the established pattern: create a `yourmodule_debug(void)` function that prints relevant state, guard it with `#ifdef _DEBUG_INTERNAL`, and call it where needed. The build system will strip it automatically in release builds.