PacketDiagnostics

public final class PacketDiagnostics

One-shot, version-agnostic per-tick packet sampler for modeled entities.

The bundler (PacketBundle.send() in EasyMinecraftGoals) collapses a tick's packets into one ClientboundBundlePacket per player, so the wire packet count looks fine — but the bundle payload is the sum of every bone's move + metadata packet, every tick, for every visible model. That payload (and the client-side deserialization cost) is what saturates connections in dense NPC areas. This class makes that payload measurable.

How it works: when armed, com.magmaguy.freeminecraftmodels.customentity.ModeledEntitiesClock wraps the real packet bundle in a CountingPacketBundle that tallies every addPacket(packet, viewers) call — total packets, packets delivered (summed across viewers), a breakdown by packet type, and a per-player count. After the configured number of ticks the aggregate is frozen into Sample for the command to print.

Counts are exact (they tally the real addPacket calls). Byte figures are rough estimates from estimateBytes — getting the true wire size would require re-serializing each NMS packet through the player's connection codec, which is fragile across versions. The packet count per player per tick is the number that actually explains client saturation, so that's what to watch.

Threading: arming happens from the command thread; counting happens on the async model clock thread. Arming/result handoff uses volatile fields and a synchronized block; the per-tick wrapper is a fresh object each tick so there is no shared mutable counting state between ticks.

Types

Link copied to clipboard
public final class CountingPacketBundle implements AbstractPacketBundle
Decorates a real AbstractPacketBundle, forwarding every call unchanged while tallying packets.
Link copied to clipboard
public final class Sample
Immutable, formatted result of a completed sample.

Properties

Link copied to clipboard
public static volatile PacketDiagnostics.Sample lastSample

Functions

Link copied to clipboard
public static CompletableFuture<PacketDiagnostics.Sample> arm(int ticks)
Arms the sampler for the next ticks model-clock ticks.
Link copied to clipboard
Clock calls these to bracket the window during which direct sends should be captured.
Link copied to clipboard
public static void cancel()
Link copied to clipboard
public static void endDirectCapture()
Link copied to clipboard
public static void endTick(PacketDiagnostics.CountingPacketBundle wrapper, int loadedEntityCount)
Folds one tick's counts into the running sample.
Link copied to clipboard
Link copied to clipboard
public static boolean isArmed()
Link copied to clipboard
public static void recordDirectSend(Object packet, int viewerCount)
Routes one observed direct broadcast into the current sampled tick, if any.
Link copied to clipboard
Wraps the real bundle so the next tick's packets get counted.