UtilityConnect:Modding API
Utility Connect gives your mod a shared network graph. You register your network blocks, and the library connects them, splits and merges networks, saves them per chunk and rebuilds them after a restart. This page lists the public types. Worked examples are on Registering Nodes.
| Status | The network side is complete. The transport types (TransportProvider, TransferMode) are interfaces only: the library does not call them and moves nothing on its own. See Transport API.
|
|---|---|
| Stability | The library is pinned to exact versions. 0.1.0-Alpha to 0.2.0-Alpha broke the API (registerKindResolver was added). 1.0.0 kept the API of 0.2.0-Alpha unchanged.
|
Setting up the dependency
Add Utility Connect as a hard dependency in your manifest.json:
"Dependencies": {
"com.cyberpiratepenguin:utilityconnect": "1.0.0"
}
With the hytale-tools Gradle plugin, the same line goes into gradle.properties:
manifest_dependencies = com.cyberpiratepenguin:utilityconnect=1.0.0
Compile against the Utility Connect jar (Java 25), but do not ship it inside your own jar. Players install it as a separate mod. A bundled copy would never be started by the server, so its networks() would always throw.
The hard dependency makes the server load Utility Connect first. Its setup() has finished before your plugin's setup() runs, so you can use the API from your own setup() on.
Packages
Only use the api packages. Everything under com.cyberpiratepenguin.utilityconnect.internal is an implementation detail and may change at any time.
| Package | Contents |
|---|---|
com.cyberpiratepenguin.utilityconnect.api |
UtilityConnectAPI
|
com.cyberpiratepenguin.utilityconnect.api.network |
Networks, NodeKind, NodeKindResolver, NodePos, ChunkKey
|
com.cyberpiratepenguin.utilityconnect.api.transport |
TransportProvider<T>, TransferMode
|
UtilityConnectAPI
Static entry point.
| Member | Description |
|---|---|
API_VERSION |
Version string of the public API, currently "1.0.0". Compiled into your mod.
|
isReady() |
true once the library's setup() has run, false before that and after shutdown.
|
runtimeVersion() |
Version of the installed library, or null while it is not running.
|
networks() |
The Networks access. Throws IllegalStateException when the library is not ready, usually because the manifest dependency is missing.
|
Networks
Access to the networks of all worlds. Every method takes the Hytale World; networks never span worlds.
| Method | Returns | Description |
|---|---|---|
addNode(World, NodePos, NodeKind) |
boolean |
Registers a block as a node. It connects at once to all allowed neighbours, also across chunk borders. true if the position was new.
|
removeNode(World, NodePos) |
boolean |
Removes a node. Networks split on their own. true if the position was known.
|
hasNode(World, NodePos) |
boolean |
Whether a loaded node exists at that position. |
networkAt(World, NodePos) |
Set<NodePos> |
All nodes in the same network, including the position itself. Empty if there is no loaded node there. A node without connections returns a set with only itself. |
sameNetwork(World, NodePos, NodePos) |
boolean |
Whether both positions are loaded and in the same network. |
networkCount(World) |
int |
Number of separate networks in that world (loaded chunks only). |
nodeCount(World) |
int |
Number of loaded nodes in that world. |
registerKindResolver(NodeKindResolver) |
void |
Registers a resolver that reads a block's role on chunk load. Call once at startup. |
Threading: call every method on the world thread only, for example from block place and break event handlers. Never from an async command or your own thread. The world thread serialises all player actions, so no locking is needed.
Loaded chunks only: nodes in unloaded chunks are not part of any network and do not show up in queries. They come back when the chunk loads.
NodeKind
Enum with the role of a node.
| Value | Meaning |
|---|---|
DEVICE |
Storage, terminal, machine. Connects to connectors only, never directly to another device. |
CONNECTOR |
Pipe, cable. Connects to every adjacent node in all six directions. |
isConnector() and the static connects(a, b) (true if at least one side is a connector) express the rule in code.
NodeKindResolver
Functional interface NodeKind resolve(World world, NodePos pos). Utility Connect calls it on the world thread for every stored node once a chunk has loaded and its blocks can be read. Return the role of your block, or null if the position is not yours. The first registered resolver that returns a value wins, so another mod cannot reinterpret your blocks. Corrected roles are saved.
NodePos and ChunkKey
NodePos(int x, int y, int z): immutable block position, the identity of a node.of(x, y, z),from(BlockPosition),toBlockPosition(),offset(dx, dy, dz),adjacent()(the six face neighbours),isAdjacentTo(other). Theyvalue must be inside the world height, because nodes are stored with chunk-relative packed positions.ChunkKey(int x, int z): a chunk column.of(chunkX, chunkZ),containing(NodePos),contains(NodePos).
Transport
TransportProvider<T> and TransferMode are described on Transport API.
| Utility Connect |
|---|
| Installation · Networks · Persistence · Version History |
| For modders: Modding API · Registering Nodes · Transport API |
| Project page on mutigeraffe.com · Download on CurseForge |