Mod loader
Fabric
Minecraft version
26.1.2
Mod version
26.0.2 (branch 26.1-fabric, built from source)
Modloader version
Fabric: Loader 0.18.6 + API 0.147.0+26.1.2
Modpack info
No response
[IMPORTANT] If bug:
[IMPORTANT] If bug: The latest.log file, not the crash report
No response
Issue description
This is a bug report with an already working implementation of the suggested fix in my fork, which is described below, running on Fabric 26.1.2. I beg you to read this issue entirely, because I explain everything in details. I opened this issue to discuss the idea, and if you think it's good I'd like to open a PR.
This is specifically about unlimited snow accumulation: accumulation.maxLayers = 9 with smoothAccumulation = true. In capped accumulation (accumulation.maxLayers =< 8) a column tops out at one block, so the defect has no room to express itself. It is only once columns can grow past their starting block that it becomes the dominant visual.
In that configuration, snow smooths out nicely on flat ground, but on sloped terrain it does not. It forms a set of flat plateaus, one per terrain level, separated by vertical snow walls that never close and once a step exists it is permanent, because uniform accumulation preserves the height difference between two areas that never exchange snow.
The result on a mountainside is a stack of frozen mesas rather than a mantle following the relief:
Reproduction steps.
- Set
accumulation.maxLayers = 9 and smoothAccumulation = true
- Also set
accumulation.accumulatesDuringSnowfall = true (its default is false; without it or a thunderstorm, column growth never starts)
- Find a snowy mountain with a multi-block terrain step
- Let snow accumulate for a while
- The step stays sharp, and the areas above and below it level out independently
As I read Hooks#accumulate, the smoothing scan has two properties that together cause this:
- It samples 4 cardinal directions at distance 1 and 2 (8 samples, no diagonals), and skips any neighbour whose
MOTION_BLOCKING heightmap Y is not equal to the center's, because the +1 exception only covers a neighbour that already holds a snow variant.
- It compares
srm$layers of the center against srm$layers of the neighbour, the layer counts relative to its base block, not absolute surface heights. This makes the scan only be able to move snow between columns that sit at the same Y. That is exactly the case that does not need smoothing, any real slope is filtered out before the comparison happens, and a column that grows past the block it started in stops comparing meaningfully against its neighbours, which is why the symptom is specific to unlimited accumulation.
So, my proposed approach to this is to replace the altitude equality guard with a gradient criterion, and measure columns by absolute snow-surface height in 1/8 layers rather than by layer count within a block. Sample the 8 immediate neighbours (4 cardinal at distance 1, 4 diagonal at distance √2) and split into two regimes:
- Above the angle of repose —> the drop to a neighbour is steeper than snow can physically hold, so the steepest one wins outright and the layer avalanches. This is what eats a terrain step into a talus ramp instead of letting it freeze into a wall.
- Below the angle of repose —> the layer relaxes onto the lowest neighbour at a flat chance. This is the surface-relaxation term that keeps random deposition from building a rough surface. Pacing is unchanged: exactly one layer added or removed per tick, placed through
placeLayersOn / accumulateSingle as before.
Here are the results in-game:
With less than 1 block of accumulation:

With around 5 blocks of accumulation:

