Weather System
Overview
A drop-in weather system for any Roblox game. 6 themed presets (Clear, Rain, Storm, Snow, Fog, Sandstorm) with smooth crossfading transitions between them. Camera-anchored particles always fall around the player wherever they walk. Ambient looping audio crossfades on weather change. Dynamic lightning during storms with delayed thunderclaps that simulate speed-of-sound distance. Weighted random auto-cycle with min/max durations. Auto-detection of CoreShun Day/Night Cycle for phase-aware storm probability and zero-conflict coexistence. Optional on-screen widget showing current weather. Full buyer hooks for wiring game logic to weather events.
Set
StartingWeather and the system handles the rest. Drop-in, done.Open source. Plain Luau. No obfuscation. Edit any file.
The 6 Presets
Each ships with
- ParticleEmitter config — color, size, lifetime, speed, spread, acceleration, all configurable
- Looping ambient sound — SoundId, volume, pitch (DEFAULTS EMPTY — buyer adds their own audio from Studio Toolbox; pcall'd Sound
lay() silently no-ops on empty/invalid ids so zero errors out of box)
- Lighting deltas — additive fog adjustments, brightness offsets, atmosphere shifts
- ColorCorrection layer — brightness/contrast/saturation/tint applied to its own CC instance
- Lightning toggle — only Storm has it on by default
Built-in weather types
- Clear — no precipitation, no sound, neutral lighting
- Rain — soft vertical rain streaks, mild blue tint, modest fog boost
- Storm — heavy rain + LIGHTNING flashes + delayed thunderclaps, dark + oppressive, dense fog
- Snow — slow drifting flakes, cool desaturated tint, modest white fog
- Fog — native Roblox atmospheric haze (Atmosphere.Density + Haze 6.0), no particles, real obscured-distance visibility
- Sandstorm — native warm-orange atmospheric haze (Atmosphere.Haze 5.5 + orange Color/Decay), no particles, real "blowing dust" feel
Smooth Transitions
- Particle crossfade — old emitter ramps to zero while new one ramps up, simultaneously
- Sound crossfade — TweenService volume tweens for both sounds, fade duration configurable
- Lighting interpolation — fog, brightness, color correction all lerp linearly between presets
- Configurable duration — 5s default for a cinematic feel; 0s for hard cut; 30s for very gradual
- Per-call override — pass transitionSec to SetWeather to use a custom duration for one transition
Lightning
Only fires during weather presets with
LightningEnabled = true (just Storm by default).- Random intervals — default 4-12 seconds between strikes; configurable (~5-10 strikes per minute during storms)
- Screen flash via dedicated
CoreShunWeather_LightningCCColorCorrection (stacks with other CCs natively, no conflicts) - Delayed thunderclap — 0.4-4.0s random delay simulates speed-of-sound distance to the strike
- Volume variance — quieter = more distant; configurable min/max
- Pitch variance — slight pitch randomization per strike for realism
- Suppressed during transition-in — won't strike during the first half of a Storm fade-in (avoids jarring "lightning the moment storm starts")
- OnLightningStrike hook — fires per strike with intensity value; trigger screen shake, flicker world lights, scare NPCs
Weighted Auto-Cycle
- Probability table — per-weather weight, normalized at pick time
- Set weight to 0 to never auto-pick a weather (you can still manually SetWeather)
- Random duration — min/max duration per hold, defaults 3-8 minutes
- Anti-repeat option — never picks the same weather twice in a row
- Pause / Resume — freeze the cycle for cutscenes, resume later
- Force next cycle — skip to the next auto-pick immediately via
_G.CoreShunWeather_ForceNextCycle()
Day/Night Cycle Integration
If you have CoreShun Day/Night Cycle installed (any version), Weather auto-detects it at boot:
- Reads phase via
_G.CoreShunDayNight_GetPhase()and applies per-phase probability multipliers - Default biasing — storms 2.5× more likely at Night, fog 1.5× more likely at Dusk, sandstorms 1.5× more likely at Day, etc. All configurable.
- Defers Fog + Atmosphere to Day/Night by default — no race condition, no flicker
- Still applies own ColorCorrection — stacks natively with Day/Night's CC for combined effect (stormy + dusk = cinematic)
- Zero changes needed to Day/Night v1.0 — fully forward-compatible
- ForceFogOverride flag — set
Config.DayNight.ForceFogOverride = trueto let Weather write to Lighting.Fog + Atmosphere ANYWAY during Fog / Sandstorm weather (true atmospheric haze even with Day/Night integrated). Default off for clean coexistence. - Opt-out flag — set
Config.DayNight.IntegrateWithDayNight = falseto manage Fog + Atmosphere directly without coexistence
Camera-Anchored 3D Volumetric Particles
- Always around the player — 3D emitter column (80 studs tall) follows the camera every Heartbeat
- Particles spawn in 3D space — above, at eye level, and around the camera — so weather is visible at every camera angle / zoom (not just hanging above the player)
- Configurable height — particles spawn at and above the player; the emit column's ceiling sits HeightAboveCamera studs above the camera
- Configurable spread — emit radius around the player
- No zones to author — works in any game, any map, any geometry
- Performance-tunable — Particles.GlobalRateMultiplier scales rate down for low-end mobile
- Re-binds on camera change — works with custom camera systems
Optional Widget
- 3 display formats —
"icon"(just dot),"name"(just text),"both"(icon + text) - Phase-tinted icon — colored dot matches the current weather's IconColor (yellow Clear, blue Rain, purple Storm, etc.)
- Pure scale sizing — UDim2.fromScale + Min/Max pixel clamps, looks identical on every device
- Mobile auto-position — relocates on phone-only devices to avoid Roblox jump button
- Configurable everything — position, anchor, size, font, colors, border, corner radius
- Disable in one line —
Config.Widget.Show = false
Buyer Hooks
Define handlers in
Config.Hooks (preferred) OR set on _G.CoreShunWeather_OnXxx at runtime. Hooks are pcall'd in task.spawn'd coroutines — a buggy hook can't crash the system.OnWeatherChange(prevWeather, newWeather)— fires at the START of every transition. Spawn enemies, swap music, mute outdoor radios.OnTransitionComplete(weather)— fires when fade settles. Useful for state-machine games that wait for "fully in weather X".OnLightningStrike(intensity)— fires per Storm flash. Trigger screen shake, flicker world lights, scare NPCs.
Runtime API (
_G Hooks)Reading:
_G.CoreShunWeather_GetWeather()— current weather name_G.CoreShunWeather_GetPreviousWeather()— previous, or nil if settled_G.CoreShunWeather_GetIntensity()— 0..1 transition progress_G.CoreShunWeather_GetTimeRemaining()— seconds until next auto-pick_G.CoreShunWeather_IsCyclePaused()— boolean_G.CoreShunWeather_IsTransitioning()— boolean
Controlling (server-side):
_G.CoreShunWeather_SetWeather(name, transitionSec?)— manual override_G.CoreShunWeather_PauseCycle()— freeze the cycle_G.CoreShunWeather_ResumeCycle()— unfreeze_G.CoreShunWeather_ForceNextCycle()— skip to next pick now
Custom Presets
Adding your own weather takes ~15 lines.
Open
WeatherPresets.lua and append a new entry with Particle, Sound, Lighting, ColorCorrection sub-tables. Then add a Probability weight in WeatherConfig.Cycle.Probability. That's it — the system picks it up at next boot.Defensive Design
- Pcall everything external — Lighting writes, Atmosphere mutations, Sound
lay, hook invocations, time API
- Bounded state — emitters and sounds clean up after transitions; no leaks
- Lerped interpolation — all numeric and Color3 deltas blended smoothly between presets
- Graceful boot — if Config or Presets fail to load, script no-ops with a clear warn (doesn't crash)
- Graceful asset failures — invalid SoundIds, malformed particle configs all caught silently
- Hook isolation — buyer hooks task.spawn'd and pcall'd; a buggy hook only logs a warn
- No assumptions — every config field has a sensible default
Replication
- Attributes-based — server writes 4 attributes on
ReplicatedStorage.CoreShunWeather_State(Weather, WeatherFrom, Intensity, TransitionDuration) - Auto-replicates — Roblox replicates attribute changes to all clients automatically
- Client reads directly — no RemoteEvent for state, no drift
- One RemoteEvent — only used for per-strike lightning broadcasts (intensity + delay + pitch)
- Server-authoritative — same weather for all players in a server
What's Included
- CoreShunWeatherSystem.rbxmx — drop into Workspace + run installer
- WeatherConfig.lua — single config ModuleScript (the only file you edit)
- WeatherPresets.lua — 6 weather presets (extensible)
- WeatherServer.lua — state machine, cycle, lightning, replication
- WeatherClient.lua — particles, sound, lightning visuals, widget
- Installer.lua — one-click command bar installer
- Manual.pdf — comprehensive feature guide with examples
- Cheatsheet.pdf — visual quick-reference
- README.txt — setup + reference
- Rojo project — for active development
Easy Installation
- Drag
CoreShunWeatherSystem.rbxmxinto your place - Open the Studio Command Bar
- Run
require(workspace.CoreShunWeatherSystem.Installer) - Open
WeatherConfigin ReplicatedStorage and customize (or skip — defaults work) - Press F5 — weather auto-cycles, storms trigger lightning, widget appears top-right
Frequently Asked
Can I have a permanent storm?
Yes.
Config.Cycle.Enabled = false and Theme.StartingWeather = "Storm". Or _G.CoreShunWeather_PauseCycle() + _G.CoreShunWeather_SetWeather("Storm") at runtime.Does this work with CoreShun Day/Night Cycle?
Yes — auto-detected at boot. Coexistence mode is enabled by default: Weather reads the phase for probability bias and defers Fog + Atmosphere to Day/Night. Zero conflicts. Day/Night v1.0 needs no updates.
Will Weather slow my game?
Server: minimal (20Hz tick + occasional weather pick). Client: ~5500 particles in flight at storm peak, distributed across a 3D volumetric emitter. Modern devices handle this easily. Pcall overhead is microseconds. Use
GlobalRateMultiplier to scale particles down for low-end mobile.Can I have per-region weather?
Not in v1 — Weather is server-wide. Per-region weather is on the roadmap. For now, you can manually
SetWeather based on player position in your own scripts and skip the auto-cycle.How do I disable a weather type entirely?
Set its
Probability to 0 in Config. It can still be picked manually via SetWeather, just won't auto-cycle to it.How do I add my own weather?
Open
WeatherPresets.lua, append a new preset table, add a probability weight in Cycle.Probability. ~15 lines total.Particles aren't showing — why?
Check (1) Particles.Enabled = true, (2) the WeatherClient LocalScript is in StarterPlayerScripts, (3) you're in play mode (not edit). If you're indoors, the building above blocks the camera-anchored emitter — that's intentional.
Lightning fires too often / too rarely.
Adjust
Lightning.MinIntervalSeconds + MaxIntervalSeconds. Default 4-12s gives ~5-10 strikes per minute during storms.Open source?
Fully. Plain Luau, no obfuscation. Edit any file.
Pairs Well With
- CoreShun Day/Night Cycle — auto-detected at boot for phase-aware storm probability. Completes the "world ambience" trio with Music Player.
- CoreShun Quest System — gate weather-themed quests via
_G.CoreShunWeather_GetWeather()in CanAccept predicates. - CoreShun Toast — fire a notification on OnWeatherChange ("A storm is coming...") for player immersion.
- CoreShun Music Player — swap to a stormier playlist on OnWeatherChange.
More Tools by coreshun
- In-Game Systems — Day & Night Cycle, Quest System, Settings Menu, Music Player, Simple Music Player, Daily Rewards, Loading Screen, Advanced Chat System, Toast, Anti-Exploit, AutoRejoin, Codes Redemption, Crash & Error Reporter
- Studio Plugins — Color Picker, UI Wireframe, Gamepass Manager, TODO Tracker (free)
- Bundles — up to 45% off
Support
Discord: discord.com/invite/hdB5tadkk8
$5.99 · 6 themed presets · Smooth transitions · Lightning + thunder · Day/Night integration · Buyer hooks · Open source
