User Tools

Site Tools


tutorial:networking

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorial:networking [2022/02/09 16:54] – external edit 127.0.0.1tutorial:networking [2024/10/26 20:39] (current) – [How do I fix the crash?] double "be" fix skycatminepokie
Line 2: Line 2:
 It is recommended to use the new networking API described on this page. It is recommended to use the new networking API described on this page.
 The old page can be [[tutorial:legacy:networking-v0|found here]]. The old page can be [[tutorial:legacy:networking-v0|found here]].
 +
 +For the even newer networking API introduced at 1.20.5, read the [[#Networking in 1.20.5 | separate documentation below]].
  
 ====== Networking ====== ====== Networking ======
Line 13: Line 15:
 Say you had a wand which highlights the block you are looking at to all nearby players. Say you had a wand which highlights the block you are looking at to all nearby players.
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-class HighlightingWandItem extends Item {+public class HighlightingWandItem extends Item {
     public HighlightingWand(Item.Settings settings) {     public HighlightingWand(Item.Settings settings) {
         super(settings)         super(settings)
Line 56: Line 58:
 | Singleplayer (or LAN host)    | Yes -> Full access          | | Singleplayer (or LAN host)    | Yes -> Full access          |
  
-It may seem complicated to have communication with the server in three different ways. However, you don't need to communicate in three different ways with the game client. Since all three connection types communicate with the game client using packets, you only need to communicate with the game client like you are always running on a dedicated server. Connection to a server over LAN or Singleplayer can be also be treated like the server is a remote dedicated server; so your game client cannot directly access the server instance.+It may seem complicated to have communication with the server in three different ways. However, you don't need to communicate in three different ways with the game client. Since all three connection types communicate with the game client using packets, you only need to communicate with the game client like you are always running on a dedicated server. Connection to a server over LAN or Singleplayer can also be treated like the server is a remote dedicated server; so your game client cannot directly access the server instance.
  
 ===== An introduction to networking ===== ===== An introduction to networking =====
Line 78: Line 80:
 </code> </code>
  
-Next, we need to send the packet to the game client. First, you need to define an ''Identifier'' used to identify your packet. For this example our Identifier will be ''wiki_example:highlight_block''. In order to send the packet to the game client, you need to specify which player's game client you want the packet to be received by. Since the action is occurring on the logical server, we may upcast the ''player'' to a ''ServerPlayerEntity''.+Next, we need to send the packet to the game client. First, you need to define an ''Identifier'' used to identify your packet. For this example our Identifier will be ''tutorial:highlight_block''. In order to send the packet to the game client, you need to specify which player's game client you want the packet to be received by. Since the action is occurring on the logical server, we may upcast the ''player'' to a ''ServerPlayerEntity''. 
 +<code java> 
 +public class TutorialNetworkingConstants { 
 +    // Save the id of the packet so we can reference it later 
 +    public static final Identifier HIGHLIGHT_PACKET_ID = Identifier.of("tutorial", "highlight_block"); 
 +
 +</code>
  
 To send the packet to the player, we will use some of the methods inside of ''ServerPlayNetworking''. We will use the following method inside of that class: To send the packet to the player, we will use some of the methods inside of ''ServerPlayNetworking''. We will use the following method inside of that class:
Line 123: Line 131:
     client.execute(() -> {     client.execute(() -> {
         // Everything in this lambda is run on the render thread         // Everything in this lambda is run on the render thread
-        ClientBlockHighlighting.highlightBlock(client, target); 
     });     });
 }); });
Line 211: Line 218:
 After this change, when you use the wand, your friend should also see the highlighted block on their own client. After this change, when you use the wand, your friend should also see the highlighted block on their own client.
  
-====== Advanced Networking topics ====== 
  
-The Networking system Fabric API supplies is very flexible and supports additional features other than just sending and receiving simple packetsAs some of these more advanced topics are longhere are links to their specific pages:+===== Networking in 1.20.5 ===== 
 +Since 1.20.5, the logic of networking has been totally rewritten. In 1.20.5''RegistryByteBuf'' is now used in PLAY-phase networking and you have to define a custom ''Payload''. First, define the payload that includes a ''BlockPos'':
  
-^ Networking Topic ^ Description ^ +<code java> 
-| [[tutorial:networking:connection_events|Connection Network connection events]] | Events related to the the lifecycle of a connection to a client or server | +public record BlockHighlightPayload(BlockPos blockPos) implements CustomPayload { 
-| [[tutorial:networking:channel_events|Channel registration events]] | Events related to a server of client declaring the ability to receive a packet on a channel of a specific name | +    public static final CustomPayload.Id<BlockHighlightPayload> ID = new CustomPayload.Id<>(TutorialNetworkingConstants.HIGHLIGHT_PACKET_ID); 
-| [[tutorial:networking:login|Login phase networking]]| Sending requests to a client during login; and allowing delay of login for a short amount of time | +    public static final PacketCodec<RegistryByteBuf, BlockHighlightPayload> CODEC = PacketCodec.tuple(BlockPos.PACKET_CODEC, BlockHighlightPayload::blockPos, BlockHighlightPayload::new); 
-| [[tutorial:networking:dynamic_handlers|Dynamic registration of channel handlers]]| Allowing for a connection to receive a packet with a special handler |+    // should you need to send more data, add the appropriate record parameters and change your codec: 
 +    // public static final PacketCodec<RegistryByteBuf, BlockHighlightPayload> CODEC = PacketCodec.tuple( 
 +    //         BlockPos.PACKET_CODEC, BlockHighlightPayload::blockPos, 
 +    //         PacketCodecs.INTEGER, BlockHighlightPayload::myInt, 
 +    //         Uuids.PACKET_CODEC, BlockHighlightPayload::myUuid, 
 +    //         BlockHighlightPayload::new 
 +    // );
  
 +    @Override
 +    public CustomPayload.Id<? extends CustomPayload> getId() {
 +        return ID;
 +    }
 +}
 +</code>
 +
 +And then, register the receiver like this:
 +<code java>
 +// NOTE: PayloadTypeRegistry has 2 functions:
 +//       - playS2C is for server -> client communication
 +//       - playC2S is for client -> server communication
 +
 +// In your common initializer method
 +PayloadTypeRegistry.playS2C().register(BlockHighlightPayload.ID, BlockHighlightPayload.CODEC);
 +
 +// In your client-only initializer method
 +ClientPlayNetworking.registerGlobalReceiver(BlockHighlightPayload.ID, (payload, context) -> {
 +    context.client().execute(() -> {
 +        ClientBlockHighlighting.highlightBlock(client, payload.blockPos());
 +    });
 +});
 +</code>
 +
 +Now, on the server side, you can send the packet to players like this:
 +<code java>
 +    public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
 +        if (world.isClient()) return super.use(world, user, hand);
 +
 +        // ...
 +
 +        for (ServerPlayerEntity player : PlayerLookup.tracking((ServerWorld) world, target)) {
 +            ServerPlayNetworking.send(player, new BlockHighlightPayload(target));
 +        }
 +
 +        return TypedActionResult.success(user.getHandStack(hand));
 +    }
 +</code>
tutorial/networking.1644425689.txt.gz · Last modified: 2022/02/09 16:54 by 127.0.0.1