Skip to content

📡 Network Synchronization & Payloads (Minecraft 26.3)

📌 Repository Source Disclaimer: The documentation in this Wiki reflects the current source code state in the repository, which may include recent unreleased commits or developmental features ahead of public release builds on CurseForge and Modrinth.

1. Official Infobox

ParameterTechnical Details
Subsystem NameNetwork Synchronization Protocol
Payload ClassPotionLimitSyncPayload.java
Payload Identifierpotion-stacker:sync_limit
Protocol PhasePlay (clientbound S2C)
Codec ImplementationStreamCodec<RegistryFriendlyByteBuf, PotionLimitSyncPayload>
Client ReceiverPotionStackerFabricClient.java
Server Dispatch EventsServerPlayConnectionEvents.JOIN, DynamicGameRuleManager listener
Menu SynchronizationbroadcastFullState() on containerMenu and inventoryMenu

2. Step-by-Step Player Workflow & Synchronization Lifecycle

  1. Initial Player Connection (Handshake): When a player connects to the dedicated server, ServerPlayConnectionEvents.JOIN triggers. The server queries current active limits from PotionStackerManager and sends a PotionLimitSyncPayload to the connecting client.

  2. Client-Side State Storage: Upon packet receipt on the client, PotionStackerFabricClient queues a task on the Minecraft client render thread (context.client().execute(...)) to update PotionStackerManager.setClientLimit(potionLimit, stewLimit). This ensures client-side slot preview rendering reflects true server limits.

  3. In-Game Administrator Mutation: An administrator executes /gamerule potion-stacker-addon:potion_limit 32. DynamicGameRuleManager detects the value change and invokes PotionStackerManager.setLimits(...).

  4. Full Multi-Client Broadcast & Menu Refresh: The server loops through all online players (server.getPlayerList().getPlayers()), dispatches PotionLimitSyncPayload, and invokes broadcastFullState() on every player's open container and inventory menus, instantly forcing the client to re-render slot contents without ghost items.


3. Mathematical Formulas & Network Bandwidth

Payload Byte Size Calculation ($B$)

Both potionLimit and stewLimit are serialized via ByteBufCodecs.VAR_INT. A Minecraft VarInt encodes 7 bits of data per byte with the 8th bit reserved as continuation flag: $$\text{VarIntBytes}(v) = \begin{cases} 1 & 0 \le v \le 127 \ 2 & 128 \le v \le 16{,}383 \ 3 & 16{,}384 \le v \le 2{,}097{,}151 \ 4 & 2{,}097{,}152 \le v \le 268{,}435{,}455 \ 5 & 268{,}435{,}456 \le v \le 2{,}147{,}483{,}647 \end{cases}$$

The total packet payload size $B$ in bytes is: $$B = \text{VarIntBytes}(P_{\text{limit}}) + \text{VarIntBytes}(S_{\text{limit}})$$

For default settings ($P = 16, S = 16$): $$B = 1 + 1 = 2\text{ bytes}$$

Even at the maximum safe limit ($39{,}768{,}215$): $$B = 4 + 4 = 8\text{ bytes}$$

Network overhead is effectively $O(1)$ and negligible across all network configurations.


4. Visual ASCII Diagrams & Packet Lifecycle

Player Join Handshake Protocol

   [ Client ]                                               [ Dedicated Server ]
       |                                                             |
       |----------------- C2S Login / Handshake -------------------->|
       |                                                             |
       |                                              ServerPlayConnectionEvents.JOIN
       |                                                             |
       |                                              Query PotionStackerManager
       |                                                pLimit=16, sLimit=16
       |                                                             |
       |<--- S2C PotionLimitSyncPayload(16, 16) ---------------------|
       |
   Receive Packet
   context.client().execute()
   PotionStackerManager.setClientLimit(16, 16)
       |
   Client GUI & Tooltips Synchronized

Live Dynamic GameRule Update & State Refresh

   [ Server Admin: /gamerule potion-stacker-addon:potion_limit 64 ]
                                 |
                                 v
                 PotionStackerManager.setLimits(64, 16, server)
                                 |
                 +---------------+---------------+
                 |                               |
                 v                               v
      Send PotionLimitSyncPayload        For every ServerPlayer:
         to all connected players           containerMenu.broadcastFullState()
                                            inventoryMenu.broadcastFullState()
                                                 |
                                                 v
                                      Eliminates Ghost Items & Resets Caches

5. Packet Buffer Layout & Codec Schema

Binary Packet Byte Stream Layout:

+------------------------------------+------------------------------------+
| Field 1: potionLimit (VarInt)      | Field 2: stewLimit (VarInt)        |
| Range: 1 .. 2,147,483,647 (1-5 B)  | Range: 1 .. 2,147,483,647 (1-5 B)  |
+------------------------------------+------------------------------------+

Codec Definition (PotionLimitSyncPayload.java):

java
public static final StreamCodec<RegistryFriendlyByteBuf, PotionLimitSyncPayload> CODEC = StreamCodec.composite(
    ByteBufCodecs.VAR_INT,
    PotionLimitSyncPayload::potionLimit,
    ByteBufCodecs.VAR_INT,
    PotionLimitSyncPayload::stewLimit,
    PotionLimitSyncPayload::new
);

6. Exhaustive Reference Matrix

AttributeValueDescription
Payload Identifierpotion-stacker:sync_limitCustomPacketPayload.Type identifier
Network ChannelclientboundPlayRegistered via PayloadTypeRegistry
Field 0potionLimit (int)Maximum stack limit for potions
Field 1stewLimit (int)Maximum stack limit for stews/soups
Execution ThreadMain Client Render ThreadDispatched via context.client().execute()
Trigger 1Player JoinServerPlayConnectionEvents.JOIN
Trigger 2GameRule MutationPotionStackerManager.setLimits
Menu Sync HookbroadcastFullState()Forces client inventory slot cache refresh

7. Developer & Network Hooks

Payload Registration (PotionStackerFabric.java):

java
PayloadTypeRegistry.clientboundPlay().register(
    PotionLimitSyncPayload.TYPE,
    PotionLimitSyncPayload.CODEC
);

Client Receiver Registration (PotionStackerFabricClient.java):

java
ClientPlayNetworking.registerGlobalReceiver(PotionLimitSyncPayload.TYPE, (payload, context) -> {
    context.client().execute(() -> {
        PotionStackerManager.setClientLimit(payload.potionLimit(), payload.stewLimit());
    });
});

Official documentation & web portal for Dasik Igaijinn mods.