Create kinetics
The optional Create addon exposes speedometers, stressometers, Rotation Speed Controllers, programmable pumps and programmable clutches on Minecraft 1.21.1. See the Create overview for installation, project setup, peripheral cables, and device naming.
The device classes also support shared typed discovery: first, firstOrNull, filter, all,
at/atOrNull, and named/namedOrNull. See typed peripheral discovery.
Use these typed providers for every device lookup.
Named devices
Give a kinetic device a unique name with the Peripheral Configurator, then acquire it over a connected cable:
import create.kinetics.RotationController
import create.kinetics.Speedometer
import create.kinetics.Stressometer
fun main() {
val input = Speedometer.named("input")
val load = Stressometer.named("main_load")
val controller = RotationController.named("governor")
println(input.speed())
println(load.capacity())
println(controller.setTargetSpeed(128))
}
Discovery uses loaded chunks only and never forces a chunk to load. Breaking the cable path makes subsequent acquisitions unavailable. An already acquired handle remains tied to its exact block entity and never follows another device that later receives the same name.
Direct sides and devices
Sides are relative to the front of the computer, just like the redstone API:
import create.kinetics.RotationController
import create.kinetics.Speedometer
import create.kinetics.Stressometer
import compukter.peripheral.Side
fun main() {
val input = Speedometer.at(Side.left)
val load = Stressometer.at(Side.bottom)
val controller = RotationController.at(Side.top)
println(input.speed())
println(load.stress())
println(load.capacity())
println(controller.setTargetSpeed(128))
}
front, back, left, right, top, and bottom inspect exactly one adjacent loaded block. They never scan the
world or force a chunk to load. The requested block must be the matching Create block entity:
| Accessor | Adjacent Create device | Operations |
|---|---|---|
speedometer() |
Speedometer | speed(): Float, awaitSpeedChange(): Float |
stressometer() |
Stressometer | stress(): Float, capacity(): Float, awaitChange(): Unit |
rotationController() |
Rotation Speed Controller | targetSpeed(): Int, setTargetSpeed(Int): Int |
Speed, stress, and capacity retain Create’s Float values without integer rounding. Speeds are signed. A rotation
controller applies Create’s own configured bounds, and setTargetSpeed returns the value that was actually accepted.
If Create exposes NaN, positive or negative infinity, or signed zero, the same binary32 value reaches Guest Kotlin;
the integration does not sanitize, widen, or convert it to fixed point. Change waits compare the observed binary32
value, including the distinction between positive and negative zero.
awaitSpeedChange() suspends until the observed speed changes and returns the new value. awaitChange() suspends until
either stress or capacity changes. These waits do not busy-poll in Guest code.
Lifetime and limits
A device accessor creates a handle for that exact acquired block entity. Replacing the block invalidates the old handle; it never silently reconnects to the replacement. Missing, mismatched, unloaded, removed, or stale devices fail the Guest operation deterministically, and the terminal process diagnostic identifies which condition prevented the operation.
Each running computer may retain the shared limit of 1,024 typed peripheral handles and at most 64 pending Create waits. Host requests and completions cross the same bounded asynchronous actor path as other world-facing computer operations and execute on the server thread where Minecraft and Create state may safely be accessed.
Programmable actuators
The Create addon adds Programmable Mechanical Pump (compukters_create:programmable_pump) and
Programmable Clutch (compukters_create:programmable_clutch). Craft either with its ordinary Create block and
one Compukters Redstone Port. They appear together in the existing Compukters creative tab, after base-mod items.
Addon groups stay together in stable addon-id order; installing another addon does not add a creative tab.
Only these programmable variants support the actuator API. Name and connect them with the Peripheral Configurator, then use the same typed discovery as other devices:
import create.actuators.Pump
import create.actuators.Clutch
fun main() {
val fuel = Pump.named("fuel")
val load = Clutch.named("load")
fuel.setReversed(true)
load.setConnected(true)
println(fuel.reversed())
println(load.connected())
readln()
load.setConnected(false)
}
Pump.setReversed(Boolean): Boolean reverses the actual fluid-flow direction without reversing the kinetic input.
Calling it again with the same value does not flip the pump again. reversed() reports the selected direction,
relative to its placement; wrench reversal updates this flag too. The direction survives program exit and world
reload. Changing its direction requires rotation and a valid pipe route before fluid can move.
Clutch.setConnected(Boolean): Boolean engages or disengages the kinetic output, and connected() reads its state.
It ignores redstone. A newly placed clutch is disengaged. It also disengages after program exit, Ctrl+C, loss of
peripheral connectivity, unloading or world reload. Ownership is transient and is never restored from saved data.
An expired handle cannot engage a replacement block. Keep the controlling program running while the load is connected.
Both setters return the resulting state. Create’s kinetic stress rules still apply.