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
ApplyResolutionagain 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.