Package dan200.computercraft.api.peripheral
A peripheral is an external device that a computer can interact with. Peripherals can be supplied by both a block (or block entity), or from turtle or pocket upgrades.
Creating peripherals for blocks
One of the most common things you'll want to do with ComputerCraft's API is register new peripherals. This is relatively simple once you know how to do it, but may be a bit confusing the first time round.There are currently two possible ways to define a peripheral in ComputerCraft:
-
With a generic peripheral: Generic peripherals are a way to add peripheral methods to any block entity, in a trait-based manner. This allows multiple mods to add methods to the same block entity.
This is the recommended approach if you just want to add a couple of methods, and do not need any advanced functionality.
-
With an
IPeripheral
: If your peripheral needs more advanced behaviour, such as knowing which computers it is attached to, then you can use anIPeripheral
.These peripherals are currently NOT compatible with the generic peripheral system, so methods added by other mods (including CC's built-in inventory methods) will not be available.
In the following examples, we'll write a peripheral method that returns the remaining burn time of a furnace, and demonstrate how to register this peripheral.
Creating a generic peripheral
First, we'll need to create a newfinal
class, that implements GenericPeripheral
.
You'll need to implement GenericSource.id()
, which should just return
some namespaced-string with your mod id.
Then, we can start adding methods to your block entity. Each method should take its target type as the first
argument, which in this case is a AbstractFurnaceBlockEntity
. We then annotate this method with
LuaFunction
to expose it to computers.
public class FurnacePeripheral implements GenericPeripheral {
@Override
public String id() {
return new ResourceLocation(ExampleMod.MOD_ID, "furnace").toString();
}
@LuaFunction(mainThread = true)
public int getBurnTime(AbstractFurnaceBlockEntity furnace) {
// Don't do it this way! Use an access widener/transformer to access the "litTime" field instead.
return furnace.saveWithoutMetadata().getInt("BurnTime");
}
}
Finally, we need to register our peripheral, so that ComputerCraft is aware of it:
ComputerCraftAPI.registerGenericSource(new FurnacePeripheral());
Creating a IPeripheral
First, we'll need to create a new class that implements IPeripheral
. This
requires a couple of boilerplate methods: one to get the type of the peripheral, and an equality function.
We can then start adding peripheral methods to our class. Each method should be final
, and annotated with
LuaFunction
.
public class BrewingStandPeripheral implements IPeripheral {
private final BrewingStandBlockEntity brewingStand;
public BrewingStandPeripheral(BrewingStandBlockEntity brewingStand) {
this.brewingStand = brewingStand;
}
@Override
public String getType() {
return "brewing_stand";
}
@LuaFunction
public final int getFuel() {
// Don't do it this way! Use an access widener/transformer to access the "fuel" field instead.
return brewingStand.saveWithoutMetadata().getInt("Fuel");
}
@Override
public boolean equals(@Nullable IPeripheral other) {
return other instanceof BrewingStandPeripheral o && brewingStand == o.brewingStand;
}
}
Finally, we'll need to register our peripheral. This is done with capabilities on Forge, or the block lookup API on
Fabric.
Registering IPeripheral
on Forge
Registering a peripheral on Forge can be done by attaching the IPeripheral
to a block entity. Unfortunately, this requires quite a lot of boilerplate, due to the awkward nature of
ICapabilityProvider
. If you've got an existing system for dealing with this, we recommend you use that,
otherwise you can use something similar to the code below:
// The main function to attach peripherals to block entities. This should be added to the Forge event bus.
public static void attachPeripherals(AttachCapabilitiesEvent<BlockEntity> event) {
if (event.getObject() instanceof BrewingStandBlockEntity brewingStand) {
PeripheralProvider.attach(event, brewingStand, BrewingStandPeripheral::new);
}
}
// Boilerplate for adding a new capability provider
public static final Capability<IPeripheral> CAPABILITY_PERIPHERAL = CapabilityManager.get(new CapabilityToken<>() {
});
private static final ResourceLocation PERIPHERAL = new ResourceLocation(ExampleMod.MOD_ID, "peripheral");
// A {@link ICapabilityProvider} that lazily creates an {@link IPeripheral} when required.
private static final class PeripheralProvider<O extends BlockEntity> implements ICapabilityProvider {
private final O blockEntity;
private final Function<O, IPeripheral> factory;
private @Nullable LazyOptional<IPeripheral> peripheral;
private PeripheralProvider(O blockEntity, Function<O, IPeripheral> factory) {
this.blockEntity = blockEntity;
this.factory = factory;
}
private static <O extends BlockEntity> void attach(AttachCapabilitiesEvent<BlockEntity> event, O blockEntity, Function<O, IPeripheral> factory) {
var provider = new PeripheralProvider<>(blockEntity, factory);
event.addCapability(PERIPHERAL, provider);
event.addListener(provider::invalidate);
}
private void invalidate() {
if (peripheral != null) peripheral.invalidate();
peripheral = null;
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> capability, @Nullable Direction direction) {
if (capability != CAPABILITY_PERIPHERAL) return LazyOptional.empty();
if (blockEntity.isRemoved()) return LazyOptional.empty();
var peripheral = this.peripheral;
return (peripheral == null ? (this.peripheral = LazyOptional.of(() -> factory.apply(blockEntity))) : peripheral).cast();
}
}
Registering IPeripheral
on Fabric
Registering a peripheral on Fabric can be done using the block lookup API, via PeripheralLookup
.
PeripheralLookup.get().registerForBlockEntity((f, s) -> new BrewingStandPeripheral(f), BlockEntityType.BREWING_STAND);
-
ClassDescriptionA thread-safe collection of computers.A
GenericSource
which provides methods for a peripheral.The interface passed to peripherals by computers or turtles, providing methods that they can call.A peripheral whose methods are not known at runtime.A peripheral is an external device that a computer can interact with.Thrown when performing operations onIComputerAccess
when the current peripheral is no longer attached to the computer.The type of aGenericPeripheral
.Monitors "work" associated with a computer, keeping track of how much a computer has done, and ensuring every computer receives a fair share of any processing time.