---
# System prepended metadata

title: Yet another networking document

---

# Vanilla protocol

```plantuml
@startuml

skinparam sequenceMessageAlign center

participant Server as Server
participant Client as Client


[-[#red]-> Client : Phase switch to "Configuration"

[-[#red]-> Server : Phase switch to "Configuration"
    
== Configuration start: Ping & Pong ==

Server ->(20) Client : ClientboundPingPacket
Client ->(20) Server : ServerboundPongPacket

== Configuration payloads ==
    
note across
    Vanilla actually starts immediately
    with the rest of the configuration,
    without waiting for Pong.
end note

Server ->(20) Client : A bunch of packets.
note left
    Here, vanilla sends the enabled features,
    the registry data, the tags, etc...
    
    It does it before starting with the configuration tasks
end note
    
== Configuration tasks ==
    
loop foreach : ConfigurationTask
    
    note across
        Allthough vanilla implements a small amount of 
        configuration tasks it-self, most tasks come from mods.
    
        As such this section will describe the tasks generically.
    end note
    
    Server ->(20) Client : DataPacket
    
    note left 
        Most configuration tasks will send some form
        of data gram packet to the client.
    
        Examples are: Payloads to sync the registry or
        server configuration entries, but also vanilla
        uses this phase to sync the server resource
        pack.
    end note
    
    Client -->(20) Server : AcknowledgementPacket
    
    note right
        The client can optionally acknowledge the 
        received packet.
    
        If the server is expecting an acknowledgement
        packet to be sent by the client it will wait
        for that packet to be received by it, before
        starting the next task.
    end note
end

    
group JoinWorldTask
    note across
        This is the final configuration task,
        used to transition the client to the play phase.
        
        As such, it is shown separately.
    end note
    
    Server ->(20) Client : ClientboundFinishConfigurationPacket
    
Client --[#red]>] : "Phase switch to Play"
    
    Client ->(20) Server: ServerboundFinishConfigurationPacket
end group
    
Server --[#red]>] : "Phase switch to Play"
@enduml
```

# Full protocol
Vanilla is in black.

General modded connection, using only `minecraft:register` and `minecraft:unregister` packets, is in blue.

NeoForge connection is in orange.

```plantuml
@startuml

skinparam sequenceMessageAlign center

participant Server as Server
participant Client as Client


[-[#red]-> Client : Phase switch to "Configuration"

[-[#red]-> Server : Phase switch to "Configuration"
    
== Configuration start: Ping & Pong ==

Server --[#blue]>(20) Client : minecraft:unregister (previous server channels)
Server -[#blue]>(20) Client : minecraft:register (server configuration channels)

Server -[#orange]>(20) Client : neoforge:register
    
Server ->(20) Client : ClientboundPingPacket
    
note right
    By now, the client knows which type
    of server it is talking to
    (vanilla, modded, neoforge).
end note
    
Client -[#blue]>(20) Server : minecraft:register (client configuration channels)

Client -[#orange]>(20) Server : neoforge:register
    
Client ->(20) Server : ServerboundPongPacket
    
note left
    By now, the server knows which type
    of client it is talking to
    (vanilla, modded, neoforge).
end note

== Configuration payloads ==

note across
    Vanilla actually starts immediately
    with the rest of the configuration,
    without waiting for Pong.
    
    Modded-aware servers will wait for Pong, to understand
    which kind of connection they are dealing with.
end note

Server -[#orange]>(20) Client : neoforge:network

Server ->(20) Client : A bunch of packets.
note left
    Here, vanilla sends the enabled features,
    the registry data, the tags, etc...
    
    It does it before starting with the configuration tasks
end note
    
== Configuration tasks ==
    
loop foreach : ConfigurationTask
    
    note across
        Allthough vanilla implements a small amount of 
        configuration tasks it-self, most tasks come from mods.
    
        As such this section will describe the tasks generically.
    end note
    
    Server ->(20) Client : DataPacket
    
    note left 
        Most configuration tasks will send some form
        of data gram packet to the client.
    
        Examples are: Payloads to sync the registry or
        server configuration entries, but also vanilla
        uses this phase to sync the server resource
        pack.
    end note
    
    Client -->(20) Server : AcknowledgementPacket
    
    note right
        The client can optionally acknowledge the 
        received packet.
    
        If the server is expecting an acknowledgement
        packet to be sent by the client it will wait
        for that packet to be received by it, before
        starting the next task.
    end note
end

    
group JoinWorldTask
    note across
        This is the final configuration task,
        used to transition the client to the play phase.
        
        As such, it is shown separately.
    end note
    
    Server ->(20) Client : ClientboundFinishConfigurationPacket
    
Client --[#red]>] : "Phase switch to Play"
    
    Client -[#blue]>(20) Server : minecraft:register (client play channels)
    
    Server -[#blue]>(20) Client : minecraft:register (server play channels)
    note left
        The minecraft:register packet with server
    play channels is sent immediately after
        the ClientboundFinishConfigurationPacket.
    
        (It does not wait for minecraft:register
            to be received from the client)
    end note
    
    Client ->(20) Server: ServerboundFinishConfigurationPacket
end group
    
Server --[#red]>] : "Phase switch to Play"
@enduml
```