Quick answer: Define three or four named quality tiers, detect the device’s tier at first launch by combining RAM, CPU, GPU, and a quick benchmark, save the chosen tier, and let the player override it. Treat “Safe Mode” as a special last-resort tier that prioritizes stability over visuals.
Your game looks beautiful on a modern gaming PC. A player on a five-year-old laptop with integrated graphics tries it, gets 8 FPS, leaves a one-star review, and refunds. The bug is not their hardware — it is your assumption that everyone has the hardware you have. Graceful degradation is the opposite of that assumption: a single build that scales from a flagship machine down to the worst PC your audience owns, and stays playable on both ends.
Why Auto-Detect at All
Players hate fiddling with settings. The vast majority will play whatever your game defaults to. If your default is “Ultra” because you tested on your dev machine, you have just sentenced everyone with a laptop to a bad first impression.
Auto-detection sets a sensible default for the player’s hardware. Done well, it produces a playable experience for 95% of players on first launch, and the remaining 5% can adjust manually. The cost is a few hundred lines of detection code and a willingness to actually test on low-end hardware.
Define Your Tiers First
Before you write any detection code, decide what the tiers actually mean. Each tier is a named bundle of settings, not a single number.
SAFE_MODE:
- Resolution scale: 0.5
- Texture quality: 1/4
- Shadows: off
- Post-processing: off
- Particle density: 0.25
- View distance: 50%
- VFX complexity: minimal
- Audio channels: 16
- Physics quality: minimal
- Target FPS: 30
LOW:
- Resolution scale: 0.75
- Texture quality: 1/2
- Shadows: hard, low resolution
- Post-processing: bloom only
- Particle density: 0.5
- View distance: 75%
- Target FPS: 30
MEDIUM (default for most players):
- Resolution scale: 1.0
- Texture quality: full
- Shadows: PCF, medium res
- Post-processing: standard
- Particle density: 1.0
- Target FPS: 60
HIGH / ULTRA:
- Resolution scale: 1.0+
- Texture quality: full
- Shadows: PCSS, high res
- Post-processing: full pipeline
- Particle density: 1.5
- Target FPS: 60+
The named tiers prevent setting drift. When QA reports “the game runs at 22 FPS on a Steam Deck,” you know exactly which tier they were on and exactly which settings to revisit.
Step 1: Hardware Detection
Combine multiple signals. No single signal is reliable, but together they classify most devices correctly.
public class HardwareTier
{
public static QualityTier Detect()
{
int ramMb = SystemInfo.systemMemorySize;
int cores = SystemInfo.processorCount;
string gpu = SystemInfo.graphicsDeviceName;
int vramMb = SystemInfo.graphicsMemorySize;
// Hard floor: under 4GB RAM goes to Safe Mode
if (ramMb < 4000) return QualityTier.SafeMode;
// Integrated graphics tend to underperform
bool integrated = gpu.Contains("Intel HD") ||
gpu.Contains("Intel UHD") ||
gpu.Contains("Intel Iris") ||
(gpu.Contains("Vega") && vramMb < 2000);
if (integrated && ramMb < 8000) return QualityTier.Low;
if (integrated) return QualityTier.Medium;
// Dedicated GPU with reasonable VRAM
if (vramMb >= 8000 && cores >= 6) return QualityTier.High;
if (vramMb >= 4000) return QualityTier.Medium;
return QualityTier.Low;
}
}
This is heuristic. Run it on every device you can get your hands on and adjust the thresholds based on what actually performs well in your engine. There is no universal table.
Step 2: Microbenchmark
Hardware detection alone misses anomalies. A player with a top-tier GPU but a thermally throttled laptop CPU will fall into the wrong tier. Add a quick benchmark on first launch.
public static IEnumerator RunBenchmark(System.Action<float> onComplete)
{
// Render a known scene for 2 seconds and measure average frame time
yield return new WaitForSeconds(0.5f); // warm-up
float startTime = Time.realtimeSinceStartup;
int frames = 0;
while (Time.realtimeSinceStartup - startTime < 2.0f) {
frames++;
yield return null;
}
float avgFps = frames / 2.0f;
onComplete(avgFps);
}
Run the benchmark in a hidden loading screen. If the measured FPS is below the target for the auto-detected tier, drop one tier. Save the result so the benchmark only runs once.
Step 3: Save and Persist the Choice
Run detection once on first launch and save the result. Subsequent launches use the saved tier unless the player resets it. This avoids running the benchmark every launch and prevents the tier from oscillating between sessions.
Always save under a versioned key. When you ship a graphics update that changes performance characteristics, bump the version, force-rerun detection, and politely tell the player you adjusted their settings.
Step 4: Player Override
Add a Quality dropdown to the settings menu with five options: Auto, Safe Mode, Low, Medium, High, Ultra, Custom. Auto runs the detection. The named tiers apply the bundle directly. Custom unlocks individual sliders.
The override must persist. Never silently re-run auto-detection on a player who has explicitly chosen a tier. Their choice is sacred.
Safe Mode as a Special Tier
Safe Mode is not just “Low with everything turned down.” It is a stability-first profile designed to let a player launch the game even when something is going wrong. It should:
- Use the most conservative renderer (BiRP fallback if your default is HDRP, OpenGL fallback if your default is Vulkan).
- Disable any feature that has historically caused crashes (compute shaders, async loading, GPU instancing).
- Be available from a launcher flag (
--safe-mode) so players can opt in before the game even loads. - Display a banner explaining what is disabled and how to return to normal mode.
Treat Safe Mode as the “run my game so I can play it” mode for players who would otherwise refund.
Verifying Across the Tier Range
Test on at least one device per tier. Steam Hardware Survey and your own analytics tell you which devices your players actually own — buy or borrow representatives from each major bucket. Cloud-based testing services let you run a build on a real low-end machine remotely if you cannot afford the hardware outright.
Add automated FPS reporting to your beta build. When a player runs the game, report the auto-detected tier, the actual FPS achieved, and any crashes. After a few hundred sessions, you will know whether your detection is calibrated correctly.
“The default settings are the only settings 80% of your players will ever see. If the default is wrong for half of them, half of your audience plays a broken game.”
Related Resources
For benchmarking your game across hardware, see how to benchmark your game across hardware tiers. For testing on low-end without owning the hardware, see how to test your game on low-end hardware without owning it. For Steam Deck specifically, see how to test Steam Deck compatibility.
Always include Safe Mode as an option in your launcher, accessible without launching the game. The players who need it most are the ones who cannot get past the title screen.