As you can see, even after some considerable accumulation it gets smooth, even in cliffs, following terrain ups and downs smoothly and realistically, like in these examples as well:
In melting, it also creates realistic features, such as snow leftovers on cliff sides (I was using Serene Seasons to get snow and then melting, the combo of these two mods played out really well after the change):
Also, as I didn't want to mess up to compatibility stuff and other config settings, I took these precautions:
- Gated behind a single predicate, currently
snowAccumulationMaxLayers > 8 (unlimited mode), matching where the defect actually appears. Every other configuration takes the existing code paths, untouched.
- The
smoothAccumulation == false path and the capped-mode neighbour scan are not modified.
- Melting uses the same model with the sign inverted, so a thaw shrinks the mantle evenly instead of pitting it.
- All existing placement-validity checks are preserved (
CANNOT_ACCUMULATE_ON, canSnowSurvive, snowSpawnMaxLightLevel, the filter predicate), and they still constrain only where snow is added, never where it melts.
- Adds two config options under
accumulation.*: reposeAngle (30–70°, default 50) and smoothingStrength (0–100, default 100).
I did not find a test harness in the repo, so I have no automated coverage to offer. Also, snowfall measured at roughly +3.3 ms of server tick in my instance.
I have a second, unrelated change sitting on the same branch driving melt speed from Serene Seasons via SeasonHooks.getMeltSpeed, which was a way to get snow to melt in different speed depending on season and height, but that API is not in the published Serene Seasons build (Forstride didn't even want to read my issue and labled it as "AI slop", so yeah), so it is not mergeable yet and I am deliberately keeping it out of this proposal. Per the template's "keep problems separate", it will get its own issue if you want it.
Disclosure: I am a Java student and I have used AI (Claude Code) to develop code, since I have a lot of experience with more than a year using it to work with unrelated projects in React.js and Node.js, and know how to use it correctly, but the idea and planning was always done by me. Also, this is my very first attempt on a open-source contribution, and I tried my best to make it nice, but sorry if I made any mistake.
Mod loader
Fabric
Minecraft version
26.1.2
Mod version
26.0.2 (branch
26.1-fabric, built from source)Modloader version
Fabric: Loader 0.18.6 + API 0.147.0+26.1.2
Modpack info
No response
[IMPORTANT] If bug:
[IMPORTANT] If bug: The latest.log file, not the crash report
No response
Issue description
This is a bug report with an already working implementation of the suggested fix in my fork, which is described below, running on
Fabric 26.1.2. I beg you to read this issue entirely, because I explain everything in details. I opened this issue to discuss the idea, and if you think it's good I'd like to open a PR.This is specifically about unlimited snow accumulation:
accumulation.maxLayers = 9withsmoothAccumulation = true. In capped accumulation (accumulation.maxLayers =< 8) a column tops out at one block, so the defect has no room to express itself. It is only once columns can grow past their starting block that it becomes the dominant visual.In that configuration, snow smooths out nicely on flat ground, but on sloped terrain it does not. It forms a set of flat plateaus, one per terrain level, separated by vertical snow walls that never close and once a step exists it is permanent, because uniform accumulation preserves the height difference between two areas that never exchange snow.
The result on a mountainside is a stack of frozen mesas rather than a mantle following the relief:
Reproduction steps.
accumulation.maxLayers = 9andsmoothAccumulation = trueaccumulation.accumulatesDuringSnowfall = true(its default isfalse; without it or a thunderstorm, column growth never starts)As I read
Hooks#accumulate, the smoothing scan has two properties that together cause this:MOTION_BLOCKINGheightmap Y is not equal to the center's, because the+1exception only covers a neighbour that already holds a snow variant.srm$layersof the center againstsrm$layersof the neighbour, the layer counts relative to its base block, not absolute surface heights. This makes the scan only be able to move snow between columns that sit at the same Y. That is exactly the case that does not need smoothing, any real slope is filtered out before the comparison happens, and a column that grows past the block it started in stops comparing meaningfully against its neighbours, which is why the symptom is specific to unlimited accumulation.So, my proposed approach to this is to replace the altitude equality guard with a gradient criterion, and measure columns by absolute snow-surface height in 1/8 layers rather than by layer count within a block. Sample the 8 immediate neighbours (4 cardinal at distance 1, 4 diagonal at distance √2) and split into two regimes:
placeLayersOn/accumulateSingleas before.Here are the results in-game:

With less than 1 block of accumulation:
With around 5 blocks of accumulation:

As you can see, even after some considerable accumulation it gets smooth, even in cliffs, following terrain ups and downs smoothly and realistically, like in these examples as well:
In melting, it also creates realistic features, such as snow leftovers on cliff sides (I was using Serene Seasons to get snow and then melting, the combo of these two mods played out really well after the change):
Also, as I didn't want to mess up to compatibility stuff and other config settings, I took these precautions:
snowAccumulationMaxLayers > 8(unlimited mode), matching where the defect actually appears. Every other configuration takes the existing code paths, untouched.smoothAccumulation == falsepath and the capped-mode neighbour scan are not modified.CANNOT_ACCUMULATE_ON,canSnowSurvive,snowSpawnMaxLightLevel, thefilterpredicate), and they still constrain only where snow is added, never where it melts.accumulation.*:reposeAngle(30–70°, default 50) andsmoothingStrength(0–100, default 100).I did not find a test harness in the repo, so I have no automated coverage to offer. Also, snowfall measured at roughly +3.3 ms of server tick in my instance.
I have a second, unrelated change sitting on the same branch driving melt speed from Serene Seasons via
SeasonHooks.getMeltSpeed, which was a way to get snow to melt in different speed depending on season and height, but that API is not in the published Serene Seasons build (Forstride didn't even want to read my issue and labled it as "AI slop", so yeah), so it is not mergeable yet and I am deliberately keeping it out of this proposal. Per the template's "keep problems separate", it will get its own issue if you want it.Disclosure: I am a Java student and I have used AI (Claude Code) to develop code, since I have a lot of experience with more than a year using it to work with unrelated projects in React.js and Node.js, and know how to use it correctly, but the idea and planning was always done by me. Also, this is my very first attempt on a open-source contribution, and I tried my best to make it nice, but sorry if I made any mistake.