Skip to content

Game.ClimateRenderSystem

Assembly: Assembly-CSharp (typical for game code; replace with actual assembly if different)
Namespace: Game.Rendering

Type: class

Base: GameSystemBase

Summary:
ClimateRenderSystem is a rendering-level system responsible for driving visual climate effects in Cities: Skylines 2. It coordinates volumetric clouds, precipitation VFX (rain, snow, hail), lightning VFX, wind textures, and a small climate-control Volume that exposes weather-related overrides. The system bridges simulation state (ClimateSystem, SimulationSystem, TimeSystem) with rendering and audio subsystems to produce synchronized weather visuals and sound. It also exposes a small API for scheduling weather prefab transitions and queuing/dispatching lightning strikes for use by other systems or jobs.


Fields

  • private static class VFXIDs
    Static container of Shader.PropertyToID integer IDs used by the precipitation/lightning VFX (CameraPosition, CameraDirection, VolumeScale, WindTexture, CloudsAltitude, MapOffsetScale, RainStrength, SnowStrength, LightningOrigin, LightningTarget). Used to set VFX parameters efficiently.

  • private enum PrecipitationType
    Local enum listing precipitation kinds (Rain, Snow, Hail) used to translate system state to VFX events/names.

  • [StructLayout(LayoutKind.Sequential, Size = 1)] private struct TypeHandle
    Compiler-generated small struct used to assign Entity query handles. Internal plumbing for DOTS/ECS integration.

  • private RenderingSystem m_RenderingSystem
    Reference to the rendering system used to obtain frame timing and camera frame data.

  • private ClimateSystem m_ClimateSystem
    Reference to the simulation climate system (source of precipitation, temperature, hail, etc.).

  • private SimulationSystem m_SimulationSystem
    Reference to the simulation system (used to pause or read sim speed when necessary).

  • private CameraUpdateSystem m_CameraUpdateSystem
    Reference to camera data (position, direction) used to drive VFX uniforms and volumetric cloud behaviour.

  • private PrefabSystem m_PrefabSystem
    Used to resolve prefabs referenced by event entities.

  • private WindTextureSystem m_WindTextureSystem
    Provides the wind texture used by precipitation VFX.

  • private TerrainSystem m_TerrainSystem
    Provides map offset/scale used by VFX (MapOffsetScale).

  • private TimeSystem m_TimeSystem
    Used to compute time-of-year for climate sampling.

  • private AudioManager m_AudioManager
    Used to play lightning SFX.

  • public bool globalEffectTimeStepFromSimulation
    If true, VFX fixed timestep is controlled by simulation time step & simulation speed (applies to VFXManager.fixedTimeStep).

  • public bool weatherEffectTimeStepFromSimulation = true
    If true, precipitation/lightning VisualEffect play rate is scaled according to simulation timestep; otherwise uses 1.

  • private static VisualEffectAsset s_PrecipitationVFXAsset
    Static cached VisualEffectAsset loaded from Resources ("Precipitation/PrecipitationVFX").

  • private VisualEffect m_PrecipitationVFX
    Instanced VisualEffect used to drive precipitation VFX (created at runtime on demand).

  • private static VisualEffectAsset s_LightningVFXAsset
    Static cached VisualEffectAsset loaded from Resources ("Lightning/LightningBolt").

  • private VisualEffect m_LightningVFX
    Instanced VisualEffect used to drive lightning VFX.

  • private Volume m_ClimateControlVolume
    A post-processing/volume object created to host WeatherPropertiesStack components (volumetric clouds, wind, etc).

  • private VolumetricClouds m_VolumetricClouds
    Volume component referencing volumetric cloud settings used and updated by the system.

  • private WindVolumeComponent m_Wind
    Volume component referencing wind configuration.

  • private WindControl m_WindControl
    Instance wrapper providing additional wind control / lifetime handling.

  • private bool m_IsRaining
    Internal flag tracking if rain VFX is currently active.

  • private bool m_IsSnowing
    Internal flag tracking if snow VFX is currently active.

  • private bool m_HailStorm
    Internal flag tracking if hail VFX is currently active.

  • private EntityQuery m_EventQuery
    EntityQuery used to scan for WeatherPhenomenon event entities so the system can instantiate/display associated prefabs as needed.

  • private NativeQueue<LightningStrike> m_LightningStrikeQueue
    Thread-safe queue used by jobs / other systems to enqueue lightning strike requests processed on the main/render thread.

  • private JobHandle m_LightningStrikeDeps
    JobHandle representing dependencies for writers that enqueue lightning strikes (to ensure their producers complete before consumption).

  • private WeatherPropertiesStack m_PropertiesStack
    Container that manages weather override properties stored in the climate control volume; used to interpolate and apply overrideable properties.

  • private readonly List<WeatherPrefab> m_FromWeatherPrefabs = new List<WeatherPrefab>()
    List of weather prefabs representing the current "from" state when interpolating between weather configurations.

  • private readonly List<WeatherPrefab> m_ToWeatherPrefabs = new List<WeatherPrefab>()
    List of weather prefabs representing the target "to" state when interpolating.

  • private bool m_PropertiesChanged
    Flag indicating that scheduled from/to prefab lists changed and SetData should be called before the next interpolation.

  • private TypeHandle __TypeHandle
    Compiler-generated handle used internally to map component types to query handles.

  • private EntityQuery __query_100321765_0
    Compiler-generated EntityQuery used for TimeSettingsData.

  • private EntityQuery __query_100321765_1
    Compiler-generated EntityQuery used for TimeData.

