promotional banner

Hydrarium

Water, ice and snow in every color.
cauldrons.png

cauldrons.png

frozen.png

frozen.png

items.png

items.png

mixing.png

mixing.png

palette.png

palette.png

Description

hydrarium

Coloured water that is still water.

GitHub release Loaders Minecraft versions License

Loaders: Fabric  •  Minecraft: 26.2  •  Side: Client & Server


About

The fluid is expensive. The colour is free.

A fluid is a registry entry, a block, a bucket, a tag membership, and a compatibility surface with every mob, boat, sponge, fishing rod and waterlogged stair in the game. A colour is three integers a renderer multiplies into a quad it was going to draw anyway.

So hydrarium registers zero fluids and zero blocks. Tinted water is minecraft:water; tinted ice is minecraft:ice; tinted snow is minecraft:snow. Same tags, same buckets, same swimming, same sponges, same waterlogged stairs. The colour is a side-channel the renderer reads and nothing else in the game has to know about.

It ships nineteen waters: the sixteen dye colours, plus ash_slurry, irradiated and lumewater, which carry behaviour as well as colour. A consumer mod adds its own by shipping one JSON file — no Java.


Features

  • They are water, all the way down — Tinted water is minecraft:water. It flows, it drowns you, a sponge soaks it up, a boat floats on it, a stair waterlogs in it, and a fishing rod works in it — because none of that is code this mod wrote.

  • They flow, and they blend on the way — Red pouring into blue makes purple, decided by vanilla's own dye recipes. A pair with no recipe muddies to grey rather than guessing at one.

  • They freeze and they melt — Ice, packed ice, blue ice, snow, snow layers and powder snow all keep the colour of the water they came from, and melting gives it back. Break ice without silk touch and it turns back into the water it was.

  • They fit in things — Buckets, bottles, cauldrons and powder-snow buckets carry the colour, and a bucket's tooltip names its water. A dye dropped in a cauldron colours it; that cauldron then fills coloured bottles and buckets.

  • An untinted world stores no bytes — Colour lives in a sparse per-position field, persisted in the chunk and synced only to whoever is watching it. A whole biome made of one water costs one catalogue row and nothing per position.

  • Nothing has to know — A world saved with a consumer mod's waters and loaded without that mod shows plain water at those positions — and gets the colour back when the mod returns.


Commands

All /water subcommands need permission level 2.

/water give <targets> <water> [<count>] buckets, stamped with a water
/water fill <from> <to> <water> repaint water that is already there; it places nothing. Ice and snow included — the only way to paint a frozen lake that was never tinted water
/water clear <from> <to> take the paint off again
/water at <pos> what water is here, which layer said so, and which block it is in

Paint the source, not the stream. A source block holds the colour you give it; a flowing cell derives its colour from whatever feeds it, and re-derives it the next time it ticks.


Adding your own waters

A consumer mod writes no Java. Ship one file in your own jar:

assets/<your mod id>/hydrarium/catalogue.json

The path is keyed on your mod id, which is what puts your water ids in your namespace. hydrarium's own nineteen are read through this same scanner from this same path in hydrarium's own jar — there is no private path for the built-ins.

{
  "waters": [
    { "id": "lumewater", "tint": 4251856, "effect": "glow", "biome_strength": 0.1 },
    { "id": "brine",     "tint": 7385292, "dye": "light_blue" }
  ],
  "biomes": [
    { "biome": "yourmod:glow_sea", "water": "yourmod:lumewater" }
  ]
}

waters declares colours:

field
id required path only; the namespace is your mod id
tint required a plain 0xRRGGBB written as a decimal integer
effect optional one of none, glow, ash, decay. An unknown name costs that water its behaviour, keeps its colour, and logs — it never fails the catalogue
biome_strength optional, default 0.25 how much of the biome's own water colour bleeds in. 0 is this colour exactly, everywhere; 1 is vanilla's straight multiply
dye optional the dye this water is. Naming one of the sixteen puts this water into dye mixing without it having to be named after a dye. A water with no dye muddies to grey against anything but itself

biomes says which biome is made of which water, and stores nothing — an entire planet's green ocean is one row here and not one byte in any chunk. A biome row may name a water some other mod's catalogue declared; the whole scan resolves before any of it is wired.

Effects are a closed set in Java on purpose. A tint is a number, so a new colour is a row; an effect is code. A catalogue may choose from the set and parameterise it, which is what keeps "a consumer writes no Java" true rather than nearly true.

