CurseForge · Minecraft mod
Sablewaves
Minecraft’s oceans were never meant to stay flat. With Sablewaves you can experience Minecraft the way it was meant to be.
Quick answer
Which Sablewaves release matches 1.21.1 NeoForge?
sablewaves-2.23.2.jar targets 1.21.1 with NeoForge. The project page does not say whether this file belongs on the client, dedicated server, or both. No extra mods listed for this file.
Where it goes
Is Sablewaves required on the client, server, or both?
The project page does not say whether this file belongs on the client, dedicated server, or both.
The source does not explicitly classify this release as client-only or server-only.
What else does sablewaves-2.23.2.jar need?
sablewaves-2.23.2.jar on 1.21.1 NeoForge. Every mod below is checked against that same setup.
This file does not list any required mods. Do not add a library just because a different file uses it.
This file does not list any required or optional mods.
Before you install it
Add Sablewaves without breaking your instance.
Built for sablewaves-2.23.2.jar on 1.21.1 NeoForge. Pick another file and the loader, install side or required mods may change.
- 01
Stick to this file
Use sablewaves-2.23.2.jar. It targets 1.21.1 with NeoForge; another release may have different loader, side or dependency requirements.
- 02
Bring the mods it needs
This file does not list any required mods. Do not add a library just because a different file uses it.
- 03
Put it on the correct side
The project page does not say whether this file belongs on the client, dedicated server, or both.
- 04
Pick the file you checked
Use the “Get this file” button beside sablewaves-2.23.2.jar. It opens that exact file at the source.
About this project
What does Sablewaves add?
Sable Waves — Realistic Tides & Swells
A NeoForge 1.21.1 companion mod for the Sable physics engine. It adds a realistic ocean: a visible moving sea surface, ocean currents that carry your ship, moon-driven tides, weather-driven swells that grow tall in thunderstorms, and wind that heels floating craft and buffets airborne ones.
Because Create: Aeronautics ships are Sable physics bodies (sub-levels), everything here affects them automatically — no extra compat needed. The same is true for any boat or craft you assemble with plain Sable.
What it does
Waves. An eight-component Gerstner (trochoidal) wave spectrum rides on top of Sable's native still-water buoyancy. Wave height and wavelength follow the wind Pierson–Moskowitz-style: calm days give gentle half-block ripples; thunderstorms build multi-block rolling swells over about a minute, then decay when the sky clears. Hulls are sampled in a grid of columns, so craft genuinely heave, pitch, and roll as crests pass under them, and wave-orbital drag makes them surge and surf along the wave direction.
Tides (moon-driven). A semidiurnal tide — two highs and two lows per Minecraft day — tracks the moon's transit. Amplitude follows the lunar phase: spring tides at full and new moon, neap tides at the quarters. Thunderstorms add a storm surge on top. (Water blocks don't physically move; the tide shifts the effective flotation level, so moored craft ride visibly higher and lower through the day.)
Wind & aeronautics. A smoothed wind field (speed, direction, gusts) follows the weather. It pushes on the exposed superstructure of floating craft (heel + drift) and — if enabled — gently buffets airborne Sable craft, so Create: Aeronautics airships feel storms aloft. Lift, thrust and control surfaces remain Create: Aeronautics' own aerodynamics; this mod adds the weather those ships fly through.
The visible sea
The ocean is drawn, not just simulated. A moving surface is rendered over the water from the same 8-component Gerstner field the physics uses, with biome-tinted water, crest foam, whitecaps that streak along the wind, sun glint, and shore breakers. The crest you watch roll toward your ship is the exact crest that lifts it — one deterministic wave field, no desync, no networking.
Ocean currents
Four current systems, all deterministic, all individually switchable:
- Ekman wind drift — surface flow at ~3% of wind speed, deflected 45°, rotating with depth until deep water runs against the surface.
- Tidal streams — flood and ebb tracking the tide, fastest mid-tide, slack at the turn.
- Longshore drift and rip currents — alongshore transport ∝ sin(2α) with rips escaping seaward.
- Ocean gyres — a divergence-free streamfunction field thousands of blocks across, with a deep counter-flow underneath.
Currents carry boats, ships and submarines. Surface flow streaks and a movable HUD readout show the flow above water; the Current Locator block draws 3D flow arrows underwater and reports which depth is running fastest.
Sails, wakes and sound
Wool is canvas — exposed wool on a Sable craft catches wind and drives the ship, rescanned every few seconds so you can trim. Moving ships throw bow spray, streak foam down their sides and drag a wake. Swells break on shallow shores. Breakers boom, hulls wash, storm seas roar — all vanilla sound events.
Weather mod integration
- ProtoManly's Weather 0.16.x–0.17.x (+ PMWeatherAPI) — its atmospheric wind field drives the sea state, currents and sails.
- Simple Clouds — the sea reads its localized weather rather than vanilla's whole-world rain flag, so storm cells cross the water properly.
Both are soft dependencies discovered by reflection; without them the internal wind model is used.
Installation
Requires: Minecraft 1.21.1, NeoForge, Sable 2.0+ (and optionally Create: Aeronautics).
Drop the sablewaves-*.jar into your mods/ folder alongside Sable.
The included jar was compiled out-of-toolchain against verified API signatures. If you ever see a linkage error in the log after a Sable update, rebuild from source (below) — the Gradle build compiles against the real published artifacts and is the canonical build.
Configuration
config/sablewaves.json is created on first launch:
| Key | Default | Meaning |
|---|---|---|
wavesEnabled |
true |
Master switch for wave forces |
waveIntensity |
1.0 |
Global wave height multiplier |
maxWaveAmplitude |
3.5 |
Cap on wave amplitude (blocks) |
waveDragMultiplier |
0.35 |
Horizontal surge/surf force from wave motion |
calmWindSpeed |
4.5 |
Fair-weather wind (m/s) |
stormWindBonus |
12.5 |
Extra wind at full thunderstorm (m/s) |
windForceCoefficient |
0.06 |
Wind push on exposed hull; 0 disables wind |
windAffectsAirborne |
true |
Buffet flying craft (Create: Aeronautics ships) |
airborneWindMultiplier |
0.35 |
How strongly wind hits airborne craft |
tidesEnabled |
true |
Master switch for lunar tides |
springTideAmplitude |
1.25 |
Tide semi-amplitude at full/new moon (blocks) |
neapFraction |
0.35 |
Fraction of spring tide left at quarter moons |
stormSurge |
0.9 |
Extra water-level rise at full storm (blocks) |
maxAccelerationG |
1.5 |
Safety cap on wave acceleration (× gravity) |
sampleSpacing |
3.5 |
Hull sample column spacing (blocks) |
maxSamplesPerAxis |
7 |
Max sample columns per axis per craft |
currentsEnabled |
true |
Master switch for ocean currents |
currentStrength |
1.0 |
Global multiplier on all current speeds |
currentMaxSpeed |
2.2 |
Hard cap on current speed (blocks/s) |
ekmanCurrentEnabled |
true |
Wind-driven surface drift with depth spiral |
tidalCurrentEnabled |
true |
Flood/ebb streams tracking the tide |
longshoreCurrentEnabled |
true |
Alongshore drift and rip currents |
gyreCurrentEnabled |
true |
Large rotating gyres with deep counter-flow |
currentStreaks |
true |
Surface streaks showing which way the water runs |
currentHudCorner |
0 |
Where the flow readout sits (0–3, or off) |
waveOverlayEnabled |
true |
Draw the moving sea surface |
waveOverlayBeachFoam |
false |
Water running up over beaches (off by default, see below) |
waveOverlayAdaptiveQuality |
true |
Step detail down automatically to hold the frame budget |
waveOverlayDebug |
false |
Print what the sea costs per frame, once a second |
Building from source
bash
./gradlew build # or: gradle build, with Gradle 8.9+ and Java 21
The build depends on:
dev.ryanhcode.sable:sable-common-1.21.1andsable-neoforge-1.21.1fromhttps://maven.ryanhcode.dev/releases(seebuild.gradle; if thesable-neoforgeartifact id differs on the maven, check the directory listing there and adjust one line)- NeoForge via the ModDevGradle plugin
The stubs/ folder is not part of the mod — it contains compile-verification stubs used to build the jar in an offline environment. You can delete it.
How it works (for the curious)
- Hooks
ForgeSablePrePhysicsTickEvent, which Sable fires every physics sub-step — the correct place to apply external forces. - For each
ServerSubLevel(each physics craft), finds the still-water surface under it, then samples the wave field η(x, z, t) across the hull footprint. - Applies per-column impulses for the difference between wave-sea and still-sea immersion (Sable's native Rapier buoyancy keeps handling flat flotation), plus orbital drag and wind.
- Impulse positions and vectors are transformed into plot-local frame, matching Sable's Rapier bridge convention, and everything is scaled by the sub-step
timeStep. - Forces are capped (
maxAccelerationG) so extreme configs can't explode the solver.
Known limits
- Wave troughs show the flat vanilla surface. The overlay draws on top of vanilla water; it can't carve it away.
- Tides shift the effective flotation level rather than moving water blocks.
- Beach Flooding & Swash is off by default as of 2.16.0. Water running up over the sand caused more visual trouble than it was worth across 2.14–2.15; waves still roll all the way to shore. The code and its tests are still here, behind the config toggle.
Offline tests
tools/ holds harnesses that run the real renderer and physics against fake worlds, without Minecraft. They exist because several beach bugs were invisible to code review and only turned up when something actually measured frames:
| Harness | What it asserts |
|---|---|
CurrentCheck |
Current field maths — divergence-free gyres, depth reversal, speed cap |
ShoreCheck |
Coastline detection stays stable across cache expiry |
FlickerCheck |
Nothing bright blinks, jumps or restyles between frames |
SwashCheck |
Turning a beach feature off doesn't make the picture calmer |
SinkCheck |
The water surface stays level instead of skinning over the sand |
QualityProbe |
The adaptive-quality governor settles instead of hunting |
DefaultCheck |
Shipped defaults are what they're meant to be |
bash
javac --release 21 -d build/stub-classes $(find stubs -name '*.java')
javac --release 21 -d build/classes -cp build/stub-classes $(find src -name '*.java')
javac --release 21 -d build/tools -cp build/classes:build/stub-classes tools/*.java
java -cp build/classes:build/tools:build/stub-classes FlickerCheck
stubs/ is not part of the mod — it's compile-verification stubs plus enough working stand-ins (a recording vertex buffer, a settable camera) for the harnesses to drive the renderer offline. It isn't shipped in the jar.
Project description from CurseForge.
Pick your setup
Sablewaves by Minecraft version and loader
Choose the version and loader you play, then open the matching release.
Check the dependencies, then try the file in a copied instance before changing a world you care about.
Recent files
Sablewaves versions and loaders
sablewaves-2.23.2.jar
13 Sept 2026
sablewaves-2.22.0.jar
5 Sept 2026
sablewaves-2.21.0.jar
31 Aug 2026
sablewaves-2.19.1.jar
29 Aug 2026
sablewaves-2.16.0
sablewaves-2.16.0.jar
29 Aug 2026
sablewaves-2.14.6.jar
26 Aug 2026
sablewaves-2.14.5.jar
24 Aug 2026
sablewaves-2.14.2.jar
21 Aug 2026
sablewaves-2.14.1.jar
20 Aug 2026
sablewaves-2.14.0.jar
18 Aug 2026
sablewaves-2.12.3.jar
15 Aug 2026
sablewaves-2.12.1.jar
10 Aug 2026
Looking for an older file? The official CurseForge project page is in Resources.