Properties

  • public float precipitationVolumeScale { get; set; } = 30f
    Controls the cubic scale of the precipitation VFX volume in world units. Default is 30. Modding tip: increasing this expands the effective VFX volume (affects particle spawning bounds); decreasing shrinks it.

  • public bool editMode { get; set; }
    When true, interpolation and property application may behave in an editor-friendly way (used by the system to alter behavior in UI/edit contexts).

  • public bool pauseSimulationOnLightning { get; set; }
    When true, triggering LightningStrike will set simulation speed to 0 (pauses simulation) — used to emphasize lightning events.

  • internal WeatherPropertiesStack propertiesStack => m_PropertiesStack
    Internal access to the WeatherPropertiesStack for interrogating or modifying applied overrides.

  • public IReadOnlyList<WeatherPrefab> fromWeatherPrefabs => m_FromWeatherPrefabs
    Read-only view of the scheduled "from" weather prefabs.

  • public IReadOnlyList<WeatherPrefab> toWeatherPrefabs => m_ToWeatherPrefabs
    Read-only view of the scheduled "to" weather prefabs.

  • public bool IsAsync { get; set; }
    Flag indicating whether the system is operating asynchronously (affects some timing choices).

Constructors

  • public ClimateRenderSystem()
    Default constructor. Most initialization occurs in OnCreate (DOTS-style). No parameters; system is created by the world.

