One thing in flight simulation that is sorely lacking from train simulation is a dynamic environment with varying and unpredictable changes. One of the largest in my opinion is in the weather. There are just too few preset weather conditions, and they make the sim feel the same every time you're playing it.
Solution?
Simple, let's create custom weather based on the REAL conditions.
I spent a while looking into the weather files and they are actually quite simple. There are a series of parameters that are easily customizable:
Wind Direction
Wind Speed
Precip Type
Precip Density
Precip Speed
Visibility
Storms
Cumulus Clouds
Overcast Clouds
Storm Clouds
Horizon/Fog Color
One can go through and manually edit an XML file and set these settings to their liking, but clearly it would be superior to have this auto-generate, or atleast be as automatic as possible. One way flight simulation programs do this is by reading an aviation weather report or METAR code and decoding it. I have been able to create an excel document that can take a METAR and spit out a complete XML ready to be compiled.
This is an initial V1 concept, all done in excel (google docs actually) reading this Cheyenne WY weather code:
KCYS 042053Z 01013G22KT 1/2SM SN VV012 M16/M19 A2972 RMK AO2 SLP162 P0002 60006 T11611189 55006 RVRNO

And its output:
- Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<cBlueprintLoader xmlns:d="http://www.kuju.com/TnT/2003/Delta" d:version="1.0">
<Blueprint>
<cWeatherPatternBP>
<DisplayName>
<Localisation-cUserLocalisedString>
<English d:type="cDeltaString">1. Clear</English>
<French d:type="cDeltaString"></French>
<Italian d:type="cDeltaString"></Italian>
<German d:type="cDeltaString"></German>
<Spanish d:type="cDeltaString">1. Despejado</Spanish>
<Dutch d:type="cDeltaString"></Dutch>
<Polish d:type="cDeltaString"></Polish>
<Russian d:type="cDeltaString"></Russian>
<Other/>
<Key d:type="cDeltaString"></Key>
</Localisation-cUserLocalisedString>
</DisplayName>
<WeatherTypeClear>
<cWeatherType>
<WindDirection d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">010</WindDirection>
<WindSpeed d:type="sFloat32" d:alt_encoding="00000080B0E10140" d:precision="string">11.31768</WindSpeed>
<PrecipitationType d:type="cDeltaString">ePrecipitationSnow</PrecipitationType>
<PrecipitationDensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0.5</PrecipitationDensity>
<PrecipitationSpeed d:type="sFloat32" d:alt_encoding="000000A099992340" d:precision="string">5.0594556672</PrecipitationSpeed>
<FogOverride d:type="cDeltaString">eTrue</FogOverride>
<FogColour>
<cHcColour>
<Red d:type="sFloat32" d:alt_encoding="000000C0CCCCF03F" d:precision="string">1.05</Red>
<Green d:type="sFloat32" d:alt_encoding="000000A09999E93F" d:precision="string">0.8</Green>
<Blue d:type="sFloat32" d:alt_encoding="000000403333E33F" d:precision="string">0.6</Blue>
<Alpha d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">1</Alpha>
</cHcColour>
</FogColour>
<FogStart d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">482.802</FogStart>
<FogEnd d:type="sFloat32" d:alt_encoding="000000000094C140" d:precision="string">804.67</FogEnd>
<LightningDensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</LightningDensity>
<LightningFrequency d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</LightningFrequency>
<BlendInTime d:type="sFloat32" d:alt_encoding="0000000000002E40" d:precision="string">15</BlendInTime>
<CloudType d:type="cDeltaString">eCloudClear</CloudType>
</cWeatherType>
</WeatherTypeClear>
<WeatherTypeOvercast>
<cWeatherType>
<WindDirection d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">010</WindDirection>
<WindSpeed d:type="sFloat32" d:alt_encoding="00000080B0E10140" d:precision="string">11.31768</WindSpeed>
<PrecipitationType d:type="cDeltaString">ePrecipitationSnow</PrecipitationType>
<PrecipitationDensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0.5</PrecipitationDensity>
<PrecipitationSpeed d:type="sFloat32" d:alt_encoding="000000A099992340" d:precision="string">5.0594556672</PrecipitationSpeed>
<FogOverride d:type="cDeltaString">eTrue</FogOverride>
<FogColour>
<cHcColour>
<Red d:type="sFloat32" d:alt_encoding="000000C0CCCCF03F" d:precision="string">1.05</Red>
<Green d:type="sFloat32" d:alt_encoding="000000A09999E93F" d:precision="string">0.8</Green>
<Blue d:type="sFloat32" d:alt_encoding="000000403333E33F" d:precision="string">0.6</Blue>
<Alpha d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">1</Alpha>
</cHcColour>
</FogColour>
<FogStart d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">482.802</FogStart>
<FogEnd d:type="sFloat32" d:alt_encoding="000000000094C140" d:precision="string">804.67</FogEnd>
<LightningDensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</LightningDensity>
<LightningFrequency d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</LightningFrequency>
<BlendInTime d:type="sFloat32" d:alt_encoding="0000000000002E40" d:precision="string">15</BlendInTime>
<CloudType d:type="cDeltaString">eCloudClear</CloudType>
</cWeatherType>
</WeatherTypeOvercast>
<WeatherTypeRain>
<cWeatherType>
<WindDirection d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</WindDirection>
<WindSpeed d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</WindSpeed>
<PrecipitationType d:type="cDeltaString">ePrecipitationRain</PrecipitationType>
<PrecipitationDensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</PrecipitationDensity>
<PrecipitationSpeed d:type="sFloat32" d:alt_encoding="000000A099992340" d:precision="string">9.8</PrecipitationSpeed>
<FogOverride d:type="cDeltaString">eFalse</FogOverride>
<FogColour>
<cHcColour>
<Red d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Red>
<Green d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Green>
<Blue d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Blue>
<Alpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Alpha>
</cHcColour>
</FogColour>
<FogStart d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</FogStart>
<FogEnd d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</FogEnd>
<LightningDensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</LightningDensity>
<LightningFrequency d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</LightningFrequency>
<BlendInTime d:type="sFloat32" d:alt_encoding="0000000000002E40" d:precision="string">15</BlendInTime>
<CloudType d:type="cDeltaString">eCloudClear</CloudType>
</cWeatherType>
</WeatherTypeRain>
<WeatherTypeStorm>
<cWeatherType>
<WindDirection d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</WindDirection>
<WindSpeed d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</WindSpeed>
<PrecipitationType d:type="cDeltaString">ePrecipitationRain</PrecipitationType>
<PrecipitationDensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</PrecipitationDensity>
<PrecipitationSpeed d:type="sFloat32" d:alt_encoding="000000A099992340" d:precision="string">9.8</PrecipitationSpeed>
<FogOverride d:type="cDeltaString">eFalse</FogOverride>
<FogColour>
<cHcColour>
<Red d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Red>
<Green d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Green>
<Blue d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Blue>
<Alpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Alpha>
</cHcColour>
</FogColour>
<FogStart d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</FogStart>
<FogEnd d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</FogEnd>
<LightningDensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</LightningDensity>
<LightningFrequency d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</LightningFrequency>
<BlendInTime d:type="sFloat32" d:alt_encoding="0000000000002E40" d:precision="string">15</BlendInTime>
<CloudType d:type="cDeltaString">eCloudClear</CloudType>
</cWeatherType>
</WeatherTypeStorm>
<PrecipitationRain>
<cPrecipitationDescription>
<BottomLeftViewSpaceOffset>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</BottomLeftViewSpaceOffset>
<TopRightViewSpaceOffset>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</TopRightViewSpaceOffset>
<BottomLeftUV>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</BottomLeftUV>
<TopRightUV>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</TopRightUV>
<AlphaTop d:type="sUInt32">255</AlphaTop>
<AlphaBottom d:type="sUInt32">255</AlphaBottom>
<ParticleStreakMultiplier d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">1</ParticleStreakMultiplier>
<TextureID d:type="cDeltaString"></TextureID>
</cPrecipitationDescription>
</PrecipitationRain>
<PrecipitationSleet>
<cPrecipitationDescription>
<BottomLeftViewSpaceOffset>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</BottomLeftViewSpaceOffset>
<TopRightViewSpaceOffset>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</TopRightViewSpaceOffset>
<BottomLeftUV>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</BottomLeftUV>
<TopRightUV>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</TopRightUV>
<AlphaTop d:type="sUInt32">255</AlphaTop>
<AlphaBottom d:type="sUInt32">255</AlphaBottom>
<ParticleStreakMultiplier d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">1</ParticleStreakMultiplier>
<TextureID d:type="cDeltaString"></TextureID>
</cPrecipitationDescription>
</PrecipitationSleet>
<PrecipitationHail>
<cPrecipitationDescription>
<BottomLeftViewSpaceOffset>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</BottomLeftViewSpaceOffset>
<TopRightViewSpaceOffset>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</TopRightViewSpaceOffset>
<BottomLeftUV>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</BottomLeftUV>
<TopRightUV>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</TopRightUV>
<AlphaTop d:type="sUInt32">255</AlphaTop>
<AlphaBottom d:type="sUInt32">255</AlphaBottom>
<ParticleStreakMultiplier d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">1</ParticleStreakMultiplier>
<TextureID d:type="cDeltaString"></TextureID>
</cPrecipitationDescription>
</PrecipitationHail>
<PrecipitationSnow>
<cPrecipitationDescription>
<BottomLeftViewSpaceOffset>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</BottomLeftViewSpaceOffset>
<TopRightViewSpaceOffset>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0.1</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0.1</Y>
</cRVector2>
</TopRightViewSpaceOffset>
<BottomLeftUV>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</Y>
</cRVector2>
</BottomLeftUV>
<TopRightUV>
<cRVector2>
<X d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">1</X>
<Y d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">1</Y>
</cRVector2>
</TopRightUV>
<AlphaTop d:type="sUInt32">120</AlphaTop>
<AlphaBottom d:type="sUInt32">120</AlphaBottom>
<ParticleStreakMultiplier d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">1</ParticleStreakMultiplier>
<TextureID d:type="cDeltaString">Kuju\RailSimulatorCore\Weather\[00]snowflake</TextureID>
</cPrecipitationDescription>
</PrecipitationSnow>
<CloudClear>
<cCloudDescription>
<WispyLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</WispyLayerAlpha>
<ThickCloudLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0.7</ThickCloudLayerAlpha>
<StormLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</StormLayerAlpha>
<ColourDarkeningIntensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</ColourDarkeningIntensity>
</cCloudDescription>
</CloudClear>
<CloudOvercast>
<cCloudDescription>
<WispyLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</WispyLayerAlpha>
<ThickCloudLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0.7</ThickCloudLayerAlpha>
<StormLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</StormLayerAlpha>
<ColourDarkeningIntensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</ColourDarkeningIntensity>
</cCloudDescription>
</CloudOvercast>
<CloudRain>
<cCloudDescription>
<WispyLayerAlpha d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">1</WispyLayerAlpha>
<ThickCloudLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</ThickCloudLayerAlpha>
<StormLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</StormLayerAlpha>
<ColourDarkeningIntensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</ColourDarkeningIntensity>
</cCloudDescription>
</CloudRain>
<CloudStorm>
<cCloudDescription>
<WispyLayerAlpha d:type="sFloat32" d:alt_encoding="000000000000F03F" d:precision="string">1</WispyLayerAlpha>
<ThickCloudLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</ThickCloudLayerAlpha>
<StormLayerAlpha d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</StormLayerAlpha>
<ColourDarkeningIntensity d:type="sFloat32" d:alt_encoding="0000000000000000" d:precision="string">0</ColourDarkeningIntensity>
</cCloudDescription>
</CloudStorm>
<WeatherEvent>
<cWeatherEvent d:id="20305720">
<Type d:type="cDeltaString">eWeatherTypeClear</Type>
<Time d:type="sFloat32" d:alt_encoding="0000000000004E40" d:precision="string">45</Time>
</cWeatherEvent>
<cWeatherEvent d:id="20305720">
<Type d:type="cDeltaString">eWeatherTypeOvercast</Type>
<Time d:type="sFloat32" d:alt_encoding="0000000000004E40" d:precision="string">999</Time>
</cWeatherEvent>
</WeatherEvent>
<Name d:type="cDeltaString">IL_Clear</Name>
<AudioControl d:type="cDeltaString">Kuju\RailSimulatorCore\Audio\Weather\Weather</AudioControl>
</cWeatherPatternBP>
</Blueprint>
</cBlueprintLoader>
This is really just a proof of concept, but all that would be needed is to compile with SERZ and run. I have been compiling to the "Clear" weather theme in the RailsimulatorCore fileset and I am able to use quickdrive scenarios with it. This coupled with custom quick drives and custom route-specific AI consists create a very dynamic sim so far.
I am continuing to work on this, currently it only supports one METAR code, but as you can see I've started laying out the groundwork to be able to input two, start and destination so the weather can change during your journey.



