# lighthouse.cfg.json Structure and Parsing in HarbourMasters/Lighthouse: A Complete Guide

> Explore the lighthouse.cfg.json structure and parsing in HarbourMasters/Lighthouse. Learn to access settings with dot-notation via Ship::Context::GetConfig() for easy configuration management.

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

---

**[`lighthouse.cfg.json`](https://github.com/HarbourMasters/Lighthouse/blob/main/lighthouse.cfg.json) is a hierarchical JSON configuration file parsed using nlohmann::json and accessed through `Ship::Context::GetConfig()` with dot-notation keys like `"Window.Backend.Id"`.**

The [`lighthouse.cfg.json`](https://github.com/HarbourMasters/Lighthouse/blob/main/lighthouse.cfg.json) file serves as the primary configuration source for the Lighthouse game engine, controlling window settings, audio backends, and debug features. This article explains the exact file structure and how the engine parses it at startup, based on the HarbourMasters/Lighthouse source code.

## lighthouse.cfg.json File Structure

The configuration file follows a nested object hierarchy where top-level sections group related settings. Each section contains sub-objects that define specific behaviors.

### Top-Level Sections

- **Window** — Graphics backend, resolution, and display options
- **Audio** — Audio driver selection and volume controls
- **Debug** — Internal debugging tools and logging

### Window Configuration

The Window section controls rendering and display parameters. The Backend sub-object is particularly important for cross-platform compatibility.

```json
{
  "Window": {
    "Backend": {
      "Id": 1,
      "Name": "DirectX"
    },
    "Width": 1920,
    "Height": 1080,
    "VSync": true
  }
}

```

**Backend.Id values** determine the graphics API:

| Value | API |
|-------|-----|
| 1 | DirectX |
| 2 | OpenGL |
| 3 | Metal |

### Audio Configuration

The Audio section mirrors the Window structure with its own Backend sub-object.

```json
{
  "Audio": {
    "Backend": {
      "Id": 0,
      "Name": "WASAPI"
    },
    "MasterVolume": 100,
    "Mute": false
  }
}

```

Available audio drivers include **WASAPI**, **SDL**, and **Null** (for silent operation).

### Debug Configuration

```json
{
  "Debug": {
    "EnableDebugOverlay": false,
    "LogLevel": "Info"
  }
}

```

## How lighthouse.cfg.json Is Parsed

### Initialization in Engine.cpp

The parsing begins in [[`src/port/Engine.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Engine.cpp)](https://github.com/HarbourMasters/Lighthouse/blob/develop/src/port/Engine.cpp#L143) during context creation. The engine instantiates `Ship::Context`, which automatically loads and parses [`lighthouse.cfg.json`](https://github.com/HarbourMasters/Lighthouse/blob/main/lighthouse.cfg.json) from the executable's directory.

### Parsing with nlohmann::json

Lighthouse uses the [nlohmann::json](https://github.com/nlohmann/json) library for JSON handling. The parsed document is wrapped by `Ship::Context::GetConfig()`, which provides type-safe accessors using **dot-notation paths**.

### Configuration Access Methods

The configuration wrapper exposes these core methods:

- `GetInt(path, default)` — Retrieve integer values
- `GetString(path, default)` — Retrieve string values
- `SetInt(path, value)` — Modify integer values at runtime
- `SetString(path, value)` — Modify string values at runtime

## Reading Configuration Values

Access parsed values through the context singleton:

```cpp
auto cfg = Ship::Context::GetRawInstance()->GetConfig();

// Read graphics backend with fallback default
int backendId = cfg->GetInt("Window.Backend.Id", 1);
std::string backendName = cfg->GetString("Window.Backend.Name", "DirectX");

// Read resolution settings
int width = cfg->GetInt("Window.Width", 1920);
int height = cfg->GetInt("Window.Height", 1080);
bool vsync = cfg->GetBool("Window.VSync", true);

```

The **second parameter** in each call specifies the default value applied when the key is missing or the file is incomplete. This ensures graceful degradation if [`lighthouse.cfg.json`](https://github.com/HarbourMasters/Lighthouse/blob/main/lighthouse.cfg.json) is corrupted or absent.

## Modifying Configuration at Runtime

The same dot-notation paths support write operations. The Settings UI uses this pattern when users change backends:

```cpp
cfg->SetInt("Window.Backend.Id", static_cast<int>(newBackend));
cfg->SetString("Window.Backend.Name", windowBackendsMap.at(newBackend));

```

Changes persist to disk via `WriteToFile()`:

```cpp
cfg->WriteToFile("lighthouse.cfg.json");

```

This creates or overwrites the JSON file with current in-memory values, ensuring the next launch uses the updated configuration.

## Key Source Files

| File | Purpose |
|------|---------|
| [`src/port/Engine.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Engine.cpp) | Creates context and triggers initial load at line 143 |
| [`README.md`](https://github.com/HarbourMasters/Lighthouse/blob/main/README.md) | Documents editable fields, especially graphics backends |
| [`lighthouse.cfg.json`](https://github.com/HarbourMasters/Lighthouse/blob/main/lighthouse.cfg.json) | Runtime-generated configuration file |

## Summary

- **lighthouse.cfg.json** uses a three-section hierarchy: Window, Audio, and Debug
- **Backend sub-objects** in Window and Audio control API selection through `Id`/`Name` pairs
- **nlohmann::json** handles parsing; `Ship::Context::GetConfig()` provides dot-notation access
- **Default values** ensure startup resilience when keys or files are missing
- **Runtime modifications** via `SetInt`/`SetString` can be persisted with `WriteToFile()`

## Frequently Asked Questions

### What happens if lighthouse.cfg.json is missing or corrupted?

The engine starts with built-in defaults. Every `GetInt`, `GetString`, and `GetBool` call includes a fallback parameter that activates when the requested path cannot be resolved in the JSON document.

### How do I switch from DirectX to OpenGL?

Edit `Window.Backend.Id` to `2` and `Window.Backend.Name` to `"OpenGL"`, then save. The README documents this procedure under the Graphics Backends section. Alternatively, use the in-game Settings UI which modifies these values programmatically.

### Where is the configuration file located?

[`lighthouse.cfg.json`](https://github.com/HarbourMasters/Lighthouse/blob/main/lighthouse.cfg.json) resides in the same directory as the Lighthouse executable. The engine loads it automatically during `Ship::Context` initialization in [[`Engine.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/Engine.cpp)](https://github.com/HarbourMasters/Lighthouse/blob/develop/src/port/Engine.cpp#L143).

### Can I create custom configuration sections?

While the engine only reads known paths like `"Window.Backend.Id"`, nlohmann::json preserves any additional JSON content. Custom keys survive `WriteToFile()` operations, though they won't affect engine behavior unless the source code is modified to access them.