← README
Well, look who blew in. Howdy, farmer! Looking to make some custom weather types for your mod? You've come to the right place!
- Getting Started
- What is a Weather Type?
- What is a Weather Flag?
- Custom Weather Type
- Screen Tint
- Effects
- Layers
- [Shaders]
- How Do I Make My Weather Happen?
- Location Context Extension Data
- Commands
- Mod Data / Custom Fields
- Trigger Actions
- Game State Queries
- Content Patcher Tokens
Cloudy Skies does not currently support content packs of its own. Instead, I expect you to use Content Patcher to load your custom data.
Don't know how to use Content Patcher? Head over to check out their excellent documentation then! They do a much better job than I ever could.
Specifically, you'll be loading textures and using the EditData
action with
the target:
Mods/leclair.cloudyskies/WeatherData
A weather type is, if you'll forgive the tautology, a type of weather. The base game has eight weather types:
Sun
Rain
Wind
Storm
Snow
Festival
Wedding
- (and one added in 1.6, not named because it's a spoiler)
Really though, it's more like six. Festival
and Wedding
are both duplicates
of Sun
, just with a little flavor for the occasion.
The Stardew 1.6 update added the ability to use custom Ids for the weather, but it didn't make it possible to actually do anything with those custom Ids. That's what this mod is for.
In so far as this mod is concerned, a weather type is any behavior associated with a specific weather flag or weather Id. We make it possible to set up a lot of those behaviors, and set up the necessary data for other mods to contribute their own behaviors. (As an example, you could use FTM to spawn custom foragables in certain weather.)
A weather flag is slightly different than a weather type. Internally, the game has flags it checks rather than directly looking at the current weather type's Id. These flags are pretty self explanatory:
IsRaining
IsSnowing
IsLightning
IsDebrisWeather
(Debris is the internal name for Wind)- (and one added in 1.6, not named because it's a spoiler)
The Storm
weather, for example, sets both the IsRaining
and
IsLightning
flags to be true.
Alright, awesome! So how do you make a custom weather type? Glad you asked!
You just need to add an entry to the Mods/leclair.cloudyskies/WeatherData
asset with your new weather type's unique Id, and any other data to go with it.
Specifically, each custom weather type supports the following properties:
Field | Description |
---|---|
Identity | |
Id |
Required. The unique Id of your weather type. This must be unique, and is used elsewhere to reference this specific weather type. You should include your mod's Unique Id in this for best results to ensure
there aren't any collisions. When using Content Patcher, you can do this
easily using the |
DisplayName |
Required. A human readable name to display to the player when this weather type is referenced by name. This is a tokenizable string. |
Icon | |
IconTexture |
Optional. The name of a texture containing this weather type's icon. The icon is displayed on the in-game HUD next to the clock when this is the active weather type in the current location. This may also be used by other mods, such as UI Info Suite or Almanac. This should be a texture you've loaded. As an example, you could use
the value
|
IconSource |
Optional. The top-left corner of your weather's icon in the provided texture. You only supply the X and Y position. An icon is always 12 by 8 pixels. Default: |
Television | |
TVTexture |
Optional. The name of a texture containing this weather type's TV animation. The animation may be displayed when a player checks the forecast using their television. This may also be used by other mods. Like |
TVSource |
Optional. The top-left corner of the first frame of your weather type's TV animation. Each frame is always 13 by 13 pixels, and the frames are always laid out as a horizontal strip. Default: |
TVFrames |
Optional. The number of frames your weather type's TV animation has. Default: |
TVSpeed |
Optional. How long should each frame of your weather type's TV animation be displayed, in milliseconds? Default: |
Forecast |
Optional. The message to display to the player when they check the forecast using their TV and this weather type is coming up. This is a tokenizable string. Example: |
ForecastByContext |
Optional. A dictionary letting you override the Example: |
Weather Totem Behavior | |
TotemMessage |
Optional. A message to display to the player when they use a custom weather totem for this weather type. If this is not set, the default message used by the base game's Rain Totem will appear. This is a tokenizable string. |
TotemSound |
Optional. An audio cue to
play when the player uses a custom weather totem for this weather type. If
this is not set, no sound will play. The base game's Rain Totem uses the
sound: |
TotemAfterSound |
Optional. An audio cue to
play after the player uses a custom weather totem for this weather type. This
plays approximately two seconds after |
TotemScreenTint |
Optional. A color to flash the screen when the player uses a custom weather
totem for this weather type. If this is not set, the screen will not flash a
color. The base game's Rain Totem uses the color: |
TotemParticleTexture |
Optional. The texture name of a texture to display as particles when the
player uses a custom weather totem for this weather type. If this is not set,
no extra particles will be displayed. The base game's Rain Totem uses the
texture: |
TotemParticleSource |
Optional. The region of the |
Behavior - Music | |
MusicOverride |
Optional. An audio cue that, when set, will play in place of the normal in-game music when this weather condition is active. This mimics the behavior of the base game's raining weather flag, which plays a rain sound. Example: |
MusicFrequencyOutside |
Optional. The frequency that Default: |
MusicFrequencyInside |
Optional. The frequency that Default: |
SoftMusicOverrides |
Optional. A list of music overrides that function like the
This is in effect a list of audio cues and game state conditions. The first entry with a matching condition will be used. You can use game state conditions to better control when any given condition should be matched.
|
Behavior - Weather Flags | |
IsRaining
|
Optional. Whether or not this weather type should apply the Default: |
IsRaining
|
Optional. Whether or not this weather type should apply the Default: |
IsSnowing
|
Optional. Whether or not this weather type should apply the Default: |
IsLightning
|
Optional. Whether or not this weather type should apply the Default: |
IsDebrisWeather
|
Optional. Whether or not this weather type should apply the Default: |
IsGreenRain
|
Optional. Whether or not this weather type should apply the
Default: |
Behavior - Other | |
UseNightTiles |
Optional. If this is set to true, this weather type will cause maps to
display their night tiles even during the day and to have darkened windows,
similar to how the base game's For the sake of flexibility, this has been moved into a separate flag for custom weather types. Default: |
SpawnCritters |
Optional. Whether or not critters should be allowed to spawn during this weather type. Critters are the small animals you'll see around maps, like birds or squirrels, along with moving cloud shadows and frogs. Default: |
SpawnFrogs |
Optional. Whether or not frogs should be allowed to spawn during this
weather type. If this is not set, the game will use the default logic and
check the |
SpawnClouds |
Optional. Whether or not cloud shadow critters should attempt to spawn. Yes, those occasional shadows you'll see moving around are technically critters. If this is not set, the game will use the default logic which checks for sunny days in summer. |
The Good Stuff | |
Lighting |
Optional. A list of Screen Tint entries that should apply when the current location has this weather type. |
Effects |
Optional. A list of Effects that should apply to the player while they are in a location with this weather type. |
Layers |
Optional. A list of Layers that should render when the current location has this weather type. |
Screen tinting data entries allow you to not just override the ambient light and tinting applied at any given time, but also smoothly fade between different colors and opacity levels.
Note: It is very important that you sort these entries by their
TimeOfDay
.
Field | Description |
---|---|
Id |
Required. The Id of this screen tint data point. This only needs to be unique within the custom weather type containing it. |
TimeOfDay |
Optional. The time of day that this screen tint should apply at. This should be a three or four digit number where the first one or two digits is the hour and the last two digits are the current minutes. For example:
If this is set to zero, or a negative value, then the value will be set based on the time it gets dark out in the current location. That time has a few possible values in the base game.
Default: |
Condition |
Optional. A game state query to determine whether or not this screen tint data point may be used. If this is not set, this data point may always be used. These conditions are only reevaluated upon location change, an event starting, or the in-game hour changing. |
TweenMode |
Optional. How smooth blending should happen between this and other
data points. Possible values: Default: |
Appearance | |
AmbientColor |
Optional. The ambient color that should be used for lighting when this
weather type is active. In the base game, this is only used if the
|
AmbientOutdoorOpacity |
Optional. The opacity that should be used when applying the You can leave this value out, or set it to |
LightingTint |
Optional. If set, this color will be drawn to the screen in lighting mode
during the Draw Lightmap phase of world rendering. In the base game, this
is only used if the
|
LightingTintOpacity |
Optional. An opacity to use with the In the base game, this is only used if the You may wish to use |
PostLightingTint |
Optional. If set, this color is drawn to the screen in normal mode after
the lighting phase of world rendering. In the base game, this is only used
if the |
PostLightingTintOpacity |
Optional. An opacity to use with the In the base game, this is only used if the |
An effect is something that applies to the player while they are in a location with a given weather type. This is specifically for things that affect players, and not for other arbitrary things that could happen.
For making other things happen, you can make suggestions, but you might want to look into other mods and triggers.
Each Effect
has the following values:
Field | Description |
---|---|
Identity | |
Id |
Required. The Id of this effect. This only needs to be unique within the weather type containing it. |
Type |
Required. The type of effect. Valid options are: More types may be added in the future, or by C# mods (in the future). |
Rate |
Optional. How often should this effect update, in ticks. Each second is
Default: |
Conditional Effects | |
Condition |
Optional. A game state query to determine whether or not this effect should be active. If this is not set, the effect will always be active. These conditions are only reevaluated upon location change, an event starting, or the in-game hour changing. |
Group |
Optional. An optional group for this effect. Only one effect in a group can
be active at a time. Specifically: the first effect in the effect list that
passes its |
TargetMapType |
Optional. What type of map should this effect be active for? This can be
Default:
|
All other effect values are specific to their individual Type
s, as follows:
The Buff
effect will add a buff to the player. This buff will persist the
entire time the effect is active, and may linger after the effect ends for
a time.
Field | Description |
---|---|
BuffId |
Required. The Id of the buff to apply to the player. This must be set,
but it doesn't necessarily have to be an existing buff in If this Id does exist in If you're making your own buff, a good idea is to include your mod's unique Id as a prefix. |
Appearance | |
DisplayName |
Optional. A display name for this buff. This is a tokenizable string. |
Description |
Optional. A description for this buff. This is a tokenizable string. |
IconTexture |
Optional. The asset name for a texture containing this buff's icon. |
IconSpriteIndex |
Optional. The sprite index for this buff's icon within |
GlowColor |
Optional. The glow color to apply to the player when they have this buff. |
Behavior | |
IsDebuff |
Optional. Whether this buff counts as a debuff, so its duration should be halved when wearing a sturdy ring.
|
LingerDuration |
Optional. The duration, in milliseconds, for which this buff should remain
on the player after the effect is no longer active. This can be set to Default: |
LingerMaxDuration |
Optional. The maximum duration the buff should remain on after the effect
is no longer active. If this is set to a number larger than |
Effects |
Optional. Extra attributes to apply for this buff. See the 1.6 migration guide for more details on this data model. |
CustomFields |
Optional. The custom fields for this buff. This can be used to, for example, add SpaceCore skills to a buff (or debuff).
|
The ModifyHealth
effect will either damage or heal the player. This can be
used to, for example, damage the player if they're caught outside in a
particularly nasty bit of weather like acid rain, or a snowstorm, or volcanic
heat, etc. Or maybe there's a sacred grove with special weather that heals
the player? Anything is possible.
Field | Description |
---|---|
Amount |
Required. The amount to change the player's health by. Setting this to a negative value will damage them, and setting this to a positive value will heal them. Note that when damaging players, the player will get temporary invulnerability to further damage so you may as to increase the time between damage ticks to avoid effectively making them immune to other dangers on the map because of the weather damage. There is no such rate limitation when healing the player. |
MinValue |
Optional. The minimum value that the player's health can reach.
Default: |
MaxValue |
Optional. The maximum value that the player's health can reach when they
are being healed. Unlike the Default: |
Chance |
Optional. The chance that this effect applies on any given update. You can
use this to make the effect only occasionally damage/heal the player. This is
a number from Default: |
The ModifyStamina
effect will either drain or fill the player's stamina. This
can be used to, for example, make the player lose stamina while they're caught
outside in a hostile bit of weather like extreme winds or a sand storm.
Field | Description |
---|---|
Amount |
Required. The amount to change the player's stamina by. Setting this to a negative value will drain it, and setting this to a positive value will fill it. |
MinValue |
Optional. The minimum value that the player's stamina can reach. Default: |
MaxValue |
Optional. The maximum value that the player's stamina can reach. Unfortunately, there is no way to set it based on the player's maximum stamina at this time aside from that, if this value is greater than the player's maximum stamina, it will be reduced to the player's maximum stamina. Default: |
Chance |
Optional. The chance that this effect applies on any given update. You can
use this to make the effect only occasionally drain/fill the player's stamina.
This is a number from Default: |
The Trigger
effect allows you to run trigger actions. These trigger actions
will run for all players, not just the host, and they may run frequently so
you'll want to be careful not to go overboard.
Trigger actions can be run whenever the effect becomes active, periodically while the effect is active, and when the effect is removed.
Field | Description |
---|---|
ApplyActions |
Optional. The actions to apply whenever this effect becomes active, as a list of strings. |
Actions |
Optional. The actions to apply whenever this effect updates, as a
list of strings. This happens every |
RemoveActions |
Optional. The actions to apply whenever this effect is removed, as a list of strings. |
A Layer is something that draws to the screen while in a location with a given weather type. You can compose multiple layers to create complex effects.
Each Layer
has the following values:
Field | Description |
---|---|
Identity | |
Id |
Required. The Id of this layer. This only needs to be unique within the weather type containing it. |
Type |
Required. The type of layer. Valid options are: More types may be added in the future, or by C# mods (in the future). |
Mode |
Optional. The blending mode for this layer. There are two choices, and they significantly change how the layer is drawn to the screen:
Default: |
Conditional Layers | |
Condition |
Optional. A game state query to determine whether or not this layer should be visible. If this is not set, the layer will always be visible. These conditions are only reevaluated upon location change, an event starting, or the in-game hour changing. |
Group |
Optional. An optional group for this layer. Only one layer in a group can
be visible at a time. Specifically: the first layer in the |
TargetMapType |
Optional. What type of map should this layer be displayed with? This can be
Default: |
All other layer properties are specific to their individual Type
s, as follows:
A Color
layer draws a full-screen rectangle of a color. This can be used
to apply a tint. Here is an example of using color layers to tint the screen
similarly to when it's raining:
{
"Id": "first",
"Type": "Color",
"Mode": "Lighting",
"Color": "orangered",
"Opacity": 0.45
},
{
"Id": "second",
"Type": "Color",
"Mode": "Normal",
"Color": "blue",
"Opacity": 0.2
}
Color
layers support the following properties:
Field | Description |
---|---|
Color |
Optional. The color to draw to the screen. Default: |
Opacity |
Optional. The opacity to draw the color with. This will handle
pre-multiplied alpha for you, so it is recommended to use this rather
than messing with Default: |
A Debris
layer can be used to draw floating debris particles, similar
to the leaves, flower petals, and snow flakes that appear in the base
game's Wind
weather type. This uses the same logic for animating and
moving particles.
Note:
Debris
layers do not natively obey theIgnoreDebrisWeather
flag of locations. As such, you should probably add aCondition
to all of yourDebris
layers with the following query:!CS_LOCATION_IGNORE_DEBRIS_WEATHER Here
Field | Description |
---|---|
Appearance | |
UseSeasonal |
Optional. As an alternative to You can use |
Texture |
Optional. The asset name of a texture to use for drawing this debris
layer. If this isn't set, then we'll fall back to using the native
seasonal sprites as described in You can either use static or animated debris. If you use animated, the logic for changing frames will function exactly the same as it does for the native sprites, so you'll want to look at those for an example of how to design your sprites. |
Sources |
Optional. A list of source rectangles to use for debris particles added by this debris layer. Each of these rectangles is specifically for the first animation frame. The subsequent frame positions will be calculated automatically. This assumes that the frames are laid out in a horizontal line. |
FlipHorizontal |
Optional. When set to true, this debris layer's sprites will be flipped horizontally when drawn. |
FlipVertical |
Optional. When set to true, this debris layer's sprites will be flipped vertically when drawn. |
Color |
Optional. The color to draw this debris layer's sprites with. Default: |
Opacity |
Optional. The opacity to draw this debris layer's sprites with.
This sets up pre-multiplied alpha with Default: |
Scale |
Optional. The scale this debris layer's sprites should be drawn at. Default: |
Behavior | |
CanBlow |
Optional. Whether or not the particles for this debris layer can enter a 'blowing' state where they move upwards. Default: |
MinCount |
Optional. The minimum number of particles to spawn for this debris layer. Default: |
MaxCount |
Optional. The maximum number of particles to spawn for this debris layer. Default: |
MinTimePerFrame |
Optional. The minimum amount of time a specific frame should be displayed, in milliseconds. Default: |
MaxTimePerFrame |
Optional. The maximum amount of time a specific frame should be displayed, in milliseconds. Default: |
ShouldAnimate |
Optional. Whether or not this debris layer should draw animated sprites. If this is set to false, only the first frame will ever be drawn. Default: |
A Rain
layer can be used to draw falling particles, similar to the rain
effect that appears in the base game's Rain
, Storm
, and GreenRain
weather types. At its most basic, the rain layer replicates the game's
normal rain particles completely:
{
"Id": "first",
"Type": "Rain",
}
Note: For the full rain experience, you'll need to do screen tinting as well.
Note:
Rain
layers do not automatically stop working during events, as the base game's rain effect does. If you want to make sure your rain does not appear during an event, you should add aCondition
like:!IS_EVENT
Field | Description |
---|---|
Appearance | |
Texture |
Optional. The asset name of a texture to use for drawing this rain layer. If this is not set, then this rain layer will use the game's native rain sprites for drawing. |
Source |
Optional. A source rectangle for the first frame of the rain animation
within the provided texture. If |
Frames |
Optional. How many frames of animation your rain texture has. This is
ignored if Default: |
FlipHorizontal |
Optional. When set to true, this rain layer's sprites will be flipped horizontally when drawn. |
FlipVertical |
Optional. When set to true, this rain layer's sprites will be flipped vertically when drawn. |
Color |
Optional. The color to draw this rain layer's sprites with. Default: |
Opacity |
Optional. The opacity to draw this rain layer's sprites with.
This sets up pre-multiplied alpha with Default: |
Vibrancy |
Optional. How many times to draw this rain layer's sprites. The
base game's Green Rain effect uses this with a value of Default: |
Scale |
Optional. The scale to draw the rain particle sprites with. Default: |
Behavior | |
Count |
Optional. How many rain particles to draw. This can be used to make the rain lighter or heavier, but you should be careful not to go too overboard, as drawing too many particles can cause performance issues. Default: |
Speed |
Optional. The speed this rain layer's particles should move. Default: |
A Shader
layer is used to apply a shader effect to the rendered game world.
This can be used for more advanced effects, like applying a distortion or
using a look-up table to adjust colors. Here's an example using the built-in
Palettize
shader to limit the game:
{
"Id": "first",
"Type": "Shader",
"Shader": "Palettize",
"Palette": "Mods/MyMod/MyPalette",
"ColorCount": 46
}
For reference, this is the palette used for that sample image:
You can use one of the built-in shaders, or provide your own shader. See the Shaders section of the documentation for more.
Note: You cannot use
Mode
for aShader
layer. It just won't have any effect at all.
Field | Description> |
---|---|
Appearance | |
Shader |
Required. The name of the shader to use. This should be either the name of one of the built-in shaders, or the absolute file path to one of your own compiled shader files. Using Content Patcher, you can use the |
Color |
Optional. A color to use when rendering with the shader. This is passed into the shader, so how it's used (and if it's used at all) may vary depending on which shader you're using. Default: |
??? |
The other properties are entirely dependent on what |
A Snow
or TextureScroll
layer can be used to draw an animated texture
in a tightly packed grid. This is used by the base game for rendering snow
during the Snow
weather type. At its most basic, this layer replicates
the game's normal snow rendering exactly:
{
"Id": "first",
"Type": "Snow"
}
But you can override this behavior by giving it your own texture. Using
Snow
or TextureScroll
changes the default behavior slightly, with
ViewSpeed
having a value for Snow
and not TextureScroll
. Additionally,
when using Snow
your layer's opacity will be multiplifed by the user's
snow transparency setting.
Field | Description> |
---|---|
Appearance | |
Texture |
Required/Optional. The asset name of a texture to use for drawing this
layer. This must be set for |
Source |
Optional. A source rectangle for the first frame of the animation
within the provided texture. If |
Frames |
Optional. How many frames of animation your texture has. This is
ignored if Default: |
TimePerFrame |
Optional. How long each frame should be displayed, in milliseconds. Default: |
FlipHorizontal |
Optional. When set to true, this layer's sprites will be flipped horizontally when drawn. |
FlipVertical |
Optional. When set to true, this layer's sprites will be flipped vertically when drawn. |
Color |
Optional. The color to draw this layer's sprites with. Default: |
Opacity |
Optional. The opacity to draw this layer's sprites with.
This sets up pre-multiplied alpha with
Default: |
Scale |
Optional. The scale to draw this layer's texture with. Default: |
Behavior | |
Speed |
Optional. The speed this layer's position should change. By default, these layers don't move at all. Default: |
ViewSpeed |
Optional. The speed this layer's position should change relative
to the movement of the viewport. A value of Default: |
This section details how to use Shader
layers. You'll find
sections for each of the built-in shaders, along with instructions on how
to develop custom shaders.
The Blur
shader is more accurately a convolution shader that operates on a 5 by 5
sample grid. Using the default settings, it performs a very basic blur, but you can
tweak the kernel weights to achieve different effects.
Field | Description |
---|---|
Distance |
Required> This field multiplies the distance from the target pixel that each
sample will be taken. If, for example, you use this with a value of Since we're dealing with a 5x5 sample grid, that means a 5x5 area of pixels will be sampled. Setting this to |
UseWeights |
Optional. Whether or not the Default: |
Weights |
Optional. A list of kernel weights. This should be a list of 25 floating point numbers, representing the 5 by 5 sample area. As an example, here is a set of weights for a Gaussian blur:
|
The Colorize
shader, reused with permission from the Nightshade project (see
LICENSE.md for details), uses color math to adjust the saturation,
lightness, and contrast of each pixel as well as having color balance inputs.
Field | Description |
---|---|
Contrast |
Optional. Adjust the contrast by this amount.
|
Lightness |
Optional. Adjust the lightness by this amount.
|
Saturation |
Optional. Adjust the saturation by this amount.
|
LumaType |
Optional. Select which graypoint to use. Valid choices:
Default: |
ShadowRgb |
Optional. An array representing how to shift colors in the shadow range. The first entry is for red, the second entry is for green, and the third entry is for blue. Each value should be in the range Default: |
MidtoneRgb |
Optional. An array representing how to shift colors in the midtone range. The first entry is for red, the second entry is for green, and the third entry is for blue. Each value should be in the range Default: |
HighlightRgb |
Optional. An array representing how to shift colors in the highlight range. The first entry is for red, the second entry is for green, and the third entry is for blue. Each value should be in the range Default: |
The Distortion
shader uses a very simple noise algorithm to distort the
texture coordinates when drawing.
Field | Description |
---|---|
Strength |
Required. The strength of the distortion effect. This value should be
very small. I recommend starting with something like |
Frequency |
Required. The frequency of the distortion effect. This value changes
the scale of the distortions, with the distortions getting smaller the
larger this is. I recommend starting with something like |
The Palettize
shader reduces the visible colors of the resulting image to
those found in the supplied Palette
. See the Shader
layer
description for an example screenshot of this in action.
Field | Description |
---|---|
Palette |
Required. The asset name of a palette texture to reference. A palette
should be a 1 or 2 pixel tall horizontal strip of colors, where each color
in the palette has a single column. A palette of 256 colors, for example,
should be either a If you provide a 2 pixel tall image, the top pixel will be used for finding similar colors, while the bottom pixel will be used to actually draw the color to the output. |
ColorCount |
Required. The number of colors in the palette texture. |
Monochrome |
Optional. Is the provided palette a monochrome palette? If this is set to true, the input color will be converted to grayscale before being compared to the palette. This may result in a higher quality image, but is not suitable for use if the palette is not monochromatic. |
Dither |
Optional. If this is set to true, the output will use dithering to create the appearance of additional colors. This can be very effective at increasing the apparent color count, but as a result it leaves the image feeling grainy, soft, and can potentially ruin the aesthetic. |
The Pixelate
shader effectively lowers the resolution of the screen in a
very simple way. This is not intended for serious use, and was really just
the result of me messing around. Still, it's here.
Field | Description |
---|---|
ScaleX |
Required. The horizontal pixel size. Setting this to |
ScaleY |
Required. The vertical pixel size. Setting this to |
Want to write your own shaders? Awesome! Cloudy Skies is here to help.
You'll need to make sure you're using the absolute file path to your shader
file, as directed in Shader
. Beyond that, how do you compile
a shader?
I'm glad you asked!
You're going to need an old version of the dotnet-mgfxc
package installed
on your computer. Specifically, version 3.8.0.1641.
Newer versions are not compatible with the version of MonoGame that
Stardew Valley uses.
But wait, there's more! That version of dotnet-mgfxc
will not work with the
latest version of .NET Core, so you'll need to install an older version of
that as well.
Specifically, you'll want to install .NET Core 3.1.32.
Note: You should NOT leave this version of .NET installed after you're done, as it has security issues. Install it, get your work done, then remove it again.
Alright. Got all that? Then you'll want to enable Debug: Re-Compile Shaders
in Cloudy Skies' settings. Once you've done that, Cloudy Skies will
automatically recompile any shaders as long as the .fx
file is in the same
folder as the .mgfx
file.
This recompilation happens:
- The first time the shader is used.
- Any subsequent times the current weather layers are reloaded,
if the
.fx
file has changed. - When the
cs_reload
command is used, if the.fx
file has changed.
Take a look at one of the built-in shaders to get an idea of what a .fx
file should look at, and go for it! You'll also want to be aware of the
following properties. If you include them in your shaders, Cloudy Skies
will automatically update them with relevant game data:
Parameter | Type | Description |
---|---|---|
ElapsedTime |
float |
The amount of time, in milliseconds, that has passed since the previous frame was rendered. This may be zero if the game has been paused for any reason. |
TotalTime |
float |
The total amount of time, in milliseconds, that has passed since the game started rendering. This is not guaranteed to change between frames if the game has been paused for any reason. |
TimeOfDay |
float |
The in-game time of day, in partial hours. As an example, |
ViewportPosition |
float2 |
The position of the top-left corner of the current viewport in the current map. This changes as the viewport moves around, and can be used to ensure that effects stay locked in the same place relative to the world. |
ScreenSize |
float2 |
The size of the current viewport. In single-player, this is the same as the size of the game window. In split-screen multiplayer, this is the size of one of the split areas. |
Just adding a custom weather type using Cloudy Skies isn't enough to actually make your weather happen in the game. You need to tell the game when and where it should be applied, and that's done in one of two ways:
-
Use a location context's
WeatherConditions
list to make the weather type occur naturally in a location context.See the 1.6 migration guide for more.
-
Use a custom weather totem to override tomorrow's weather specifically.
To make a custom weather totem, you'll need to add a custom object to the
game. In 1.6, the best way to do this is by editing the Data/Objects
list to add your custom item, and then editing a shop, crafting recipe,
event, etc. to give the player a way to obtain your item.
The important thing is that your custom weather totem has a CustomField
in its Data/Objects
entry with the key leclair.cloudyskies/WeatherTotem
and a value with the desired weather type's Id.
Cloudy Skies has a secondary data asset for adding custom data to
location contexts with the goal of expanding the in-game forecasting
system. To edit this data, you need an EditData
action with
this target:
Mods/leclair.cloudyskies/LocationContextExtensionData
Field | Description |
---|---|
Id |
Required. The Id of the location context that this entry
is extending. This needs to match an entry in the
|
DisplayName |
Optional. A display name for this location context, to be used when this context should be presented to the user in some way. So far, that means when the user has a choice of selecting this location context from the TV's Weather channel to view its forecast. This is a tokenizable string. |
Totems | |
AllowWeatherTotem |
Optional. A map of weather type Ids to boolean values setting whether or not a custom weather totem should be allowed to work in this location context. Example: |
TV Forecast | |
IncludeInWeatherChannel |
Optional. Whether or not this location context should be included in the TV's Weather channel. Default: |
WeatherChannelCondition |
Optional. A game state query to determine whether or not the player should currently see this location context in the TV's Weather channel. |
WeatherForecastPrefix |
Optional. A string that is displayed by the TV's Weather channel before the weather-specific string. As an example, the base game uses this for Ginger Island's forecast. This is a tokenizable string. |
TV Forecast: Sprites | |
WeatherChannelBackgroundTexture |
Optional. The asset name of a texture that should be displayed as the background of the TV's Weather channel when viewing the weather for this location context. This can be used to change the background behind the meteorologist. |
WeatherChannelBackgroundSource |
Optional. The position of the top-left corner of the first frame of the
TV's Weather channel background. Each background frame is 42 by 28 pixels.
This is ignored if If there are multiple frames, they are assumed to be laid out in a horizontal strip. Example: |
WeatherChannelBackgroundFrames |
Optional. How many frames of animation does the TV's Weather channel
background have. This is ignored if Default: |
WeatherChannelBackgroundSpeed |
Optional. How long should each frame of the TV's Weather channel background
animation be displayed, in milliseconds? This is ignored if
Default: |
WeatherChannelOverlayTexture |
Optional. The asset name of a texture that should be displayed as the foreground of the TV's Weather channel when viewing the weather for this location context. This can be used to replace the entire image, or to replace the meteorologist specifically. |
WeatherChannelOverlayIntroSource |
Optional. The position of the top-left corner of the first frame of the
TV's Weather channel intro foreground. Each frame is 42 by 28 pixels.
This is ignored if If there are multiple frames, they are assumed to be laid out in a horizontal strip. This is, specifically, for the foreground animation that plays while the user is selecting which region they would like to view the forecast for. |
WeatherChannelOverlayIntroFrames |
Optional. How many frames of animation does the TV's Weather channel
intro foreground have. This is ignored if Default: |
WeatherChannelOverlayIntroSpeed |
Optional. How long should each frame of the TV's Weather channel intro
foreground animation be displayed, in milliseconds? This is ignored if
Default: |
WeatherChannelOverlayWeatherSource |
Optional. The position of the top-left corner of the first frame of the
TV's Weather channel weather foreground. Each frame is 42 by 28 pixels.
This is ignored if If there are multiple frames, they are assumed to be laid out in a horizontal strip. This is, specifically, for the foreground animation that plays while the player is viewing the forecast in the region. While this plays, the forecasted weather's icon will be displayed over this foreground animation. If this is not set, it is assumed to be positioned directly to the right of the last intro foreground frame. |
WeatherChannelOverlayWeatherFrames |
Optional. How many frames of animation does the TV's Weather channel
weather foreground have. This is ignored if Default: |
WeatherChannelOverlayWeatherSpeed |
Optional. How long should each frame of the TV's Weather channel weather
foreground animation be displayed, in milliseconds? This is ignored if
Default: |
As an example, Cloudy Skies itself includes the following data to support the three location contexts in the base game:
{
"Default": {
"Id": "Default",
"DisplayName": "[LocalizedText location.stardew-valley]",
"IncludeInWeatherChannel": true
},
"Desert": {
"Id": "Desert",
"DisplayName": "[LocalizedText Strings\\StringsFromCSFiles:Utility.cs.5861]",
"IncludeInWeatherChannel": true,
"WeatherChannelCondition": "PLAYER_HAS_MAIL Host ccVault Any",
"WeatherChannelBackgroundTexture": "LooseSprites\\map",
"WeatherChannelBackgroundSource": {"X": 0, "Y": 0},
"WeatherChannelBackgroundFrames": 1
},
"Island": {
"Id": "Island",
"DisplayName": "[LocalizedText Strings\\StringsFromCSFiles:IslandName]",
"IncludeInWeatherChannel": true,
"WeatherChannelCondition": "PLAYER_HAS_MAIL Current Visited_Island Any",
"WeatherForecastPrefix": "[LocalizedText Strings\\StringsFromCSFiles:TV_IslandWeatherIntro]",
"WeatherChannelOverlayTexture": "LooseSprites\\Cursors2",
"WeatherChannelOverlayIntroSource": {"X": 148, "Y": 62},
"WeatherChannelOverlayIntroFrames": 1,
"WeatherChannelOverlayWeatherSource": {"X": 148, "Y": 62},
"WeatherChannelOverlayWeatherFrames": 1
}
}
Cloudy Skies has the following console commands:
Invalidate the cached effects and layers, causing them to be reinitialized. Useful if working on C# stuff that changes how effects or layers work.
List all the known weather types, including how many effects and layers they have, which locations they are active in, and which locations they will be active in tomorrow.
Change tomorrow's weather in your current location to use the weather type with the provided Id. This acts as though you used a custom weather totem.
Note: This obeys the weather totem permissions, and will not override forced weather likes
Festival
andWedding
.
Targets:
modData
on individual item instancesCustomFields
inData/Objects
This can be used either as modData
or by setting a custom field
on an object. Either way, the value should be the Id of whatever
weather type you want the totem to change tomorrow's weather to.
When the player uses the totem, it will act like a Rain Totem,
but for whatever weather is specified.
Target:
CustomFields
inData/LocationContexts
This can be used to control whether or not a custom weather totem
for the weather type with the Id [ID]
can be used to override
tomorrow's weather in the relevant location context.
The value should be true
or false
Note: This takes priority over the Location Context Extension Data model, but is only provided as an alternative for ease of use.
Cloudy Skies adds the following trigger action actions to the game:
Note: If using the
debug action
command to test commands, you should be aware of a bug in the game causing quotation marks to not be handled correctly bydebug action
. You may need to escape your quotation marks.
Convert the fruit trees within the provided target area(s)
into another type of fruit tree. As an example, here's a command that
will instantly convert any fruit trees within 5 tiles of the player
into apple trees (which have an Id of 633
):
leclair.cloudyskies_ConvertFruitTrees 633 Player Current 5
Note: This command only affects fruit trees, and not wild trees.
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of fruit trees to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given fruit tree will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
--change-fruit |
If this flag is set, any existing fruit will be changed to match the new tree type. This may result in fruit being removed if the new tree is not in season and fruit cannot grow. |
--only-mature |
If this flag is set, only mature fruit trees will be converted. All other trees will be skipped. |
--set-days <days> |
Set the 'days until mature' field of any changed fruit trees to this value.
Setting this to |
-q <string> , --query <string> |
An optional game state query
for filtering which fruit trees are affected. For performance reasons, you
should avoid using The The |
Convert the trees within the provided target area(s)
into another type of tree. As an example, here's a command that
will instantly convert any trees within 5 tiles of the player
into mushroom trees (which have an Id of 7
):
leclair.cloudyskies_ConvertTrees 7 Player Current 5
Note: This command only affects wild trees, and not fruit trees.
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of trees to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tree will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-q <string> , --query <string> |
An optional game state query
for filtering which trees are affected. For performance reasons, you should
avoid using The |
Apply fertilizer to dirt tiles and Garden Pots within the provided target area(s). As an example, here's a command that applies Speed-Gro to all tilled dirt and pots in the current location:
leclair.cloudyskies_FertilizeDirt (O)465 Location Here
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of tiles to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tile will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-q <string> , --query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has a crop planted, the |
Advance crop growth within the provided target area(s). As an example, here's a command that will instantly grow any pumpkins within 5 tiles of the player to maximum growth:
leclair.cloudyskies_GrowCrops -q "ITEM_ID Input (O)490" --days 13 Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of tiles to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tile will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-d <number> , --days <number> |
The number of days of growth each crop should experience. Must be a positive integer. Default: |
--max-days <number> |
The maximum number of days of growth each crop should experience. If this
is set, each crop will grow a random number of days between |
-q <string> , --query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has a crop planted, the |
--fertilizer-query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has been fertilized, the |
Advance the growth of fruit trees within the provided target area(s). As an example, here's a command that will instantly grow any fruit trees within 5 tiles of the player into their fully grown state, but does not cause fruit to grow:
leclair.cloudyskies_GrowFruitTrees --days 112 --max-fruit 0 5 Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of trees to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tree will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
--days <number> |
The number of days of growth each fruit tree should experience. Default: |
--max-fruit <number> |
The maximum number of fruit we should attempt to grow on any given fruit tree. If the tree already has at least this many fruit, we won't try to grow any additional fruit. This also respects the individual tree's fruit limit, and won't cause a tree to spawn more fruit than it should.
Default: |
-q <string> , --query <string> |
An optional game state query
for filtering which fruit trees are affected. For performance reasons, you
should avoid using The The |
Make giant crops grow within the provided target area(s) if it's possible. As an example, here's a command that will instantly grow any pumpkins within 5 tiles of the player into giant crops:
leclair.cloudyskies_GrowGiantCrops -q "ITEM_ID Input (O)490" --allow-immature Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of tiles to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tile will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
--allow-immature |
If this flag is set, we will allows crops that aren't yet mature to grow into giant crops. |
--ignore-size |
If this flag is set, we will ignore size requirements for giant crops and allow any crop to grow into a giant crop, even if it doesn't have the necessary other crops next to it, as long as there is open space to grow. |
--allow-anywhere |
If this flag is set, we will ignore locations that are not flagged with
|
-q <string> , --query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has a crop planted, the |
--fertilizer-query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has been fertilized, the |
Grow moss on the trees within the provided target area(s). As an example, here's a command that will has a 50% chance to grow moss on each tree within 5 tiles of the player:
leclair.cloudyskies_GrowMoss -c 0.5 Player Current 5
Note: This command only affects wild trees, and not fruit trees.
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of trees to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tree will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-q <string> , --query <string> |
An optional game state query
for filtering which trees are affected. For performance reasons, you should
avoid using The |
Advance the growth stage of trees within the provided target area(s). As an example, here's a command that will instantly grow any trees within 5 tiles of the player into their fully grown state:
leclair.cloudyskies_GrowTrees --stages 5 Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of trees to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tree will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-s <number> , --stages <number> |
The number of stages of growth each tree should experience. Trees generally
have 6 total stages, where |
--max-stage <number> |
The maximum growth stage any given tree should be allowed to reach as a result of this action. Default: |
-q <string> , --query <string> |
An optional game state query
for filtering which trees are affected. For performance reasons, you should
avoid using The |
Kill the crops growing within the provided target area(s). As an example, here's a command that kills any pumpkins growing on Ginger Island:
leclair.cloudyskies_KillCrops -q "ITEM_ID Input (O)490" Context Island
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of tiles to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tile will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-q <string> , --query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has a crop planted, the |
--fertilizer-query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has been fertilized, the |
Remove moss from the trees within the provided target area(s).
As an example, here's a command that will remove all moss on trees
in either the Farm
or Town
maps:
leclair.cloudyskies_KillMoss Location Farm Location Town
Note: This command only affects wild trees, and not fruit trees.
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of trees to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tree will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-q <string> , --query <string> |
An optional game state query
for filtering which trees are affected. For performance reasons, you should
avoid using The |
Spawns forage within the provided target area(s). As an example, here's a command that will spawn random fish in all valid forage locations within 5 tiles of the player:
leclair.cloudyskies_SpawnForage -i ALL_ITEMS -iq "ITEM_CATEGORY Target -4" Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of forage to spawn. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tile will spawn a forage, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
--include-default |
If this flag is set, the location's default forage items will be added to the list of possible forage to spawn. By default, we only spawn the items you provide to the action as arguments. |
--ignore-spawnable |
If this flag is set, we will not skip tiles without a |
-i <string> , --item <string> |
Add an item to the list of potential forage to spawn. This supports item queries. |
-iq <string> , --item-query <string> |
An optional game state query
to apply to the last added |
-q <number> , --item-quality <number> |
An optional quality to apply to the last added |
Remove fertilizer from dirt tiles and Garden Pots within the provided target area(s). As an example, here's a command that removes fertilizer from any dirt and pots that have Speed-Gro in the current location:
leclair.cloudyskies_UnFertilizeDirt --fertilizer-query "ITEM_ID Input (O)465" Location Here
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of tiles to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tile will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-q <string> , --query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has a crop planted, the |
--fertilizer-query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has been fertilized, the |
Rewind the growth stage of trees within the provided target area(s). As an example, here's a command that will instantly revert any trees within 5 tiles of the player into saplings:
leclair.cloudyskies_UnGrowTrees --min-stage 2 --stages 100 Player Current 5
Note the use of an arbitrarily large number for --stages
in this example, in case any mods have added trees with
more growth stages.
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of trees to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tree will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-s <number> , --stages <number> |
The number of stages of growth each tree should experience. Trees generally
have 6 total stages, where |
--min-stage <number> |
The minimum growth stage any given tree should be allowed to reach as a result of this action. Default: |
-q <string> , --query <string> |
An optional game state query
for filtering which trees are affected. For performance reasons, you should
avoid using The |
Un-water watered dirt tiles and Garden Pots within the provided target area(s). As an example, here's a command that will un-water any pumpkins within 5 tiles of the player:
leclair.cloudyskies_UnWaterDirt -q "ITEM_ID Input (O)490" Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of tiles to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tile will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-q <string> , --query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has a crop planted, the |
--fertilizer-query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has been fertilized, the |
Un-water watered pet bowls within the provided target area(s). As an example, here's a command that will un-water any pet bowls within 5 tiles of the player:
leclair.cloudyskies_UnWaterPets Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of pet bowls to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given pet bowl will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
Deprecated. Please use leclair.cloudyskies_WaterDirt
instead.
Water un-watered dirt tiles and Garden Pots within the provided target area(s). As an example, here's a command that will water any pumpkins within 5 tiles of the player:
leclair.cloudyskies_WaterDirt -q "ITEM_ID Input (O)490" Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of tiles to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given tile will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
-q <string> , --query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has a crop planted, the |
--fertilizer-query <string> |
An optional game state query
for filtering which tiles are affected. For performance reasons, you should
avoid using If the tile has been fertilized, the |
Water un-watered pet bowls within the provided target area(s). As an example, here's a command that will water any pet bowls within 5 tiles of the player:
leclair.cloudyskies_WaterPets Player Current 5
Option | Description |
---|---|
-h , --help |
View usage information for this action. |
--max <number> |
The maximum number of pet bowls to change. Must be a positive integer. Default: |
-c <number> , --chance <number> |
The percent chance that any given pet bowl will be changed, from Default: |
--indoors |
If this flag is set, indoor locations will not be skipped. They are skipped by default. |
Most of Cloudy Skies' custom trigger actions use a flexible <target>
argument
that accepts several different forms, making it easy to target entire regions
or specific tiles. The following forms are permitted:
Target the full map of each location within the provided location context(s).
You can use All
to match all contexts, Here
to match the context of the
current location, or provide the Id of a specific context to target.
Target the full map of the provided location(s). You can use All
to match
all locations, Here
to match the current location, Indoors
or Outdoors
to match all thus described locations, or provide the name of a specific
location to target.
Target a specific tile of the provided location(s). You can use All
to match
all locations, Here
to match the current location, or provide the name
of a specific location to target.
x
and y
are the X and Y tile coordinates to target, and radius
is the
radius to extend from the targeted tile. Use 1
to only target one
specific tile.
Target a number of random tiles of the provided location(s). You can use All
to match all locations, Here
to match the current location, Indoors
or
Outdoors
to match all thus described locations, or provide the name of a
specific location to target.
minCount
and maxCount
are used to determine how many random tiles should
be selected. The system will pick at least minCount
and at most maxCount
tiles. Please note that these tiles are not checked for uniqueness.
minX
and maxX
define the bounds of the X coordinate to target. Please note
that if you provide a minX
less than zero, it will be set to zero. If you
provide a maxX
greater than the target map's width, it will be reduced to
the target map's width.
minY
and maxY
define the bounds of the Y coordinate to target. Please note
that if you provide a minY
less than zero, it will be set to zero. If you
provide a maxY
greater than the target map's height, it will be reduced to
the target map's height.
minRadius
and maxRadius
define the bounds of the radius to target around
the target tile.
As an example, here's a target that will pick 5 to 10 random locations on the
Farm
map with a small radius:
RandomTile Farm 5 10 0 1000 0 1000 2 4
Here, we've used 1000
as an arbitrarily large value for maxX
and maxY
.
It doesn't matter that they're that big, because they'll be reduced to fit
the actual map's size.
Target the current position of the specified player. You can use All
to
match all online players, Current
to match the current player, Host
to match the hosting player, or provide the unique multiplayer ID of a
player to target them specifically.
radius
is the radius to extend from the targeted player. Use 1
to only
target the one specific tile they're standing on.
Target the current position of the specified NPC. You can use All
to
match all NPCs, or provide the internal name of an NPC to target
them specifically.
radius
is the radius to extend from the targeted NPC. Use 1
to only
target the one specific tile they're standing on.
Cloudy Skies adds the following game state queries to the game:
Whether the given location
is flagged to ignore debris weather. You can use this query to hide your
Debris
layers in such locations.
The weather Id in the given location. This allows you to check the weather
up to one week in the past by setting offset to a non-zero value. You can also
provide more than one weatherId to match multiple possible weather types.
For example, using CS_WEATHER Here -1 Rain Storm
will check if the weather
yesterday was either Rain
or Storm
.
Whether the weather at the given location
has the IsRaining
weather flag.
If you set offset
to a non-zero value, it will check the weather on that
day instead. For example, you can check if it was raining yesterday by
using CS_WEATHER_IS_RAINING Here -1
.
Cloudy Skies records a full week of historical weather data.
Whether the weather at the given location
has the IsSnowing
weather flag.
If you set offset
to a non-zero value, it will check the weather on that
day instead. For example, you can check if it was snowing two days ago by
using CS_WEATHER_IS_SNOWING Here -2
.
Cloudy Skies records a full week of historical weather data.
Whether the weather at the given location
has the IsLightning
weather flag.
If you set offset
to a non-zero value, it will check the weather on that
day instead. For example, you can check if it was lightning yesterday by
using CS_WEATHER_IS_LIGHTNING Here -1
.
Cloudy Skies records a full week of historical weather data.
Whether the weather at the given location
has the IsDebrisWeather
weather flag.
If you set offset
to a non-zero value, it will check the weather on that
day instead. For example, you can check if it was debris weather yesterday by
using CS_WEATHER_IS_DEBRIS Here -1
.
Cloudy Skies records a full week of historical weather data.
Whether the weather at the given location
has the IsGreenRain
weather flag.
If you set offset
to a non-zero value, it will check the weather on that
day instead. For example, you can check if it was green raining yesterday by
using CS_WEATHER_IS_GREEN_RAINING Here -1
.
Cloudy Skies records a full week of historical weather data.
This token represents the weather flags of the current location. Possible values:
Raining
Snowing
Lightning
Debris
GreenRain
Sunny
(present if none of the previous value are present)Music
(present ifMusicOverride
is set)NightTiles
(present ifUseNightTiles
is set)WaterCrops
(present ifWaterCropsAndPets
is true (or not set andRaining
is true))