Settings System
Settings System
Status: Designed Author: user + game-designer Last Updated: 2026-03-28 System Index: #21 — Alpha, Polish Layer
Overview
The Settings System manages user preferences — audio volume, display options, and controls. Settings are persisted locally via Godot's ConfigFile to user://settings.cfg. The system provides a UI overlay accessible from the Main Menu and via a pause menu (Escape key) during gameplay. Settings apply immediately without requiring a restart.
Player Fantasy
"The game respects my preferences." Volume too loud? One slider. Want fullscreen? One click. Settings persist between sessions — set once, forget.
Detailed Design
Core Rules
- Settings stored as an autoloaded singleton (
Settings) reading/writinguser://settings.cfg. - Settings UI is a modal overlay — pauses the game when opened during gameplay (client-side only, server continues).
- Changes apply immediately (no "Apply" button needed for V1).
- Default values used if config file is missing or corrupt.
V1 Settings
| Category | Setting | Type | Default | Range |
|---|---|---|---|---|
| Audio | Master Volume | float | 1.0 | 0.0-1.0 |
| Audio | Music Volume | float | 0.7 | 0.0-1.0 |
| Audio | SFX Volume | float | 1.0 | 0.0-1.0 |
| Display | Fullscreen | bool | false | toggle |
| Display | VSync | bool | true | toggle |
| Display | Window Size | enum | 1280x720 | 720p/1080p/1440p |
| Game | Display Name | string | "Player" | 1-20 chars |
| Game | Server Address | string | (default) | IP or hostname |
Settings UI Layout
┌────────────────────────────────────┐
│ SETTINGS [X] │
│ │
│ Audio │
│ Master: [━━━━━━━●━━] 80% │
│ Music: [━━━━━●━━━━] 70% │
│ SFX: [━━━━━━━━━●] 100% │
│ │
│ Display │
│ Fullscreen: [ ] Off │
│ VSync: [✓] On │
│ Resolution: [1280×720 ▼] │
│ │
│ Game │
│ Name: [__________] │
│ Server: [________________] │
│ │
│ [RESET DEFAULTS] │
└────────────────────────────────────┘
Persistence
save_settings():
var config = ConfigFile.new()
config.set_value("audio", "master_volume", master_volume)
config.set_value("audio", "music_volume", music_volume)
config.set_value("audio", "sfx_volume", sfx_volume)
config.set_value("display", "fullscreen", fullscreen)
config.set_value("display", "vsync", vsync)
config.set_value("display", "window_size", window_size)
config.set_value("game", "display_name", display_name)
config.set_value("game", "server_address", server_address)
config.save("user://settings.cfg")
load_settings():
var config = ConfigFile.new()
if config.load("user://settings.cfg") != OK:
return # use defaults
master_volume = config.get_value("audio", "master_volume", 1.0)
# ... etc
Interactions with Other Systems
| System | Direction | Interface |
|---|---|---|
| Audio Manager | Writes to | Volume settings applied to AudioBus volumes |
| Main Menu | Opens overlay | Settings button on main menu |
| All scenes | Opens overlay | Escape key opens pause + settings |
Formulas
None.
Edge Cases
| Case | Resolution |
|---|---|
| Config file corrupt/unreadable | Delete and recreate with defaults. Log warning. |
| Web export: no fullscreen toggle | Use browser fullscreen API instead. Setting may behave differently. |
| Web export: no window size option | Hide resolution setting on web. Browser controls window size. |
| Settings changed during multiplayer | Client-side only. No server impact. |
| Reset defaults | Restore all values to defaults, save immediately. |
Dependencies
Upstream
None — standalone utility system.
Downstream
| System | Dependency Type | Interface |
|---|---|---|
| Audio Manager | Soft | Reads volume settings |
| Main Menu | Soft | Reads display name and server address |
Tuning Knobs
The settings ARE tuning knobs for the player. No meta-tuning needed.
Acceptance Criteria
| # | Criterion | Verification |
|---|---|---|
| 1 | Settings persist between sessions | Integration test: change volume, quit, relaunch, assert volume preserved |
| 2 | Volume sliders affect audio immediately | Audio test: drag slider, assert volume changes in real-time |
| 3 | Fullscreen toggle works | Visual test: toggle fullscreen, assert window mode changes |
| 4 | Escape opens settings during gameplay | Integration test: press Escape in combat, assert settings overlay appears |
| 5 | Reset defaults restores all values | Integration test: change settings, click Reset, assert all defaults |
| 6 | Missing config file uses defaults | Integration test: delete settings.cfg, launch, assert defaults loaded |