Resolution order

A position's colour is decided in three layers, and /water at reports which one answered:

  1. the field — a per-position entry, sparse, persisted in the chunk and synced to whoever is watching it. The only layer that costs bytes.
  2. the biome — a catalogue row. Costs nothing per position.
  3. vanilla — ordinary water, in the ordinary way.

Gallery

The nineteen built-in waters. Every one of them is `minecraft:water`.
<sub>The nineteen built-in waters. Every one of them is `minecraft:water`.</sub>

A red stream and a blue stream meet, and everything downstream runs purple.
<sub>A red stream and a blue stream meet, and everything downstream runs purple.</sub>

Ice, packed ice, blue ice, snow, snow layers and powder snow, each keeping the colour of the water it froze from.
<sub>Ice, packed ice, blue ice, snow, snow layers and powder snow, each keeping the colour of the water it froze from.</sub>

A cauldron holds a colour, and fills bottles and buckets with it.
<sub>A cauldron holds a colour, and fills bottles and buckets with it.</sub>

Under the surface the fog goes with it — a purple pool does not look blue from inside.
<sub>Under the surface the fog goes with it — a purple pool does not look blue from inside.</sub>

Buckets, bottles, ice, snow blocks and snowballs all carry their water's colour.
<sub>Buckets, bottles, ice, snow blocks and snowballs all carry their water's colour.</sub>


Dependencies

Required

Mod Version Notes
Fabric Loader >=0.19.3
Fabric API Data attachments, fluid rendering, block colours, chunk lifecycle
Java 25

Incompatibilities

Mod Conflict Workaround
Resource packs that retexture the water bucket hydrarium overrides eight files under assets/minecraft/items/ — the buckets and the frozen items — to give their colour somewhere to land. It is the only place this mod writes outside its own namespace.
Load hydrarium above the pack, or drop the pack's bucket item models.
Mods that replace water's fluid model The colour arrives through FluidRenderingRegistry. A mod that registers its own model for minecraft:water after hydrarium wins, and tinted water draws plain.
None yet. Report it and it can be looked at.

Installation

  1. Install Fabric Loader 0.19.3 or newer, on Java 25.
  2. Drop hydrarium.jar and Fabric API into mods/.
  3. Launch. There is nothing to configure.

Install it on both sides for a server: the field is stored and mixed server-side and drawn client-side, and a client without it simply sees ordinary water.


Building

export JAVA_HOME=".../jdk-25"

./gradlew build                  # the jar, in build/libs/
./gradlew test                   # 40 assertions, no game bootstrap
./gradlew runClient              # playtest
./gradlew runServer -Psmoke      # 29 in-world checks, then it halts

Minecraft, loader and Fabric API versions come from the com.mattmc.mcmod convention plugin, not from this repo. CLAUDE.md has the rest of the build surface, and what breaks silently.


FAQ

Does this add a new fluid?

No — and that is the whole design. Adding a fluid means adding a block, a bucket, tag memberships, and a compatibility surface with every mob, boat and sponge in the game. Tinted water is minecraft:water wearing a colour, so all of that keeps working for free.

My water is the wrong colour. Why?

Run /water at <pos>. It names the layer that answered — the per-position field, a biome row, or vanilla — and the block it is in, which matters because red ice and red water look nearly the same from above.

I painted a stream and it went back to normal.

Paint the source, not the stream. A source block holds a colour; a flowing cell derives one from whatever feeds it, and re-derives it the next time it ticks. Paint the source and let the wave carry it.

What happens to a world if I remove the mod?

Nothing breaks. Those positions are ordinary water, ice and snow, and they render as ordinary water, ice and snow. Put the mod back and the colour is still there.

Two red and two blue snowballs made a grey snow block. Bug?

A decision, and a pinned one. A crafting grid has no level and so no recipe book to ask about dye mixing, so the grid muddies to grey where two red and two blue sources would make purple.


Credits

Built on Fabric and Fabric API. The sixteen dye colours are vanilla's own DyeColor values and the mixing table is vanilla's own dye recipes — so red water is the same red as a red bed.


License

Source-available, not redistributable. Play with it, modify it for your own use, send patches. Re-uploading it or bundling it into a modpack needs written permission. See LICENSE for the exact terms.


Issues and patches welcome.

The Hydrarium Team

profile avatar
  • 5
    Projects
  • 200
    Downloads

More from mattjesmcView all