Home Logic Networks
Post
Cancel

Logic Networks

Logic Networks is a mod for Minecraft that implements advanced logic and logistics systems programmable with a node network interface, similar to Unreal blueprints or shader editors.

Tools: Java, Gradle/Groovy, OpenGL, git/GitHub


Summary

Logic Networks aims to be a streamlined, centrally controlled alternative to popular logistics mods for the game that lack advanced programming features. It introduces node networks for this purpose, allowing manipulation of several types of signals through processing nodes. The mod was built over the course of roughly a month.

  • View source code on the GitHub repository.
  • There is also an old work-in-progress wiki covering the mod’s systems in more depth.
  • Some demos are shown below, covering the basic functionality of the node graph editor and a simple use case in driving a seven-segment display.

Demo

Network Graph Basics

Logic Networks’ node editor is written from scratch with GLFW (OpenGL bindings) on top of the game’s rendering engine, and it visually resembles existing game interfaces (such as the advancement menu) to blend in better. Basic nodes don’t need to define their own visual representation; the default rendering methods estimate size from inputs and outputs and render signal sockets and the node name on an appropriately sized box.

More advanced nodes can take advantage of the included UI library to add dropdowns, text and numerical inputs, and so on, as seen in some of the basic built-in nodes such as constant numerical values as demonstrated in the video below.

Nodes that interact with the world have an input for a linking card, which allows the player to designate a network anchor that the node operates through. The actual functionality of network anchors is used in the 7-segment display example, but the interface is demonstrated here:

Signals of various types can be read from or written to “network anchors” (a block that serves as I/O for a node network), as well as passed to any node accepting that signal type. Signals of compatible types can be implicitly converted, as demonstrated above with analog (0-15, to represent in-game redstone values) and integer signals.

7-Segment Display

As an example use case, massive redstone (Minecraft’s wiring system) machines to decode binary digits for a 7-segment-display (with all the slowness of in-world redstone circuits) can be condensed and simplified to be entirely contained within a network, reading an integer input signal and outputting 7 different signals for the display–and doing it all in a single server tick:

The video above shows the most basic use case of network anchors: boolean signals can be written to them to emit an on/off redstone wiring signal. An analog input is read from a block, then passed through some boolean checks to determine which segments of the display should be powered for the input. Those segments are then turned on by writing positive boolean signals to their lights.

Implementation

Flexibility

Logic Networks is built to be loader-agnostic so that it can be used on any of the major Minecraft mod loaders (Forge, Fabric, Quilt). To achieve this, main functionality is defined in a Common source set and loader-specific code is loaded via Java services when needed.

As an example, the services package on Forge contains Forge-specific systems for network packets (ForgeNetworking), information about loaded mods (ForgePlatformInfo) and functionality that’s augmented by the Forge loader such as render layers and object registries (ForgePlatformAccess).

The same functionality is implemented differently on Fabric within its services package.

Speed

It’s also fast: when a network graph editor is closed, the node network tree (implemented as a directed acyclic graph) is minimized and sent to the server for processing; on the server, it’s then “compiled” to a set of instructions based on nodes’ evaluate functions. Nodes that are not required for any output (or write instruction) are stripped; the remaining nodes are processed in turn until each branch has completed.

Modularity

The mod is built to be completely modular. Adding new types of signals and nodes is trivial so you can quickly define your own functionality and then build new node networks using it. Addons to the mod can be created without ever touching platform-specific code; additional node and signal types can be registered from common source.

As an example, a node that joins two strings can be implemented as below. All that’s needed to define a node type is an array of input signal types, an array of output signal types, a localizeable name and an evaluate function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class StringJoinNode extends SimpleOperatorNode<StringJoinNode> {
    public StringJoinNode(NodeType<StringJoinNode> nodeType, UUID uuid, int x, int y) {
        super(nodeType,
                Translations.Nodes.STRING_JOIN, // Localization key for the node name
                BuiltinSignalTypes.STRING.arrayOf(2), // Input signal type array
                BuiltinSignalTypes.STRING.arrayOf(), uuid, x, y); // Output signal type array
    }

    @Override
    public Object[] evaluate(Object[] inputs) {
        // When a network is compiled, this function evaluates a node's outputs for its inputs
        // This node just adds the two strings in its input array and returns the output
        return new Object[]{(inputs[0]) + ((String) inputs[1])};
    }
}

…and all that’s left is to register it:

1
2
3
4
5
6
7
8
9
10
11
// Create a singleton instance of the node type, which is used at runtime to
// construct the actual node objects; in this case StringJoinNode
public static final NodeType<StringJoinNode> STRING_JOIN
    = new BaseNodeType<>(StringJoinNode::new);

static {
    // The node and signal registries are concurrent to allow for simple static initialization
    // (required because mods on some platforms are loaded asynchronously)
    CommonRegistries.NODE_TYPES.register(
        new ResourceLocation(Constants.MOD_ID, "string_join"), STRING_JOIN);
}
This post is licensed under CC BY 4.0 by the author.