Methods

  • private void SetData(WeatherPropertiesStack stack, IReadOnlyList<WeatherPrefab> fromPrefab, IReadOnlyList<WeatherPrefab> toPrefab)
    Collects overrideable properties from the provided weather prefabs and configures the WeatherPropertiesStack appropriately. Distinguishes between immediate overrides and time-based interpolation overrides.

  • public void Clear()
    Clears scheduled from/to weather prefab lists and marks properties changed so SetData is re-run on next update.

  • public void ScheduleFrom(WeatherPrefab prefab)
    Append a WeatherPrefab to the "from" list for interpolation/transition setup.

  • public void ScheduleTo(WeatherPrefab prefab)
    Append a WeatherPrefab to the "to" list for interpolation/transition setup.

  • private float GetTimeOfYear()
    Returns normalized time-of-year used to sample ClimateSystem. If ClimateSystem has an override date it uses that; otherwise it queries TimeSettingsData and TimeData singletons and computes rendering-frame-aligned time-of-year. If absent, returns 0.5.

  • private void UpdateWeather()
    Samples ClimateSystem using time-of-year, ensures SetData has been applied when scheduled lists changed, and advances interpolation in WeatherPropertiesStack using both simulation and rendering time information. Also respects editMode.

  • private void UpdateEffectsState()
    Decides which precipitation VFX events (rain/snow/hail start/stop) should be fired based on m_ClimateSystem.precipitation, hail, and temperature. Maintains m_IsRaining/m_IsSnowing/m_HailStorm internal state.

  • [Preserve] protected override void OnCreate()
    Initializes references to subsystems (ClimateSystem, RenderingSystem, SimulationSystem, CameraUpdateSystem, PrefabSystem, WindTextureSystem, TerrainSystem, TimeSystem, AudioManager), creates the climate-control Volume and WeatherPropertiesStack, obtains/creates VolumetricClouds and Wind volume components, sets up resources and queries, and allocates the lightning queue. Also loads VisualEffectAssets from Resources ("Precipitation/PrecipitationVFX", "Lightning/LightningBolt").

  • private void ResetOverrides()
    Resets volumetric cloud volume overrides to disabled/defaults (helper used during initialization).

  • public NativeQueue<LightningStrike> GetLightningStrikeQueue(out JobHandle dependencies)
    Returns the NativeQueue used for lightning strike requests and outputs the current job dependencies (so producers can add their JobHandle with AddLightningStrikeWriter).

  • [Preserve] protected override void OnUpdate()
    Main update: if there's an active viewer, it updates weather interpolation, volumetric clouds, ensures VFX instances exist, updates precipitation/lighting state and properties, and adjusts VFX speed/playrate. It also iterates event entities, resolves any WeatherPhenomenon prefabs, completes and consumes the lightning queue, and triggers LightningStrike for queued entries.

  • public void AddLightningStrikeWriter(JobHandle jobHandle)
    Registers a producer JobHandle so the system knows dependencies before consuming the m_LightningStrikeQueue. Call this from systems/jobs that enqueue lightning strikes.

  • private void UpdateVolumetricClouds()
    Adjusts volumetric cloud FadeIn settings and render hook depending on camera altitude/direction (makes clouds render correctly above or below camera).

  • [Preserve] protected override void OnDestroy()
    Completes any pending lightning job dependencies, disposes the lightning queue, disposes WindControl and WeatherPropertiesStack, destroys the climate volume, and performs base cleanup.

  • private void CreateDynamicVFXIfNeeded()
    Instantiates a GameObject+VisualEffect for precipitation and lightning at runtime when their VisualEffectAssets are loaded and instances are missing. Ensures a small pool (one instance each) exists.

  • public void LightningStrike(float3 start, float3 target, bool useCloudsAltitude = true)
    Trigger an immediate lightning event. Optionally sets start.y to sit in the cloud volume altitude. If pauseSimulationOnLightning is true, sets simulation speed to 0. Sends VFX event and plays lightning SFX.

  • private bool GetEventName(PrecipitationType type, bool start, out string name)
    Internal helper mapping PrecipitationType + start/stop state to VFX event name strings (e.g., "OnRainStart"/"OnRainStop").

  • private void UpdateEffectState(PrecipitationType type, bool start)
    Uses GetEventName and sends the appropriate event to the precipitation VisualEffect instance to start/stop precipitation.

  • private void UpdateEffectsProperties()
    Syncs VFX uniforms/parameters: camera position/direction, volume scale, wind texture, cloud altitude, map offset/scale, rain/snow strengths from ClimateSystem, etc. Uses SetChecked* helpers to avoid setting null textures or absent VFX.

  • private void UpdateVFXSpeed()
    Adjusts VFXManager.fixedTimeStep or VisualEffect.playRate depending on globalEffectTimeStepFromSimulation and weatherEffectTimeStepFromSimulation to keep VFX time progression consistent with simulation/rendering speeds.

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    Compiler-generated: builds internal queries for TimeSettingsData and TimeData.

  • protected override void OnCreateForCompiler()
    Compiler helper that calls __AssignQueries and assigns TypeHandle handles. Not normally called by mod code.

  • private void __AssignHandles(ref SystemState state)
    Compiler-generated small helper invoked by OnCreateForCompiler to populate handles (present on TypeHandle struct).

Usage Example

using Unity.Mathematics;
using UnityEngine;
using UnityEngine.VFX;

// inside a system/behavior that has a reference to ClimateRenderSystem:
[Preserve]
protected override void OnCreate()
{
    base.OnCreate();

    // Example: tweak precipitation volume and enable edit mode for editor UI previews
    var climate = World.GetOrCreateSystemManaged<Game.Rendering.ClimateRenderSystem>();
    climate.precipitationVolumeScale = 50f;
    climate.editMode = true;

    // Schedule weather prefabs (assuming you have references to WeatherPrefab instances)
    // climate.ScheduleFrom(currentWeatherPrefab);
    // climate.ScheduleTo(targetWeatherPrefab);

    // Trigger a manual lightning strike at runtime:
    float3 start = new float3(100f, 0f, 200f);
    float3 target = new float3(110f, 0f, 210f);
    climate.LightningStrike(start, target);

    // If a job will enqueue lightning, register its JobHandle before the system consumes the queue:
    // JobHandle writerJobHandle = ...;
    // climate.AddLightningStrikeWriter(writerJobHandle);
}

Additional notes and modding tips: - VisualEffectAssets are loaded via Resources at paths "Precipitation/PrecipitationVFX" and "Lightning/LightningBolt". Replace or override those assets in modded Resources or intercept creation if you want custom VFX. - precipitationVolumeScale affects the VFX volume used for particle emission; adjust it to fit your city camera heights. - Use GetLightningStrikeQueue/AddLightningStrikeWriter to enqueue lightning strikes from background jobs safely. Always supply a JobHandle via AddLightningStrikeWriter so the render system completes producers before consuming the queue. - The system manages a Volume (m_ClimateControlVolume) and WeatherPropertiesStack — disposing or destroying that volume externally will break the interpolation pipeline; prefer interacting through the exposed propertiesStack when modifying overrides. - Be cautious when setting globalEffectTimeStepFromSimulation: changing VFXManager.fixedTimeStep affects all VisualEffect playback globally and may have side effects for other systems using VFXManager.