Appearance
Carving terrain
CarveApi cuts land far faster than setting blocks one at a time, and it spreads the work over several ticks. Call it on the server thread.
Make a cut
Build a cut, then call start(). Rimulib ticks it until it finishes.
java
// A round hole down to the bottom of the world
CarveApi.column(level, centre, 40).start();
// Level a disc of land down to y 64
CarveApi.flatten(level, centre, 60, 64).named("Landing pad").start();Shapes
| Method | Shape |
|---|---|
column | A round hole down to the bottom of the world |
flatten | A disc levelled to one height, or to any height you choose per column |
slit | A north to south slit whose width can change along its length |
wedge | A fan that opens along a heading |
line | A straight trench |
lens | A lens-shaped cut along a heading |
Choose the floor yourself
A Floor returns the height for each column. Everything above that height is removed. Return CarveApi.UNTOUCHED to skip a column.
A Surface decides what the block left at the floor becomes. Return null to keep it. You can also pass null as the whole surface.
java
CarveApi.Floor bowl = (x, z) -> {
double d = Math.hypot(x - centre.x, z - centre.z);
return d > 50 ? CarveApi.UNTOUCHED : 60 + (int) (d * d / 100);
};
CarveApi.Surface scorch = (x, y, z, was) -> Blocks.BLACKSTONE.defaultBlockState();
CarveApi.flatten(level, centre, 50, bowl, scorch).start();Floors and surfaces run on the server thread, so keep them fast.
Control a running cut
start() returns the same Cut, so you can keep it:
| Method | What it does |
|---|---|
done() | Whether the cut has finished |
stop() | Ends the cut early |
finish() | Finishes now and blocks the server thread until done |
chunks() | The chunks in the cut, nearest first |
To drive a cut yourself, skip start() and call tick() once per server tick. tick(front) only cuts as far as front blocks out, which is useful when the cut should follow something moving.
Large cuts
perTick(n)sets how many chunks are handled at a time.lazy()only cuts loaded chunks and comes back for the rest as they load.streaming(hold, release)also loads chunks for the cut. Pass two functions that add and remove your own chunk tickets.
Protect your blocks
Register the blocks once, then opt in on each cut with keepBlocks():
java
CarveApi.keepBlocks(state -> state.is(MyBlocks.CORE));
CarveApi.column(level, centre, 40).keepBlocks().start();The spared overloads of column and flatten leave a 5 by 5 group of columns standing around one position.
Write many blocks at once
paint writes straight into chunk sections, then relights and resends them. Containers replaced this way lose their contents.
java
Map<BlockPos, BlockState> blocks = new HashMap<>();
blocks.put(pos, Blocks.STONE.defaultBlockState());
CarveApi.paint(level, blocks);Columns under an active ward are left as they are. See Erasing and wards.
Hooks
| Method | When it runs |
|---|---|
watch | Every block a cut or write replaces |
joinWith | Fixes a painted block from its neighbours, such as connected textures |
onTimeTurn | When turnTime(level) is called, so you can undo your own work |
turnTime(level) tells your listeners, then drops every cut still running in that level.
