On this page
Tune and ship

Performance

What CCDS exposes to the player, what each option costs, and where frame time actually goes in a driving game.

The player-facing options

Seven graphics settings, all persisted per player and all changeable at runtime.

Setting Range Shipped default Cost when raised
Shadows on/off false High — an extra render pass over the city
Shadow resolution 0–3 0 (Low) High — memory and fill rate
Soft shadows on/off false Moderate — extra filtering
Max realtime lights 0–16 0 High — per-light cost on every affected object
Draw distance 500–5000 m 700 High — more geometry per frame
Antialiasing 0–2 0 (None) Low (FXAA) to moderate (SMAA)
Image effects on/off false Moderate to high, depends on the volume profile
C#
CCDS.SetShadows(true);
CCDS.SetShadowResolution(2);     // 0 Low, 1 Medium, 2 High, 3 Very High
CCDS.SetSoftShadows(true);
CCDS.SetMaxRealtimeLights(4);
CCDS.SetDrawDistance(2000f);
CCDS.SetAntialiasingMode(1);     // 0 None, 1 FXAA, 2 SMAA
CCDS.SetImageEffects(true);

Each setter persists and raises CCDS_Events.OnQualityChanged. Hook that if your own systems need to react.

The shipped defaults are a low-end baseline, not a recommendation. A desktop title should ship higher starting values; edit the default* fields in CCDS_Settings.asset — see Settings Reference.

URP quality tiers

Four pipeline assets in Assets/CCDS/URP/:

Asset Tier
CCDS_Low.asset Low
CCDS_Med.asset Medium
CCDS_High.asset High
CCDS_Ultra.asset Ultra

CCDS_Renderer.asset is the renderer they share. Camera post-processing profiles: CCDS_CameraProfile_Default, _Day, _Day_MM, _Night.

Wire the tiers to Unity's Quality levels in Project Settings → Quality. CCDS's own settings adjust values within the active tier; they do not switch tiers for you.

The biggest costs in a city driving game

In rough order of impact:

Cost Why it dominates What to do
Traffic vehicle count Every traffic car is a physics body with wheel colliders Lower traffic density
Draw distance A city has a lot of geometry; 5000 m draws nearly all of it Keep it as low as the game allows, use LODs and fog
Realtime lights + shadows Multiplied by every affected renderer Bake lighting; keep realtime lights for the player's vehicle
WheelCollider count Physics cost scales with active vehicles Cap concurrent AI and traffic
Draw calls Many small props defeat batching Static-batch the city, atlas materials

Traffic density is the single most effective dial, and it is already player-facing:

C#
CCDS.SetTrafficDensity(0.5f);          // 0–2, 1.0 = 100%
CCDS.DisableTrafficForAWhile();        // temporary, e.g. during a race
CCDS.ToggleTrafficPermanently(false);  // until re-enabled

Lighting

Bake it. A city lit in realtime will not hold frame rate on any platform.

  • Bake lightmaps for static geometry, and keep realtime lights for vehicles and dynamic effects.
  • Re-bake after any geometry change — stale lighting data does not warn you.
  • Re-bake reflection probes alongside, for the same reason.
  • overrideLightmapTextures caps lightmaps at 1024 with crunch compression at build time. It trades bake quality for download size; leave it on for mobile.

Optional URP features degrade silently

If a URP feature's resources are stripped from a project — SSAO is the usual case — URP can log an error every frame. CCDS force-disables the feature and logs a single warning instead.

The implementation is in CCDS_UI_Options (ApplySSAOEnabled / IsSSAOResourceAvailable) and is fully reflection-based, so URP API changes degrade to "unavailable" rather than breaking compilation.

If you add optional renderer features of your own, follow the same pattern. A per-frame error log is itself a performance problem.

Measuring

Use the Unity Profiler, not frame-rate impressions.

Profiler area Look for
CPU → Rendering Draw call and batch counts
CPU → Physics Cost scaling with vehicle count
CPU → Scripts Per-frame allocations
GPU Shadow and post-processing passes
Memory Texture and lightmap footprint

CCDS's own F12 debug panel includes a performance module for a quick in-game read, but it is not a substitute for the Profiler. It is also off in release builds — see Build and Deploy.

Profile in a build, not in the editor. Editor overhead is large enough to hide and to invent problems.

Writing performant CCDS code

  • Cache component lookups. ACCDS_Component and ACCDS_Vehicle already cache the common ones.
  • Use TryGetComponent(out var x) instead of a null-checked GetComponent.
  • Use FindAnyObjectByType<T>() / FindObjectsByType<T>(); the legacy find APIs are deprecated in Unity 6.
  • Keep LINQ out of per-frame code.
  • Subscribe to CCDS_Events instead of polling state in Update.
  • Gate verbose logging behind CCDS.DebugLog, which respects enableDebugMessages.

Mobile

Concern Guidance
Colour space Gamma. autoSetColorSpacePerPlatform handles it at build time.
Traffic Lower the default density
Shadows Off, or Low resolution only
Realtime lights 0
Draw distance Near the 500 m floor
Lightmaps Enable overrideLightmapTextures
Post-processing Off by default

Next

(c) 2014 - 2026 BoneCracker Games - City Car Driving Simulator 1.6Back to top ↑
Document details

Generated from: 03_Tune_And_Ship/02_Performance.md
Date: 2026-09-15 07:52
(c) 2014 - 2026 BoneCracker Games - City Car Driving Simulator 1.6