# How Lighthouse Resolves Mod Loading Priority Conflicts: Alphabetical Order Wins

> Discover how Lighthouse resolves mod loading priority conflicts. Learn how alphabetical order ensures correct asset loading and prevents overwrites, keeping your game stable.

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

---

**Lighthouse resolves mod conflicts by loading files alphabetically, with later entries overwriting earlier ones—meaning `Z_Mod.o2r` always beats `A_Mod.o2r` when both define the same asset.**

Lighthouse, the modding framework behind the HarbourMasters game ports, uses a deterministic conflict resolution system that requires no user configuration. Understanding this priority mechanism helps mod creators predict override behavior and lets players control which assets display without editing configuration files. The entire system relies on simple filesystem ordering rather than manifest files or priority flags.

## How the Mod Loading Pipeline Works

When Lighthouse boots, it executes a four-phase pipeline in the resource loader (implemented in [`src/port/Resource/GfxBridge.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Resource/GfxBridge.c) and surrounding boot code):

### Phase 1: Recursive Folder Scan

The engine walks the `mods` directory recursively, collecting every `.o2r` and `.otr` file. Subdirectories are fully traversed, meaning `mods/subfolder/MyMod.o2r` participates in the same priority queue as root-level files.

### Phase 2: Lexicographical Sort

All discovered paths are sorted alphabetically using standard string comparison (`strcmp`). This sort is case-sensitive on most platforms, so `Z_mod.o2r` precedes `a_mod.o2r`. The full path string determines order, so directory nesting affects priority—`mods/Alpha/Mod.o2r` sorts before `mods/Beta/Mod.o2r`.

### Phase 3: Sequential Bundle Loading

Each mod file loads in the sorted order, unpacking its assets into memory structures.

### Phase 4: Overwrite-on-Conflict Merge

Assets feed into global lookup tables. When an incoming asset's internal OTR/O2R identifier matches an existing entry, the new asset replaces the old unconditionally.

The last mod alphabetically holding a given asset ID always wins the conflict.

## Concrete Code Example

The loading logic in [`src/port/Resource/GfxBridge.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Resource/GfxBridge.c) follows this pattern (simplified for clarity):

```c
/* Representative logic from the boot sequence */
char **mod_paths = scan_mod_folder("mods");          // collect all .o2r/.otr
qsort(mod_paths, count, sizeof(char*), strcmp);     // alphabetical ordering

for (int i = 0; i < count; ++i) {
    AssetBundle *bundle = load_o2r_or_otr(mod_paths[i]);
    merge_into_global_tables(bundle);                // later entries win
}

```

Consider this file structure:

```

mods/
├── EarlyPack.o2r      // defines texture 0x04001200 = "Original logo"
├── Subfolder/
│   └── LatePack.o2r   // defines texture 0x04001200 = "Custom logo"
└── ZZZ_Override.o2r   // defines texture 0x04001200 = "Final logo"

```

Loading order becomes:
1. `EarlyPack.o2r`
2. `Subfolder/LatePack.o2r`
3. `ZZZ_Override.o2r` ← **wins**

The player sees "Final logo" regardless of when mods were installed.

## Language Pack Special Case

Language packs reside in `mods/~lang/` and follow identical rules. The `~` prefix ensures this directory sorts early, isolating language assets from gameplay mods. Within `~lang/`, alphabetical order still governs which pack active for each language code.

As documented in `docs/modding/LANGUAGE PACKS.md`, the language selector UI filters to one pack per language, but the underlying loading mechanism uses the same overwrite behavior—if multiple `es-ES` packs exist, the alphabetically last one populates the Spanish text tables.

## Key Source Files for Mod Loading Priority

| File | Relevance |
|------|-----------|
| [`src/port/Resource/GfxBridge.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Resource/GfxBridge.c) | OTR texture loading; asset table insertion with overwrite semantics |
| [`include/overlays.h`](https://github.com/HarbourMasters/Lighthouse/blob/main/include/overlays.h) | Overlay table declarations receiving mod assets |
| [`README.md`](https://github.com/HarbourMasters/Lighthouse/blob/main/README.md) (lines 84–86) | Documents the `mods/` folder auto-loading behavior |
| `docs/modding/LANGUAGE PACKS.md` | `mods/~lang/` subdirectory rules |

## Practical Control Strategies

Mod creators and players can exploit alphabetical ordering without code changes:

- **Prefix with numbers**: `01_Base.o2r`, `99_Final.o2r`
- **Use directory depth**: `mods/0-Early/` vs. `mods/9-Late/`
- **Timestamp in filename**: `mods/Pack_2024-01-15.o2r`

Because Lighthouse provides no explicit priority metadata, filename engineering becomes the sole conflict resolution tool.

## Summary

- Lighthouse scans `mods/` recursively and sorts all `.o2r`/`.otr` files alphabetically by full path
- Assets load sequentially; later files overwrite earlier ones on identifier collision
- No configuration files or manifest declarations control priority—only filesystem naming
- Language packs in `mods/~lang/` follow identical rules with UI filtering per language
- Mod creators control override order through strategic filename and directory naming

## Frequently Asked Questions

### Can I set explicit loading priority numbers instead of using alphabetical order?

No. Lighthouse has no priority metadata system—alphabetical sorting is hardcoded in the resource loader. The `qsort` with `strcmp` in [`src/port/Resource/GfxBridge.c`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Resource/GfxBridge.c) is the sole ordering mechanism. You must rename files or reorganize directories to achieve desired load order.

### Does subdirectory nesting affect loading priority?

Yes. The full path string participates in alphabetical comparison, so `mods/A/Mod.o2r` loads before `mods/B/Mod.o2r`. Deep nesting can be used strategically to group mods by priority tier (e.g., `mods/0-Foundation/`, `mods/5-Gameplay/`, `mods/9-Polish/`).

### What happens if two mods modify the same texture but I want both effects combined?

Lighthouse does not merge asset contents—complete replacement occurs. To combine modifications, you must manually merge the assets into a single file using external tools, then name that file to load last. The engine has no partial-override or patch-layering capability.

### Are there platform differences in alphabetical sorting?

Case sensitivity depends on the host platform's filesystem and C library `strcmp` implementation. On case-sensitive systems (Linux, macOS APFS), `Z` precedes `a`. For cross-platform consistency, use consistent casing and numeric prefixes rather than relying on letter case for ordering.