How to Extract Assets from a Banjo-Kazooie ROM Using Lighthouse: A Complete Guide

Lighthouse extracts assets from a Banjo-Kazooie ROM through a five-step pipeline: ROM selection, SHA-1 checksum validation against a known-good whitelist, Companion initialization with O2R archive targeting, binary asset table parsing, and OTR archive generation with embedded manifest.

The GameExtractor class in HarbourMasters/Lighthouse orchestrates the complete asset extraction process. This tool converts Nintendo 64 ROM data into portable OTR (Ocarina of Time Resource) archives that Lighthouse can load at runtime. Whether triggered through the Mod Menu or run programmatically, the pipeline follows identical validation and extraction logic defined in the C++ source.


ROM Selection and File Loading

Asset extraction begins when a user selects a ROM file through Lighthouse's UI or when code invokes the extraction API directly.

The GameExtractor::SelectGameFromUI method receives the file path from interface elements like the Pick File dialog or Mod Menu. This immediately delegates to GameExtractor::LoadRomFromPath, which reads the entire ROM into memory for processing.

// From src/port/Extractor/GameExtractor.cpp#L13-L22
GameExtractor extractor;
extractor.SelectGameFromUI(onComplete);  // UI-driven path
// or
extractor.RunStandalone("path/to/rom.z64");  // Programmatic path

Both entry points converge on the same validation and extraction pipeline.


Checksum Validation Against Known Banjo-Kazooie Versions

Before any asset extraction occurs, Lighthouse verifies the ROM's authenticity through cryptographic hashing.

The Companion::CalculateHash method computes a SHA-1 hash of the complete ROM file. This hash is compared against mGameList, a hard-coded whitelist containing the four officially-released Banjo-Kazooie version hashes. Only matching ROMs proceed to extraction.

// Validation logic from src/port/Extractor/GameExtractor.cpp#L41-L46
if (!Companion::CalculateHash(romData, hash)) {
    return false;  // Hash computation failed
}
// Compare against mGameList whitelist entries

This prevents extraction from modified, corrupted, or incompatible ROM files.


Companion Initialization for O2R Archive Generation

Once validated, the ROM data passes to the Companion singleton class—the core engine for asset parsing and archive creation.

The Companion initializes with three critical parameters:

  • The ROM byte buffer
  • ArchiveType::O2R (Lighthouse's OTR format variant)
  • Destination folder path for the output file

Progress reporting attaches through a reference to total asset count.

// Initialization from src/port/Extractor/GameExtractor.cpp#L52-L57
Companion::Instance = new Companion(
    romData,
    ArchiveType::O2R,
    outputFolder,
    &totalAssetCount
);

Binary Asset Extraction and OTR Archive Writing

The actual extraction executes through Companion::Init with ExportType::Binary.

This method performs three operations:

  1. Parses ROM asset tables—traverses Banjo-Kazooie's internal data structures to locate models, textures, audio, and other resources
  2. Reads raw asset bytes—extracts each resource's complete binary data
  3. Writes OTR archive—packages assets into a single file with a manifest mapping identifiers to original ROM locations
// Extraction call from src/port/Extractor/GameExtractor.cpp#L60-L66
Companion::Instance->Init(ExportType::Binary);
// Parses tables, extracts assets, writes OTR with manifest

The resulting archive is self-contained and portable across Lighthouse installations.


Cleanup, Result Storage, and UI Completion

After successful extraction, the pipeline finalizes output handling and resource cleanup.

The GetOutputPath method retrieves the generated file location, stored in the static variable sLastOutputPath for external access. The Companion singleton destroys itself automatically, and the UI callback receives completion status.

// Cleanup sequence from src/port/Extractor/GameExtractor.cpp#L73-L81
sLastOutputPath = Companion::Instance->GetOutputPath();
delete Companion::Instance;
Companion::Instance = nullptr;
// UI callback fired with success status

The generated OTR file can now load directly into Lighthouse or serve as a source for language-pack modifications.


Code Examples: Extraction Patterns

Stand-Alone Extraction

For automated pipelines or command-line tools:

#include "port/Extractor/GameExtractor.h"

int main() {
    GameExtractor extractor;
    if (!extractor.RunStandalone("C:/Games/BanjoKazooie.z64")) {
        return 1;  // Extraction failed—invalid ROM or I/O error
    }
    // Success: sLastOutputPath contains the generated OTR location
    std::string output = GameExtractor::sLastOutputPath;
    return 0;
}

UI-Driven Extraction

For integration with Lighthouse's Mod Menu interface:

// Inside LighthouseModMenuWindow.cpp
auto onComplete = [&](bool success) {
    if (success) {
        // Display extracted asset via Companion::Instance->GetCurrentAssetName()
    } else {
        // Present error dialog to user
    }
};

GameExtractor extractor;
extractor.SelectGameFromUI(onComplete);

Both patterns execute identical validation and extraction logic.


Key Source Files and Architecture

Understanding the complete pipeline requires familiarity with these implementation files:


Summary

  • ROM selection triggers through SelectGameFromUI or RunStandalone, both calling LoadRomFromPath
  • SHA-1 validation against mGameList whitelist ensures only authentic Banjo-Kazooie versions extract
  • Companion singleton manages O2R archive creation with ROM data, output folder, and progress tracking
  • Binary export mode parses asset tables and writes OTR files with location-to-identifier manifest
  • Result access via static sLastOutputPath enables downstream consumers to locate generated archives

Frequently Asked Questions

What ROM formats does Lighthouse support for Banjo-Kazooie extraction?

Lighthouse accepts standard Nintendo 64 ROM files with .z64 or compatible extensions. The critical requirement is SHA-1 hash matching against the internal whitelist—file extension alone does not determine compatibility. ROMs must be unmodified releases from the four known commercial versions.

Can I extract assets from a modified or hacked Banjo-Kazooie ROM?

No. The mGameList whitelist explicitly rejects unknown hashes. This design prevents extraction from corrupted files, fan translations, or hack ROMs that might contain incompatible asset table structures. You must use an original, unmodified commercial release.

What is the difference between O2R and standard OTR archives?

O2R (Ocarina of Time Resource variant) is Lighthouse's specialized archive format. While structurally similar to OTR archives used by other decompilation projects, O2R specifically targets Banjo-Kazooie's asset organization and may include format adaptations for that game's data structures. The Companion class abstracts these differences through the ArchiveType::O2R enumeration.

Where does Lighthouse save the extracted OTR file?

The output location derives from the destination folder passed during Companion initialization and the original ROM's identifying information. The final path is accessible through GameExtractor::sLastOutputPath after extraction completes. When run through the UI, this path typically resides in a user-configurable assets directory.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →