Skip to content

Networking

Meme Man edited this page May 1, 2025 · 2 revisions

Networking in Nexus

Nexus provides a comprehensive set of pre-defined utilities that allow you to write your network code similar to how you would on your loader of choice, but more concise. It more closely follows Neo/Forge's style of defining and registering packets. For example:

@NetworkRegistrarEntry // Optional; you can use bootstrap methods or some other way to statically initialize this class
public class MyPacketRegistrarClass {

    // NetworkSide here is pretty important, since registration/active method calls made to NetworkServices#NETWORK_MANAGER behave based on it
    public static final BasePacket<MyPacket> EXAMPLE_PACKET = registerPacket(new BasePacket<>(new ResourceLocation("my_modid", "example_packet"), MyPacket.class, MyPacket::encode, MyPacket::decode, MyPacket::handle, NetworkSide.C2S));

    private static <MSGT> BasePacket<MSGT> registerPacket(BasePacket<MSGT> packet) {
        return NexusServices.NETWORK_MANAGER.registerPacket(packet); // Actually register the packet
    }
}

In the snippet above, we're registering our example packet like we'd register a standard object in order to let the game know that a our packet exists and is valid/can be used to communicate between the client and the server. The Network Manager service will delegate actual registration to each loader and safely register the packet.

The packet class itself would look something like this:

public class MyPacket { // Ensure that you properly segregate side-specific objects. If you need a reference to Minecraft, for instance, use ClientUtil#getClient() or your own utility method in a class that isn't initialized on both sides
    private final int someInt;
    private final String someString;

    public MyPacket(int someInt, String someString) {
        this.someInt = someInt;
        this.someString = someString;
    }

    public MyPacket(FriendlyByteBuf buf) { // ALT: You can use this overloaded constructor for decoding instead (MyPacket::new instead of MyPacket::decode)
        this(buf.readInt(), buf.readUtf());
    }

    public static MyPacket decode(FriendlyByteBuf buf) {
        return new MyPacket(buf.readInt(), buf.readUtf());
    }

    public void encode(FriendlyByteBuf buf) {
        buf.writeInt(this.someInt);
        buf.writeUtf(this.someString);
    }

    public static PacketContext handle(MyPacket myPacketObj) {
        return (nullablePlayerOwner, currentLevel, currentConnection, currentSide) -> {
            // ... (Do stuff)
        };
    }
}

Nexus provides robust packet context that should fulfill most of your needs when writing C2S/S2C packets.

Sending Packets

Sending packets from one side to another is straightforward:

public class SomeItem extends Item {

    public SomeItem(Properties properties) {
        super(properties);
    }

    @Override
    public InteractionResult useOn(UseOnContext ctx) {
        if (ctx.getLevel().isClientSide) { // Validate that we're not sending a packet to the server from the server (duh)
            NexusServices.NETWORK_MANAGER.sendToServer(new MyPacket(2, "A string that signals something to the server or whatever"));
        }
        return super.useOn(ctx);
    }
}

The Network Manager service provides a lot more methods for you to utilise based on your use case. Each implementation has safeguards based on the defined NetworkSide of each of your packets.

Clone this wiki locally