Weather Configuration
Register weather types — timing, server-side Lua hooks, and client-side visual layers — in a single per-mod config file.
Weather types are full-screen effects (rain, snow, fog, and similar) that the server randomly cycles through, each running for a randomized duration before transitioning to the next. A single file defines everything about a weather type: its timing, its optional server-side Lua behaviour, and its client-side visuals (animated layers and an optional shader).
Each entry is organised into up to three blocks by which side of the game owns it:
timing— how long the weather lasts and how long it fades in and out. Shared scheduling.scripts— optional server-side Lua hooks.client— optional client-side visuals: shader, scrolling, and animated layers.
How often a weather occurs is not set here. A registered weather only appears in the world when a biome lists it under
weather-options(with aweight). See the biome terrain config. This file only defines what each weather type is.
At load time the server cross-checks the two sides and logs a warning if a biome references a weather name that no config registered (usually a typo), or if a registered weather is referenced by no biome (so it can never occur). Watch the server log if a weather you expect never shows up.
File Location
Register the file in your mod’s manifest (mods/<YourMod>/<YourMod>.yaml):
weather-config: weather-config.yaml
Then create the file it points to, relative to your mod’s folder:
mods/<YourMod>/weather-config.yaml
The file is a single list of weather entries:
weathers:
- name: my_weather
timing:
min-ms: 20000
max-ms: 40000
transition-out-ms: 5000
Weather names are automatically prefixed with your mod name unless you write one already containing a colon, so my_weather becomes YourMod:my_weather.
Layer PNG images live under your mod’s texture folder, named after each layer’s name field (case-sensitive):
mods/<YourMod>/assets/textures/weathers/<layer name>.png
Minimal Example
A weather with no server behaviour and no visuals (a clear/calm type):
weathers:
- name: clear_skies
timing:
min-ms: 20000
max-ms: 40000
transition-out-ms: 5000
Fields
Top level
| Field | Required | Description |
|---|---|---|
name | Yes | The weather type’s registered name (auto-prefixed with your mod name). |
timing | Yes | The scheduling block. See below. |
scripts | No | Server-side Lua hooks — server-update, server-on-start, server-on-end. An unrecognized hook name fails the weather at load. See Shared Blocks → scripts. Omit for a weather with no server logic. |
client | No | Client-side visuals. Omit for an invisible/default-look weather. |
A missing or wrong-typed field discards the whole weather entry (logged as an error). Because each block is validated strictly, a misspelled key inside timing or scripts is reported at load time rather than silently ignored.
timing
| Field | Required | Default | Description |
|---|---|---|---|
min-ms | Yes | — | Minimum time this weather runs before transitioning out, once selected. |
max-ms | Yes | — | Maximum time this weather runs. The server picks a random duration in [min-ms, max-ms] each time this weather starts. |
transition-out-ms | Yes | — | How long the weather overlay fades out when this weather ends and another begins. |
transition-in-ms | No | 0 | How long the weather overlay fades in when this weather starts. 0 (the default) makes it appear instantly. |
The fade is a client-side cross-fade: when the active weather changes, the old type fades out over its transition-out-ms, then the new type fades in over its transition-in-ms.
scripts
All three hooks are optional. Each is declared as a bare path to a .lua file that returns its handler function (the same shape as items’ server-on-primary-use). See the Server Weather API for hook signatures.
| Key | When Called |
|---|---|
server-update | Every server tick while this weather is active. |
server-on-start | Once when this weather starts in a region. |
server-on-end | Once when this weather ends in a region, just before the next weather starts. |
scripts:
server-update: /weathers/my-weather/scripts/server_update.lua
server-on-start: /weathers/my-weather/scripts/server_on_start.lua
server-on-end: /weathers/my-weather/scripts/server_on_end.lua
client
| Field | Required | Default | Description |
|---|---|---|---|
shader | No | (engine default) | A namespaced shader name applied while this weather is active. See shader config. |
vertical-loop | No | — | If present, all layers scroll downward. |
vertical-loop.pixels-per-second | Yes (if vertical-loop present) | — | Downward scroll speed in pixels per second. |
layers | Yes (if client present) | — | One or more animated layers, drawn in declaration order (first = bottom). |
Layer fields
| Field | Required | Default | Description |
|---|---|---|---|
name | Yes | — | Base name of the PNG file. The file must be <name>.png in assets/textures/weathers/. Matches the name used by healthbar and biome-backdrop textures. |
frame-count | Yes | — | How many frames the animation has. Use 1 for a static layer. |
frame-width | Yes | — | Width of a single frame in pixels. |
frame-height | Yes | — | Height of a single frame in pixels. |
frame-time-ms | No | 100 | Default milliseconds per frame. Used when frame-durations-ms is absent. |
frame-durations-ms | No | — | Per-frame timing override. See Per-Frame Timing. |
parallax | No | 1.0 | Horizontal scroll speed multiplier relative to the base speed. |
direction | No | right | Horizontal scroll direction: left or right (case-insensitive; lowercase matches what ships). |
scale-resolution | No | 1.0 | Scale factor applied to the layer. |
Sprite Sheet Format
Each layer is a single PNG containing all animation frames in a horizontal strip:
[ frame 0 ][ frame 1 ][ frame 2 ] …
- Total image width =
frame-width × frame-count - Total image height =
frame-height - Frames are read left to right during playback
For a static layer (frame-count: 1), the image is just the single full-size frame.
Per-Frame Timing
By default, all frames display for the same duration (frame-time-ms). To give individual frames different hold times, add frame-durations-ms to the layer.
Two entry formats are supported and can be mixed freely:
Flat — one value per frame:
frame-durations-ms: [200, 200, 200, 3000]
Batch — a duration applied to several consecutive frames:
frame-durations-ms:
- count: 3
duration-ms: 200
- count: 1
duration-ms: 3000
Both produce the same result: frames 0–2 last 200 ms each, frame 3 lasts 3000 ms.
Note: The total number of entries (after expanding batches) must equal
frame-countexactly. If the counts do not match,frame-durations-msis ignored andframe-time-msis used for all frames instead.
Complete Example
Based on the real shipped weather types — a plain sunny type, a static rain layer, and an animated snow type with server hooks and mixed frame timing:
weathers:
- name: sunny
timing:
min-ms: 30000
max-ms: 45000
transition-out-ms: 5000
- name: rainy
timing:
min-ms: 20000
max-ms: 40000
transition-in-ms: 4000
transition-out-ms: 5000
client:
layers:
- name: rainy
frame-count: 1
frame-width: 1920
frame-height: 1080
frame-time-ms: 300
- name: snowy
timing:
min-ms: 25000
max-ms: 35000
transition-in-ms: 4000
transition-out-ms: 5000
scripts:
server-update: /weathers/snowy/scripts/server_update.lua
server-on-start: /weathers/snowy/scripts/server_on_start.lua
client:
vertical-loop:
pixels-per-second: 25
layers:
- name: snowy
frame-count: 16
frame-width: 1920
frame-height: 1080
frame-time-ms: 200
parallax: 5.0
direction: left
frame-durations-ms:
- count: 8
duration-ms: 200
- count: 8
duration-ms: 3000
See Also
- Server Weather API — hook signatures and the weather region object.
- Biome terrain config — assigning weathers to biomes and setting their occurrence weights.