Skip to content

Using VoxLib from Java

Mystery2099 edited this page Sep 18, 2026 · 3 revisions

Using VoxLib from Java

Java mods can use the full core API. The geometry works the same; the calls are simply more verbose because VoxLib is written in Kotlin.

Most APIs live in Kotlin object declarations. Java sees one public INSTANCE field for each object, with the API methods attached to that instance.

VoxelAssembly voxels = VoxelAssembly.INSTANCE;
VoxelRotation rotations = VoxelRotation.INSTANCE;
CommonShapes commonShapes = CommonShapes.INSTANCE;

The methods are not Java static methods. If you try a static import such as import static VoxelAssembly.union, it will not compile in VoxLib 1.8.0.

Kotlin-to-Java call map

Kotlin Java
createCuboidShape(...) VoxelAssembly.INSTANCE.createCuboidShape(...)
a + b VoxelAssembly.INSTANCE.plus(a, b)
union(a, b, c) VoxelAssembly.INSTANCE.union(a, b, c)
shape.rotateLeft() VoxelRotation.INSTANCE.rotateLeft(shape)
shape.rotate(t) VoxelRotation.INSTANCE.rotateWithTransformation(shape, t)
shape.simplifyForOutline(8) VoxelAssembly.INSTANCE.simplifyForOutline(shape, 8)
shape.toBoundingBoxShape() VoxelAssembly.INSTANCE.toBoundingBoxShape(shape)
shape appendShapes { ... } Write the conditional and call union

rotateWithTransformation is the Java name selected by the Kotlin @JvmName annotation.

Creating and combining shapes

import com.github.mystery2099.voxlib.combination.VoxelAssembly;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.VoxelShape;

VoxelAssembly voxels = VoxelAssembly.INSTANCE;

VoxelShape base = voxels.createCuboidShape(0, 0, 0, 16, 1, 16);
VoxelShape post = voxels.createCuboidShape(7, 1, 7, 9, 15, 9);
VoxelShape top = voxels.createCuboidShape(6, 15, 6, 10, 16, 10);

VoxelShape table = voxels.plus(voxels.plus(base, post), top);
VoxelShape combined = voxels.union(base, post, top);
VoxelShape overlap = voxels.combine(BooleanOp.AND, shapeA, shapeB);

createCuboidShape accepts Number, so Java boxes int and double arguments automatically.

Rotating shapes

import com.github.mystery2099.voxlib.rotation.VoxelRotation;
import com.github.mystery2099.voxlib.rotation.VoxelShapeTransformation;

VoxelRotation rotations = VoxelRotation.INSTANCE;

VoxelShape east = rotations.rotateRight(north);
VoxelShape south = rotations.flipHorizontal(north);
VoxelShape west = rotations.rotateWithTransformation(
    north,
    VoxelShapeTransformation.ROTATE_LEFT
);

Common shapes and default arguments

Java cannot use Kotlin default arguments. Pass every declared argument, even when Kotlin code can omit it.

import com.github.mystery2099.voxlib.shapes.CommonShapes;
import net.minecraft.core.Direction;

CommonShapes shapes = CommonShapes.INSTANCE;

VoxelShape slab = shapes.createSlab(8);
VoxelShape pillar = shapes.createPillar(6, true);
VoxelShape table = shapes.createTable(2, 2);
VoxelShape chair = shapes.createChair(8, true, 8);
VoxelShape stairs = shapes.createStairs(Direction.NORTH);
VoxelShape fence = shapes.createFenceConnections(true, true, false, false);

The fence booleans are north, east, south, west.

Conditional assembly

The appendShapes builder is the one API that does not translate cleanly. It expects a Kotlin receiver lambda, and VoxelShapeModifier has an internal constructor. In Java, an ordinary conditional is clearer:

VoxelAssembly voxels = VoxelAssembly.INSTANCE;
VoxelShape seat = voxels.createCuboidShape(2, 8, 2, 14, 10, 14);
VoxelShape legs = voxels.createCuboidShape(3, 0, 3, 13, 8, 13);

VoxelShape chair = hasBackrest
    ? voxels.union(
        seat,
        legs,
        voxels.createCuboidShape(3, 10, 12, 13, 16, 14)
    )
    : voxels.union(seat, legs);

Simplification and cache utilities

VoxelAssembly voxels = VoxelAssembly.INSTANCE;

VoxelShape outline = voxels.simplifyForOutline(complexShape, 8);
VoxelShape bounds = voxels.toBoundingBoxShape(complexShape);
VoxelShape hollow = voxels.createOutlineShape(0, 0, 0, 16, 16, 16, 1);

ShapeCache.INSTANCE.clearCache(); // Usually needed only by tests and tools.

Java must supply maxBoxes and thickness; their Kotlin defaults are not Java overloads.

Constants

Kotlin const val properties compile to static fields:

String modId = VoxLib.MOD_ID;
String version = VoxLib.VERSION;

This is the exception to the INSTANCE rule. Methods on VoxLib, VoxelAssembly, VoxelRotation, CommonShapes, and ShapeCache still use INSTANCE.

One 1.8.0 wart is worth knowing about: VoxLib.VERSION still contains 1.7.0+1.21.1. Use loader metadata or your declared dependency version when you need the installed artifact version.

Nullability

VoxLib declares its public parameters and return values as non-null Kotlin types. Java can still pass null because it does not enforce Kotlin nullability at compile time. Do not pass null; the API does not define behavior for it.

Clone this wiki locally