How to Create and Pack Custom .o2r/.otr Files for Lighthouse: A Complete Guide
Lighthouse loads custom assets from .o2r (standard-definition) or .otr (high-definition) archives placed in the mods folder, which are created using the external Torch and Retro tools to export, edit, and re-import game assets.
Creating custom asset packs for HarbourMasters/Lighthouse enables developers to add new languages, replace textures, modify fonts, or inject entirely new content into the game. The build pipeline relies on two external tools: Torch for standard-definition .o2r archives and Retro for high-definition .otr counterparts. This guide walks through the complete workflow used by the Lighthouse development team.
Prerequisites and Tool Setup
Before creating custom .o2r or .otr files, ensure you have the required tools installed:
- Torch – The asset export/import tool that extracts ROM contents into editable YAML and repacks them into archives
- Retro – The standalone OTR/O2R generation tool for creating HD asset packs
- A base ROM file (US v1.0 recommended for compatibility)
These tools are referenced in the project's README.md and invoked during CI builds via CMakeLists.txt.
Stage 1: Export Original ROM Assets with Torch
The first step to create custom .o2r files is extracting the original game assets into an editable format.
Torch parses the base ROM and outputs:
- Individual asset files organized by type
- A
modding.ymlconfiguration file controlling the build process - YAML representations of text, textures, and other game data
Run the export command:
torch modding export baserom.us.v10.z64 -s lighthouse -d workdir
Key parameters:
baserom.us.v10.z64– Your source ROM file-s lighthouse– Specifies the game target-d workdir– Destination directory for extracted assets
The resulting workdir contains a src/ directory with all editable assets and the critical modding.yml manifest.
Stage 2: Edit Assets and Configure Pack Metadata
With assets exported, modify the YAML files to implement your changes. Common modifications include:
- Text translation – Edit dialog files in
workdir/src/assets/lang/<region>/dialog/*.yaml - Sprite replacement – Update texture references and binary data
- New asset injection – Add entirely new files following the existing naming conventions
For language packs specifically, create a langinfo.yml file describing your new language:
cat > workdir/src/assets/langinfo.yml <<EOF
region: es
langinfo:
- { name: Español, index: 0, script: 0 }
EOF
Then enable pack mode in modding.yml by adding:
config:
dialog_pack: true
output:
binary: bkes.o2r
The dialog_pack: true flag tells Torch this is a language pack that should be registered in the in-game language menu. The output.binary field names your final .o2r file.
Stage 3: Import Edited Assets into .o2r Archive
Once editing is complete, rebuild the archive:
torch modding import o2r baserom.us.v10.z64 -s lighthouse -d workdir
Torch re-encodes all YAML files into binary game formats and packages them into bkes.o2r (or your configured output name). The tool validates asset integrity against the original ROM structure during this process.
Stage 4: Build HD Assets with Retro (Optional)
For high-resolution texture and font support, generate a companion .otr file using the Retro tool:
retro pack workdir bkes.otr
Retro reads the same source directory but outputs assets under alt/assets/ inside the archive. When an HD texture pack is active, Lighthouse searches the alt/ subtree first and falls back to SD data for any missing assets.
This separation allows players to enable or disable HD content independently without affecting the underlying game logic or text data store in the .o2r file.
Stage 5: Install and Load Custom Packs
Place the generated archives in the appropriate mods subdirectory:
<game_root>/mods/~lang/bkes.o2r # language pack
<game_root>/mods/~lang/bkes.otr # optional HD assets
Pack categories use the ~<type>/ naming convention:
~lang/– Language and dialog packs- Other
~<type>/folders for gameplay mods, texture replacements, etc.
According to the source code in [src/port/UI/LighthouseModMenuWindow.cpp](https://github.com/HarbourMasters/Lighthouse/blob/develop/src/port/UI/LighthouseModMenuWindow.cpp#L165), the Mod-Menu UI automatically scans for files ending in .o2r and registers them for player selection.
Complete Workflow Reference
# Full pipeline from export to installation
# 1. Export base assets
torch modding export baserom.us.v10.z64 -s lighthouse -d workdir
# 2. Edit files in workdir/src/...
# 3. Configure modding.yml and create langinfo.yml if needed
# 4. Build SD archive
torch modding import o2r baserom.us.v10.z64 -s lighthouse -d workdir
# 5. Build optional HD archive
retro pack workdir bkes.otr
# 6. Install to game directory
mkdir -p "$GAME_ROOT/mods/~lang"
cp workdir/bkes.o2r "$GAME_ROOT/mods/~lang/"
cp bkes.otr "$GAME_ROOT/mods/~lang/" # optional
Summary
- Torch handles the
.o2rpipeline:export→ edit →import - Retro generates
.otrHD companions from the same source directory - Language packs require
langinfo.ymlanddialog_pack: trueinmodding.yml - Archives belong in
mods/~<type>/subdirectories for automatic discovery - The Mod-Menu UI scans
*.o2rfiles per the implementation inLighthouseModMenuWindow.cpp
Frequently Asked Questions
What is the difference between .o2r and .otr files?
.o2r files contain standard-definition assets processed by Torch — text, sprites, game logic, and base textures. .otr files are high-definition counterparts generated by Retro, holding alt/assets/ with upgraded textures and fonts. Lighthouse checks .otr first when HD packs are enabled, falling back to .o2r for any missing assets.
Can I create asset packs without the original ROM?
No. Both Torch export and import operations require the base ROM for validation and proper asset encoding. The ROM provides the original compression schemes, pointer tables, and structural templates that Torch uses to ensure modified assets load correctly in-game.
How does Lighthouse detect and load custom packs?
The Mod-Menu UI implementation in src/port/UI/LighthouseModMenuWindow.cpp iterates through the mods directory, identifies files with the .o2r extension, and populates the in-game selection interface. Packs are categorized by their parent folder name (~lang, ~texture, etc.) and become selectable without manual configuration file edits.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →