# How the Lighthouse Decompilation Project Is Structured: A Deep Dive into the Banjo-Kazooie Source Code

> Explore the Lighthouse decompilation project structure. Discover its layered architecture, CMake builds, N64 emulation, game logic, and asset pipelines for Banjo-Kazooie.

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

---

**The Lighthouse repository follows a layered architecture with CMake-driven builds, global headers in `include/`, low-level N64 emulation via libultralib, game logic in `src/`, and YAML-based asset pipelines.**

The Lighthouse decompilation project is a community effort to recreate *Banjo-Kazooie* as clean, buildable C code that runs on modern platforms. Understanding how the Lighthouse decompilation project structure works is essential for contributors aiming to extend the engine or debug gameplay systems. This guide walks through each architectural layer, from build scripts to game logic, with concrete examples from the source tree.

---

## Root Directory and CMake Build System

The repository root contains the orchestration layer. The top-level [`CMakeLists.txt`](https://github.com/HarbourMasters/Lighthouse/blob/main/CMakeLists.txt) defines the entire build process: it pulls in the `libultraship` submodule, sets platform-specific compiler flags, and registers custom CMake targets.

Two targets are critical for first-time setup:

- `ExtractAssets` — runs the Torch-based extractor to produce `bk.o2r` from a legal ROM
- `GeneratePortO2R` — packages port-specific textures and shaders into `lighthouse.o2r`

These targets are invoked automatically via the commands documented in [`docs/BUILDING.md`](https://github.com/HarbourMasters/Lighthouse/blob/main/docs/BUILDING.md). The root also houses CI configuration (`.github/workflows/`), documentation (`docs/`), and the [`README.md`](https://github.com/HarbourMasters/Lighthouse/blob/main/README.md) with quick-start instructions.

---

## Global Headers in `include/`

The `include/` directory is the single source of truth for data structures that mirror the original N64 binary layout. Every source file includes these headers, making them the backbone of the decompilation's memory model.

Key files:

- **[`structs.h`](https://github.com/HarbourMasters/Lighthouse/blob/main/structs.h)** — defines `Object`, `Level`, `Player`, and other core structs passed throughout the engine
- **[`variables.h`](https://github.com/HarbourMasters/Lighthouse/blob/main/variables.h)** — holds global state such as `gCurrentLevel` and `gPlayerHealth`

Because these headers are universally included, changes here propagate across the entire codebase. This design matches the original game's reliance on fixed-memory layouts for its actors and world state.

---

## Low-Level N64 Emulation via `lib/ultralib/`

Rather than shipping Nintendo's original proprietary SDK, the project depends on **libultraship**, a community-maintained submodule hosted in `lib/ultralib/`. This library provides:

- **RSP/CPU primitives** — vector mathematics, DMA transfers, and inter-processor messaging
- **Audio synthesis** — sample playback, reverb, and sequencer logic
- **Utility macros** — assertions via [`ultra_assert.h`](https://github.com/HarbourMasters/Lighthouse/blob/main/ultra_assert.h) and platform-agnostic wrappers

Higher-level game code calls into this layer exactly as the original binary did, preserving timing-sensitive behavior. The [`ultra_assert.h`](https://github.com/HarbourMasters/Lighthouse/blob/main/ultra_assert.h) header, for example, is referenced across the codebase for runtime consistency checks.

---

## Game Logic in `src/`

The `src/` directory contains the decompiled game implementation, organized to reflect the original module boundaries.

### The `SM/` Subdirectory

Despite its name, `SM/` holds the core *Banjo-Kazooie* gameplay systems. Key files include:

- **[`quarrie.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/quarrie.c)** — level initialization and player spawn logic
- **[`anim_callbacks.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/anim_callbacks.c)** — animation state machine callbacks
- **[`furniture.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/furniture.c)** — interactive object handlers

These files implement character movement, collision response, and object interaction. They rely on the global structs from `include/` and call into `libultralib` for hardware-abstraction needs.

### Cut-Scene System in `cutscenes/`

Each scripted sequence lives in its own module:

- [`cutscene_trigger.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/cutscene_trigger.c) — detects conditions and launches sequences
- [`sparkle.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/sparkle.c), [`glow_sparkle.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/glow_sparkle.c) — individual cut-scene implementations
- [`cutscene_animsequence.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/cutscene_animsequence.c) — drives camera and animation from extracted assets

The cut-scene manager registers callbacks that pause normal gameplay, play the sequence, then restore control.

### Development and Reference Subdirectories

- **`emptyLvl/`** — a minimal test level for rapid iteration without loading the full game world
- **`unused/`** — legacy code retained for reference; excluded from the final binary

---

## Example: Level Initialization from [`quarrie.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/quarrie.c)

This pattern appears throughout `src/SM/` for every playable area:

```c
#include "include/structs.h"
#include "include/variables.h"

/* Called once ROM assets are unpacked */
void init_quarrie(void) {
    /* Set player start position */
    gPlayer->position = (Vec3){ .x = 100.0f, .y = 0.0f, .z = -250.0f };
    
    /* Stream level geometry via DMA-style loader */
    load_level_geometry("quarrie_lvl.bin");
    
    /* Register per-frame update hook */
    register_update_callback(quarrie_update);
}

```

The function composes global state manipulation (`gPlayer`), asset loading (`load_level_geometry`), and engine registration (`register_update_callback`) — the three pillars of level initialization in this architecture.

---

## Example: Cut-Scene Trigger from [`cutscene_trigger.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/cutscene_trigger.c)

```c
#include "include/structs.h"

/* Invoked on player-object collision */
void trigger_cutscene(Object *obj) {
    if (obj->state == OBJ_STATE_ACTIVE) {
        /* Queue cut-scene by ID; manager handles the rest */
        start_cutscene(CUTSCENE_SPARKLE);
    }
}

```

The trigger inspects object state, then delegates to the centralized cut-scene system. This separation keeps gameplay code focused on conditions while the `cutscenes/` modules handle presentation.

---

## Asset Pipelines in `assets/` and `docs/`

Runtime content is defined declaratively in YAML files under `assets/yaml/us/rev1/`. The build tooling (documented as "retro" in the README) consumes these definitions to generate `.o2r` and `.otr` archives.

- **[`soundfont.yaml`](https://github.com/HarbourMasters/Lighthouse/blob/main/soundfont.yaml)** — describes instrument banks and sample mappings
- Texture and model definitions — specify source files and compression settings

The [`docs/BUILDING.md`](https://github.com/HarbourMasters/Lighthouse/blob/main/docs/BUILDING.md) file contains the exact command sequences for generating these archives, which the engine loads at startup. This pipeline decouples asset authoring from engine compilation, enabling iterative content work without full rebuilds.

---

## Continuous Integration and Distribution

GitHub Actions workflows in `.github/workflows/` automate three stages on every commit:

1. **Asset extraction** — runs `ExtractAssets` on a runner configured with the extractor (ROM not included in repository)
2. **Multi-platform builds** — compiles for Windows (MSVC), macOS (Xcode), and Linux (GCC/Clang) via CMake generators
3. **Packaging** — produces zip archives, AppImages, and DMG bundles for end-user testing

This pipeline ensures reproducible binaries and catches build regressions before they reach contributors.

---

## Summary

- **CMake-driven builds** — [`CMakeLists.txt`](https://github.com/HarbourMasters/Lighthouse/blob/main/CMakeLists.txt) orchestrates extraction, compilation, and packaging through documented targets
- **Centralized headers** — [`include/structs.h`](https://github.com/HarbourMasters/Lighthouse/blob/main/include/structs.h) and [`include/variables.h`](https://github.com/HarbourMasters/Lighthouse/blob/main/include/variables.h) provide the memory model shared across all modules
- **Hardware abstraction** — `lib/ultralib/` (libultraship) implements N64-specific primitives without proprietary code
- **Modular game logic** — `src/SM/` for gameplay, `src/cutscenes/` for scripted sequences, with clear separation of concerns
- **Declarative assets** — YAML definitions in `assets/` feed the build pipeline for runtime archives
- **Automated quality assurance** — CI workflows validate every commit across platforms and package for distribution

---

## Frequently Asked Questions

### What programming language is the Lighthouse decompilation written in?

The project is written in **C**, matching the original *Banjo-Kazooie* development approach. Headers use standard C syntax with preprocessor macros for platform adaptability. The build system is CMake, and tooling scripts use Python for asset extraction.

### How does Lighthouse handle original Nintendo 64 hardware calls?

All low-level hardware access routes through **libultraship**, a community replacement for Nintendo's proprietary `ultralib`. This submodule implements RSP vector operations, audio synthesis, and memory management without including copyrighted code. Game logic in `src/` calls these APIs exactly as the original binary did.

### Where is the actual game code located in the repository?

The decompiled gameplay implementation lives in **`src/`**, with subdirectories organized by function: `src/SM/` for core mechanics, `src/cutscenes/` for scripted sequences, `src/emptyLvl/` for debugging, and `src/unused/` for reference material. Each `.c` file typically corresponds to a specific system or level from the original game.

### What files do I need to edit to add a new level?

Start with three locations: create level initialization code in `src/SM/` (following the [`quarrie.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/quarrie.c) pattern), add any required struct definitions to [`include/structs.h`](https://github.com/HarbourMasters/Lighthouse/blob/main/include/structs.h), and define assets in `assets/yaml/us/rev1/` if the level needs new textures or audio. Update [`CMakeLists.txt`](https://github.com/HarbourMasters/Lighthouse/blob/main/CMakeLists.txt) if you introduce new source files that require separate compilation units.