Skip to content

Game Settings

IGameSettingsService owns the standard graphics/display options every game needs in its options menu — graphics quality tier, resolution + fullscreen mode, vsync, and target frame rate — and takes care of the boring, error-prone parts: persisting them across restarts, re-applying them on launch, and protecting the player from a resolution they can't see to undo.

Enable

The service is optional and off by default. In your ServiceConfiguration asset, tick Enable Game Settings Service (under Game Services). It requires the Time Service (on by default), which drives the resolution revert countdown.

Resolve it like any engine service:

using OxHeart.Core.GameSettings.Interfaces;
using OxHeart.Core.ServiceManagement.Service;

var settings = ServiceLocator.Instance.Get<IGameSettingsService>();

Quality, vsync, target frame rate

These apply immediately, persist immediately, and raise SettingsChanged:

settings.SetQualityLevel(3);        // a QualitySettings tier index
settings.SetVSyncCount(1);          // 0 = off, 1, 2
settings.SetTargetFrameRate(60);    // -1 = platform default

settings.SettingsChanged += kind =>
{
    // kind is Quality | Resolution | VSync | TargetFrameRate
    RefreshSettingsUi();
};

Current values are readable any time: settings.QualityLevel, settings.VSyncCount, settings.TargetFrameRate, settings.CurrentResolution, settings.FullScreenMode, settings.AvailableResolutions.

Resolution — the revert/confirm safety

A resolution or fullscreen change can leave the player looking at a black or out-of-range screen with no way to click "cancel". ApplyResolution solves this the way desktop OSes do: it applies the new mode immediately but auto-reverts unless the player confirms within a timeout.

var handle = settings.ApplyResolution(
    width: 2560, height: 1440,
    mode: FullScreenMode.FullScreenWindow,
    refreshRate: new RefreshRate { numerator = 60, denominator = 1 },
    revertTimeout: TimeSpan.FromSeconds(15)); // optional; defaults to the config value

// Drive a "Keep this resolution? Reverting in Ns" dialog:
handle.Countdown += seconds => countdownLabel.text = $"Reverting in {Mathf.CeilToInt(seconds)}s";
handle.Reverted  += () => CloseConfirmDialog();          // fired on timeout OR an explicit Revert()

keepButton.onClick.AddListener(handle.Confirm);          // keep the new resolution
revertButton.onClick.AddListener(handle.Revert);         // go back now

Guarantees:

  • The countdown is real-time. It runs on the Time service's unscaled clock, so it keeps ticking even if your options menu pauses the game with Time.timeScale = 0.
  • An unconfirmed change never survives a restart. If the player quits (or the game crashes) while the confirm dialog is up, the next launch reverts to the last confirmed resolution automatically.
  • Overlapping changes are safe. If you call ApplyResolution again before confirming a previous one, the revert target stays the original confirmed resolution — you can't strand yourself by stacking changes.

Configuration — GameSettingsConfig

Create via Assets → Create → OxHeart → Game Settings Config and place it at Resources/Configs/DefaultGameSettingsConfig. If no asset is present the service uses sensible code defaults, so this is optional.

Field Purpose
Default Quality / VSync / Target Frame Rate / FullScreen Mode Seeded on first run, before anything is saved. Quality -1 keeps the project's current level.
Manage Quality / Resolution / VSync / Target Frame Rate Turn a setting off to make the service ignore it entirely — it won't apply, persist, or overwrite that setting, leaving your game free to own it.
Resolution Revert Seconds Default auto-revert timeout for ApplyResolution when you don't pass one.

Persistence

Settings are stored as a single JSON blob under one PlayerPrefs key (LoLEngine.GameSettings.v1). The key and its fields are a frozen contract — a future engine version that adds a field will migrate the blob rather than reset it, so shipped players keep their settings.

API summary

Member Purpose
SetQualityLevel(int) / QualityLevel Graphics quality tier
SetVSyncCount(int) / VSyncCount VSync (0/1/2)
SetTargetFrameRate(int) / TargetFrameRate Target FPS (-1 = platform default)
ApplyResolution(w, h, mode, refreshRate, revertTimeout?)IResolutionChangeHandle Change resolution with revert/confirm
CurrentResolution / FullScreenMode / AvailableResolutions Read current display state
SettingsChanged (event, GameSettingKind) Raised after a managed setting changes
Save() Force a persistence flush (setters already persist)

Sample

Import the Game Settings sample and open GameSettings.unity. The runtime-built options panel exercises quality, vsync, target FPS, and the resolution revert/confirm countdown. Resolution changes behave differently in the editor Game view than in a standalone player — use a build (or note the Game-view limitations) when smoke-testing that path.