LibNetworkStack's base library.

First off: this isn't completely designed around minecraft, so if you are only interested in using this in a normal minecraft networking you probably want to read the javadoc for the package as well.

There are a few main concepts:

  1. Network ID organisation
  2. Connections
  3. Contextual parent network ID's
  4. Dynamic parent network ID's
  5. Data network ID's
  6. Signal network ID's
  7. Caches
  8. Debugging

Network ID organisation

Network ID's are organised into a tree: the root node is always a ParentNetId, and the child nodes can either extend ParentNetIdBase (for organising nodes), or NetIdBase (for sending data).
Every ID has a name, usually in the form "mod_id:mod_specific_name", however it is only important that the name not collide with other children of the same parent. These names are used to assign integer ID's to each network ID so that the full name doesn't have to be sent with each and every packet, so they must be the same at both ends!


Each individual connection has it's own ActiveConnection object associated with it: this stores the current network ID registry, any caches, and handles reading and writing packets out to the underlying connection.

There is a second base type: a BufferedConnection, which will buffer (or queue) packets until it's next "tick". This is generally a large performance optimisation if you need to send a lot of smaller packets.

Contextual parent network ID's

In addition to organising all network nodes, any parent type that extends ParentNetIdSingle can also write out data for it's represented object. For example you might have a network ID for a BlockEntity, and then several children of that block entity that all need to communicate with the same entity on the other side.

Dynamic parent network ID's

It is occasionally useful for an object to be contained within multiple different types of object, for example a buildcraft combustion engine might be contained within a block entity, or used in a flying robot. Dynamic network ID's allows the same object to communicate even if it doesn't necessarily have a single path upwards to the root.

Unlike normal ID's the dynamic parent must know the child that it will be sending, rather than the child needing to know the parent.

(List title):

Class Overview
ParentDynamicNetId The parent for a specific DynamicNetId
DynamidNetId The child which doesn't know what is it's parent, but the object itself must have some way to obtain it's current parent is via LinkAccessor#getLink(Object)
DynamicNetLink The per-instance link object that holds both the parent and the child network ID and objects.

Data network ID's

These allow you to send and receive between 1 and 65,536 bytes of binary data. If you know the exact length of the data to be sent you can pre-specify it in the constructor, or you can allow using a shorter (or longer) maximum packet length by calling either setTinySize() or setLargeSize().

Data ID's come in two variants: either untyped (which are somewhat comparable to the "static" java modifier for methods), or typed, which require (and will deserialise) an object for them to be called upon.

Parent Class
Untyped ParentNetId NetIdData
Typed ParentNetIdSingle NetIdDataK

Signal network ID's

These are very similar to data network ID's, except they won't write any data out: instead the mere presence of this packet should convey all of the information required. Two variants exist: typed and untyped depending on whether the parent has a contextual object or not.

Parent Class
Untyped ParentNetId NetIdSignal
Typed ParentNetIdSingle NetIdSignalK


These are a slightly more niche feature, but still useful nonetheless. Essentially these offer a way to create a registry of objects to/from integer ID's on a per-connection, per-use basis. This can help avoid a situation where you need to reliably sync a (possibly large) registry of id's right at the start of a network connection, especially if not all of those ID's will be used over it's duration.

The only class associated with caches is NetObjectCache, and it's usage is simple: Just create a new ParentNetId, then pass in a hash/equals and network serialiser implementation. (Alternatively if your data can be mapped to/from an Identifier then you can use the function based factory: createMappedIdentifier).

To send an ID you can then call getId to get the ID that will be sent. (Note that the ID's *are* buffered by default, so you must only use them in a buffered connection, or call #notBuffered()).

On the receiving end you can call NetObjectCache.getObj(ActiveConnection, int) to obtain the original object (although it will return null if the entry isn't present - either if it hasn't sent yet or you passed it the wrong ID.


To enable debugging (also known as log spam) you can add the option "-Dlibnetworkstack.debug=true" to the launch arguments. (You can also debug caches separately with "-Dlibnetworkstack.cache.debug=true").