Fluid Registry

Adding new fluids to game


Custom fluids are made in a startup script. The event is not cancellable.
Here are a couple examples on how to use the fluid builder:
The thin texture added by KubeJS is an opaque version of the water texture.
If you want the fluid to be transparent, you need to copy or create a transparent texture.
Some methods can be set by default if you use the 'thin' argument for the builder:
const $SoundEvents = Java.loadClass('net.minecraft.sounds.SoundEvents')
const $ParticleTypes = Java.loadClass('net.minecraft.core.particles.ParticleTypes')

StartupEvents.registry('fluid', event => {
  event.create('water_clone', 'thin')
    .displayName('Water Clone')
    .type(type =>
      type.addDripstoneDripping(1, $ParticleTypes.DRIPPING_DRIPSTONE_WATER, 'minecraft:water_cauldron', $SoundEvents.POINTED_DRIPSTONE_DRIP_WATER)
    )
})
This is the same as doing it this way:
const $SoundEvents = Java.loadClass('net.minecraft.sounds.SoundEvents')
const $ParticleTypes = Java.loadClass('net.minecraft.core.particles.ParticleTypes')

StartupEvents.registry('fluid', event => {
  event.create('water_clone')
    .displayName('Water Clone')
    .tint(0x3F76E4)
    .type(type => type
      .renderType(3)
      .stillTexture('kubejs:block/thin_fluid_still')
      .flowingTexture('kubejs:block/thin_fluid_flow')
      .fallDistanceModifier(0)
      .addDripstoneDripping(1, $ParticleTypes.DRIPPING_DRIPSTONE_WATER, 'minecraft:water_cauldron', $SoundEvents.POINTED_DRIPSTONE_DRIP_WATER)
    )
})
Methods supported by the fluid builder
  • displayName(string) Sets the display name for this object, e.g. 'Water'. This will be overridden by a lang file if it exists.
  • translationKey(string) Sets the translation key for this object, e.g. 'block.minecraft.water'.
  • formattedDisplayName() Makes displayName() override language files.
  • formattedDisplayName(string) Combined method of formattedDisplayName().displayName(name).
  • tag(string[]) Adds a tag to this fluid, e.g. 'minecraft:fluid'.
  • type(builder) More details below
  • tint(color) Adds a tint over the texture. This will mix with the colors on the texture, so it will work best with a grayscale texture.
Color options
There are 3 ways to write colors:
  • Using the Color wrapper: Color.RED
  • Using RGB hex values: 0xFF0000
  • Using ARGB hex values: 0x7F0000FF
List of all the Color options
  • BLACK
  • DARK_BLUE
  • DARK_GREEN
  • DARK_AQUA
  • DARK_RED
  • DARK_PURPLE
  • GOLD
  • GRAY
  • DARK_GRAY
  • BLUE
  • GREEN
  • AQUA
  • RED
  • LIGHT_PURPLE
  • YELLOW
  • WHITE
  • WHITE_DYE
  • ORANGE_DYE
  • MAGENTA_DYE
  • LIGHT_BLUE_DYE
  • YELLOW_DYE
  • LIME_DYE
  • PINK_DYE
  • GRAY_DYE
  • LIGHT_GRAY_DYE
  • CYAN_DYE
  • PURPLE_DYE
  • BLUE_DYE
  • BROWN_DYE
  • GREEN_DYE
  • RED_DYE
  • BLACK_DYE
  • stillTexture(string) Mandatory
  • flowingTexture(string) Mandatory
  • renderType(int) Mandatory
Render Types
  • 0: solid
  • 1: cutout
  • 2: cutout mipped
  • 3: translucent
  • translucent() Sets the render type to 3
  • slopeFindDistance(int) Sets the distance where the fluid will check for a direction to spread.
  • levelDecreasePerBlock(int)
  • explosionResistance(float)
  • tickRate(int) Lower rate will make the fluid spread faster.
  • noBucket()
  • noBlock()
Fluid type builder
  • screenOverlayTexture(string)
  • blockOverlayTexture(string)
  • descriptionId(string) Sets the identifier representing the name of the fluid type.
  • motionScale(double) Sets how much the velocity of the fluid should be scaled by.
  • canPushEntity(bool)
  • canSwim(bool)
  • canDrown(bool)
  • fallDistanceModifier(float) Sets how much the fluid should scale the damage done when hitting the ground per tick.
  • canExtinguish(bool)
  • canConvertToSource(bool)
  • supportsBoating(bool)
  • pathType(int) The path type is used to tell the AI if it can walk into it.
Path Types
  • 0: BLOCKED
  • 1: OPEN
  • 2: WALKABLE
  • 3: WALKABLE_DOOR
  • 4: TRAPDOOR
  • 5: POWDER_SNOW
  • 6: DANGER_POWDER_SNOW
  • 7: FENCE
  • 8: LAVA
  • 9: WATER
  • 10: WATER_BORDER
  • 11: RAIL
  • 12: UNPASSABLE_RAIL
  • 13: DANGER_FIRE
  • 14: DAMAGE_FIRE
  • 15: DANGER_OTHER
  • 16: DAMAGE_OTHER
  • 17: DOOR_OPEN
  • 18: DOOR_WOOD_CLOSED
  • 19: DOOR_IRON_CLOSED
  • 20: BREACH
  • 21: LEAVES
  • 22: STICKY_HONEY
  • 23: COCOA
  • 24: DAMAGE_CAUTIOUS
  • 25: DANGER_TRAPDOOR
  • adjacentPathType(int)
  • sound(soundAction, soundEvent) Sets a sound to play when a certain action is performed.
Sound args
The first argument is the SoundAction:
You will have to load the class for this to work!
const $SoundActions = Java.loadClass('net.neoforged.neoforge.common.SoundActions')
Possible options:
  • BUCKET_FILL
  • BUCKET_EMPTY
  • FLUID_VAPORIZE
  • CAULDRON_DRIP
Example usage:
sound($SoundActions.BUCKET_FILL, $SoundEvents.AMETHYST_BLOCK_BREAK)
  • canHydrate(bool)
  • lightLevel(int) Between [0-15]
  • density(int)
  • temperature(int)
  • viscosity(int)
  • rarity(string)
Rarity options
  • 'common'
  • 'uncommon'
  • 'rare'
  • 'epic'
  • addDripstoneDripping(float, particleType, string, soundEvent) Allows this fluid to drip from Pointed Dripstone stalactites and fill cauldrons below.
Arguments
  • chance: the chance that the cauldron below will be filled every time the Pointed Dripstone is randomly ticked
  • dripParticle: Nullable the particle that spawns randomly from the tip of the Pointed Dripstone when this fluid is above it
  • cauldron: the block the Pointed Dripstone should replace an empty cauldron with when it successfully tries to fill the cauldron
  • fillSound: Nullable the sound that plays when the Pointed Dripstone successfully tries to fill an empty cauldron
A list of default particles can be found here
You will have to load the class for this to work!
const $ParticleTypes = Java.loadClass('net.minecraft.core.particles.ParticleTypes')
Example usage:
addDripstoneDripping(1, $ParticleTypes.DRIPPING_DRIPSTONE_LAVA, 'minecraft:lava_cauldron', $SoundEvents.POINTED_DRIPSTONE_DRIP_LAVA)