DUXPLIMA Documentation

Packets

Mojang-mapped packet ports for NPCs, the tab list and text displays, with the NMS quarantined behind them.

uxmlib-packet holds the shared helpers and three ports. Every packet crosses a port boundary as an opaque Object, so the interface and everything above it carries no net.minecraft reference and is testable against a fake. Only the single internal implementation behind each port touches NMS.

NPC packets

NpcPackets npcs = new NmsNpcPackets(sender);

int id = npcs.allocateEntityId();

A fake-player NPC reaches a client in a fixed sequence: a player-info entry carrying the name and skin so the client knows how to render a body, then the entity spawn, then the look packets that aim the head and body.

The client links the skin to the spawned entity because the spawn UUID equals the player-info entry's profile id, so the spawn must reuse the same profile id.

The entry is added unlisted so the body renders but the NPC never appears as a tab-list row, and the entry is kept for the entity's whole lifetime. Removing it de-renders the entity on modern clients, which is the single most common reason a hand-rolled NPC vanishes after a few seconds.

Supporting value types: NpcPose, EquipmentSlot, ArmorStandPart, HorseVariant, NamedColor, ByteAngle.

Tab list packets

TabListPackets tabs = new NmsTabListPackets(...);

tabs.addOrUpdate(entry);

These are how you do the per-viewer tab things Paper cannot: a custom display name, a client-side sort order, and a custom skin for an entry you fully control.

TabEntry describes the row and TabSkin its texture. PlayerInfoUpdates builds the update actions.

Each method returns one built packet, so the same packet can be sent to many viewers without rebuilding it. That matters: building is the expensive half.

Text display packets

DisplayTextPackets is the per-viewer text-display port, which is what a per-viewer hologram sits on when the public Display API cannot express it.

Shared helpers

HelperDoes
ComponentsAdventure to vanilla component conversion
BundlesGrouping packets so a client applies them in one frame
CodecsThe stream-codec buffer trick for building payloads
ReflectGuarded reflection, so a missing member is a clear failure
EntityIdsFake-entity id allocation off the shared server counter
GameProfilesProfile and texture property construction

Bundling matters more than it looks: an NPC spawn that arrives as four separate packets can render for a frame with the wrong pose or skin. Bundled, the client applies them together.

Sending

PacketSender sender = new PacketSender(resolver);

sender.send(player, packet);
sender.send(channel, packet);