In a normal scene, the sky can often take up nearly 50% of the screen. With that in mind, I set out to create a sky system that is beautiful and simple. This is a technical dive into the inner workings of Ardenfall’s sky system. If you’re more interested in individual features, then I would check out our latest devlog.

Montage of different weather and times

Parameterized objects

One thing I have to mention is the fact that I’m using what I call “Parameterized Objects”, or in simple terms “Scriptable Object Prefabs”. In other words, I make use of a system that allows me to have a Scriptable Object be a parent of another, and only tweak the values I wish to tweak. This makes making different “Skies” easier (I’ll get back to that later), since often they are quite similar, needing only a few tweaks. I plan on making a post on parameterized objects later on, but for now lets focus on Skies!

Example of using Parameterized Objects for an item

Data Structure

The sky system is weather and time based.

Weather 1: - TOD at time: 0 - TOD at time: 0.25 - TOD at time: 0.5 - TOD at time: 1

TOD stands for “Time of Day”, which is a scriptable object with a list of values that the sky is supposed to look like at a certain time. For example, “tod_clear_day” has values that make the sky a beautiful blue color, the sun is bright, the stars are hidden, and the clouds are white.

The active weather, whether clear or cloudy, will blend between two TOD’s, depending on the time of day. I have two helpful functions that let me do this: Weather.GetSkyFloat(id), and Weather.GetSkyColor(id). The id is a string, which is the field name for whatever value I want. Using reflection (cached of course), it automatically gets the two current TOD’s that are blending, lerp the values, and returns.

Weather Data!

Simple, but Powerful

The weather system doesn’t just affect the sky shader, however. Sky values can be grabbed from any system, which is incredibly helpful! Several post processing effects, such as fog and height fog, are affected by the TOD, as well as terrain wetness (material shininess), wind, and ambient lighting.

A weather also has ambient sounds attached, such as birds or rain. It can spawn a particle system, such as rain, and it also affects what songs are played. Finally, each weather can have a custom post processing profile attached as well.

Blending

Of course, skies aren’t the only thing that is blended: weathers are too! In other words, when a weather is transitioning, there are 4 skies being blended together. This transition also fades in/out particle emit counts, ambient volume, and post processing volumes.

Future: Positional Weathers

Currently, the enabled weather (or two, if transitioning) is considered world wide. Of course if the player runs off to another location, the weather may change, but only one weather calculates at a time. The rain particles follow the player, the ambient sounds do as well, and so on. In the future, I’d love for weather to be positional, where the player can see storm clouds in the distance and travel there. That would add a lot of complication, specifically to the blending of sounds and particles and all of that junk. I’d love to get this working someday!

The Sky’s the Limit

And that is all for now! I hope this post was helpful and insightful! If you have any specific questions, feel free to throw me a line on my Twitter, or join our Discord! Have a wonderful day. :)