Do I need this page?

Prerequisites: Core Concepts + Your First Addon โ€” complete a basic addon first!

On this page

How the Network Works

The LOGO machine's network system discovers nearby devices by running a BFS (breadth-first search) outward through cable blocks. Any block entity found during traversal that implements ISpcNetworkDevice becomes a readable/writable endpoint.

LOGO CPU BFS starts here cable โ‹ฏ cable Sensor ISpcNetworkDevice cable Actuator ISpcNetworkDevice Button ISpcNetworkActivation Cable link Discovery Branch point
Discovery StepWhat Happens
1. StartBFS starts from the LOGO machine's anchor block
2. TraverseWalks through blocks that are SPC cables or implement ISpcCableTraversable
3. DiscoverFinds block entities implementing ISpcNetworkDevice
4. RegisterMaps each device's IP to its readDeviceValue/applyDeviceValue
5. ScanSeparately scans loaded chunks for ISpcNetworkActivation blocks

The Three Network Interfaces

InterfaceImplement OnPurposeMethods
ISpcNetworkDevice Block Entity Data endpoint โ€” read/write signal values over the network 4 methods
ISpcNetworkActivation Block Entity Wireless boolean trigger โ€” named network, active/inactive 2 methods
ISpcCableTraversable Block Marker โ€” BFS walks through this block like a cable 0 methods
โ„น๏ธ Block vs. Block Entity
ISpcCableTraversable goes on the Block class (it's a structural property).
ISpcNetworkDevice and ISpcNetworkActivation go on the Block Entity (they need state and world access).

ISpcNetworkDevice โ€” Data Endpoints

MethodReturnsParametersDefaultDescription
getDeviceTypeId() String โ€” โ€” Must match an ID registered in SpcNetworkRegistry
getNetworkIp() String โ€” โ€” Unique address nodes use to target this device (e.g., "ROT-1,2,3")
readDeviceValue() SpcSignalValue โ€” INTEGER_ZERO Current value this device exposes (called when a node reads this IP)
applyDeviceValue(SpcSignalValue) void value โ€” signal from the node no-op Receive a value from a node (called when a node writes to this IP)
public class RotationSensorBE extends BlockEntity implements ISpcNetworkDevice {
    private int currentSpeed = 0;

    @Override
    public String getDeviceTypeId() {
        return "mymod:rotation_sensor";
    }

    @Override
    public String getNetworkIp() {
        return "ROT-" + getBlockPos().toShortString();
    }

    @Override
    public SpcSignalValue readDeviceValue() {
        return SpcSignalValue.integer(currentSpeed);
    }
}

ISpcNetworkActivation โ€” Wireless Triggers

Activation blocks are wireless boolean inputs โ€” they don't need cable connections. The runtime scans loaded chunks for activation blocks whose network name matches a declared input.

MethodReturnsParametersDescription
getNetworkName() String โ€” The wireless network name (must match a Wireless Transmitter name)
isSignalActive() boolean โ€” Whether this activation source is currently active
public class MotionSensorBE extends BlockEntity implements ISpcNetworkActivation {
    private String networkName = "";
    private boolean detected = false;

    @Override
    public String getNetworkName() { return networkName; }

    @Override
    public boolean isSignalActive() { return detected; }
}

ISpcCableTraversable โ€” Custom Cables

A marker interface with no methods. Implement it on your Block class to tell the BFS "you can walk through me."

InterfaceMethodsImplement OnEffect
ISpcCableTraversable None (marker) Block subclass BFS treats this block as traversable cable during network discovery
public class FiberOpticCableBlock extends Block implements ISpcCableTraversable {
    // Just a normal block โ€” the marker is enough
    public FiberOpticCableBlock(Properties props) {
        super(props);
    }
}

SpcNetworkRegistry

Register your device types so the editor can display them with proper names. Blocks don't need separate registration โ€” only device types do.

MethodReturnsParametersDescription
registerDeviceType(String, String) void deviceTypeId, displayName Register a device type ID with its display name
findDeviceType(String) Optional<SpcNetworkDeviceType> deviceTypeId Look up a registered type
allDeviceTypes() Map<String, SpcNetworkDeviceType> โ€” Unmodifiable view of all types
isFrozen() boolean โ€” Whether the registry is locked
freeze() void โ€” Internal โ€” do not call

SpcNetworkDeviceType (inner record)

ComponentTypeDescription
deviceTypeIdStringUnique identifier
displayNameStringHuman-readable name for the editor

Step-by-Step: Network Sensor

1

Register the device type

SpcNetworkRegistry.registerDeviceType(
    "mymod:rotation_sensor", "Rotation Sensor");
2

Create the block entity

Implement ISpcNetworkDevice โ€” override getDeviceTypeId(), getNetworkIp(), readDeviceValue().

3

Place the block next to SPC cables

The BFS will discover your block entity during network scan.

4

Read in a node using virtual signals

Nodes can reference devices by their network IP using virtual signal reads.

Step-by-Step: Activation Source

1

Create the block entity

Implement ISpcNetworkActivation โ€” return a network name and active state.

2

No registration needed

Activation blocks don't need registry entries โ€” the runtime scans for them by interface.

3

Match the network name

Your block's getNetworkName() must return the same string configured on a Wireless Transmitter connected to the LOGO machine.

Step-by-Step: Custom Cable

1

Implement the marker interface

public class MyCable extends Block implements ISpcCableTraversable { }
2

That's it

No registration needed. Place your cable blocks between the LOGO machine and network devices โ€” the BFS will traverse through them.