Making it snow on a plains farm: faking winter weather in Minecraft Bedrock

Bedrock has no snow weather and decides rain-or-snow from the biome. How LLS Seasons builds a snowy day from fog, a particle and a snow carpet of its own, and the summer freeze a snow sweep caused.

· 7 min read

Snow falling on a cleared field in the LLS Farm Sim Pack in winter

The Farm Sim Pack has a 28-day year, and the calendar is only convincing if the world changes with it. Summer is clear, autumn storms, and winter snows, including on a plains farm. That last part is where Bedrock pushes back hardest.

Bedrock can’t snow on demand

A script can set the weather to one of three things: Clear, Rain or Thunder. There is no snow. Whether falling precipitation looks like rain or snow is decided on each player’s client from the biome’s temperature, and no script can change that.

So in a cold biome, Rain shows snow. Everywhere else, Rain shows rain. My first plan was to ride vanilla Rain on snowy days, which works in a taiga and is wrong on a plains farm: you get falling raindrops and snow on the ground at the same time.

The answer was to stop using vanilla weather for snow altogether.

A snowy day is three effects

On a snowy day the sky is set to Clear, so vanilla draws no precipitation at all, and three things stand in for snow:

  1. Overcast fog. Rain darkens the sky; Clear doesn’t. A grey fog shipped in the resource pack is pushed onto every player for the day, so the sky closes in the way it should.
  2. Falling snow. A particle effect drops flakes around each player who’s outdoors. Players in hot biomes are skipped, and that biome check is cached per player rather than repeated twice a second.
  3. Snow on the ground. A carpet of snow blocks is laid around players and farms on the first day of winter and deepens a step each snowy day, up to six eighths of a block. I stopped short of a full block deliberately: near-full snow noticeably slows walking, and six already reads as deep.

Fog isn’t a vanilla weather type either, so it gets its own roll. Each season rolls its chances independently every calendar day:

SeasonThe sky
Spring20% rain, otherwise clear
SummerClear, every day
Autumn25% thunderstorm, else 60% rain; 40% fog on top of anything; the last day always snows
Winter60% snow; 20% fog on top

The day’s roll is stored, so reloading the world gives the same sky. If anything outside the pack changes the weather (vanilla’s own weather cycle, or sleeping through a storm), the pack puts the day’s weather back as soon as it notices.

The carpet kept melting

Laying snow is easy. Keeping it is not. Vanilla melts snow_layer on random ticks wherever the biome is warm or the light is bright, which is everywhere on a plains farm. A freshly laid carpet was pocked with bare squares within minutes.

The first fix was a repair pass: every so often, find the holes and fill them. It worked, and it looked broken. Random ticks are scattered, so the melt took the field one block at a time, and each hole sat bare until the next repair pass popped it back in, often right in front of the player. Melt, then repaint doesn’t read as weather. It reads as a bug.

First fix: switch random ticks off

The first real fix stopped the melting at the source. While winter had snow on the ground, the pack set randomtickspeed to 0, and handed the world’s own value back at the thaw. That’s a world-wide hammer, so it was held for the narrowest window possible: winter, and only while there was carpet down.

It was only affordable because Farm Sim crops don’t grow on random ticks; they run on a day counter, one stage at midnight. But everything else that does paused for the week: saplings, sugar cane, cactus, bamboo, cocoa, nether wart, mushrooms, fire spread, copper oxidising, leaf decay. A tree chopped down in winter kept its leaves until spring. It worked, and it reached into far more of the world than snow has any right to.

The real fix: snow of its own

Since 0.6.5 the carpet isn’t vanilla snow at all. It’s llss:snow_layer, a block of the pack’s own with the same eight heights as vanilla snow and no random-tick behaviour. Nothing melts it except the pack itself, so random ticks stay on all winter and saplings keep growing.

It fixed a second problem too. The old passes placed and removed minecraft:snow_layer, so the spring thaw could also clear vanilla snow: a cold biome’s, a snow golem’s, or snow a player put down on purpose. Now every pass only touches its own block, and vanilla snow is never touched.

Worlds that ran the old version come back to their own randomtickspeed automatically: the value saved during an old winter is restored, not Bedrock’s default.

The repair pass is still there as a safety net for holes the game didn’t make: a patch a player dug out, a chunk that loaded after the lay pass, a layer washed off by water.

Making a big job not freeze the game

A season of farming covers a lot of ground, and laying or thawing snow over all of it is hundreds of thousands of block columns. Done in one go, that stalls the server.

Each pass runs as a job: a generator handed to system.runJob, which Bedrock advances a little each tick. The catch is that a job moves at one step per tick it’s given, however much work each step does. With one column per step, a full thaw was measured at a pace that would take longer than a real year. So each step handles a batch of columns before it yields. The batch size is the one dial between “visibly slow” and “the server stutters”.

The pack also has to remember where it laid snow, or it can never thaw it. Every time a player moves half a radius into fresh ground, the new spot is added as a “carpet centre”. Up to 300 centres are kept, which holds a season of real farming in a list small enough to store with the world.

Hot and cold biomes

Snow shouldn’t fall in a desert, and only cold biomes should keep it once spring comes. The script API version this pack targets has no getBiome() call, so climate is read the way a command block would: execute if biome against a short list of hot and cold biome IDs, tried until one matches.

That’s slow if you do it for every column, so it’s done once per carpet centre and cached on it. At worst a centre right on a biome border gets the wrong call, which is a far smaller problem than stalling the server to check every block.

Spring, and the freeze it caused

The thaw runs over the first days of spring: a couple of visible days of the carpet getting shallower a level at a time, then a final pass clears whatever’s left outside cold biomes.

After that, a guardrail keeps snow out of warm biomes until autumn ends, in case a chunk that was unloaded at the thaw loads later with snow still on it. The first version of that guardrail cost me a week of confusion. Every 15 seconds it re-wiped snow around every stored carpet centre (up to 300 of them, 64 blocks each) and every player, in one go, without ever yielding, and it threw an error on every column in an unloaded chunk.

In game that was a three-second freeze every eighteen seconds all summer. It looked like a horse bug and like lag from other packs. The clue was in the content log: repeated [Watchdog] Spike lines, evenly spaced. The spacing between spikes is the timer’s period plus the stall itself, because game ticks don’t advance during a stall. Eighteen seconds minus a three-second stall is fifteen, which was exactly that timer.

The guardrail now runs as its own small job on a two-second timer: only centres near a player, a cheap check that a chunk is loaded before touching its columns, nearest chunk first, a few hundred columns per tick, and a centre is crossed off the list for good once all its chunks have been swept. The freeze is gone as of 0.6.5.

Some numbers in this system are only right because they were measured in a real farm world. The reach around each player (64 blocks) is limited by simulation distance: chunks further out aren’t loaded, so the script can’t place snow in them, and a debug readout counts those misses so I can tell whether a larger radius would actually help.

Try it

The seasons, the snow and the crop calendar are all in the Farm Sim Pack. The first-year guide is a season-by-season plan for a new farm. If you use /time set and wonder why winter won’t end: it moves the sun, not the calendar. Use /scriptevent llss:setseason spring.

The mod

More from the devlog

← All devlog