How Gate Works
This page explains the internal mechanics of Gate: how connections are established, how packets flow through the proxy, and how players move between servers.Connection Lifecycle
1. Initial Connection
When a client connects to Gate, the following sequence occurs: Code path:Proxy.listenAndServe()accepts connection (pkg/edition/java/proxy/proxy.go:543-582)Proxy.HandleConn()checks rate limits (proxy.go:584-640)MinecraftConnis created with handshake handlerhandshakeSessionHandler.HandlePacket()processes handshake (pkg/edition/java/proxy/session_client_handshake.go:67-136)
2. Handshake Phase
The handshake is the first packet sent by any Minecraft client:- Determine client protocol version
- Extract virtual host (for forced hosts)
- Decide whether to enter status or login flow
- Check version compatibility
ServerAddress field allows Gate to implement “forced hosts” - routing players to different servers based on the domain they connected to:
pkg/edition/java/proxy/session_client_handshake.go:114-118 for virtual host parsing.
3. Status Phase (Server Ping)
WhenNextStatus = 1, the client wants server status:
Flow:
- Switch to
statusSessionHandler - Wait for
StatusRequestpacket - Resolve ping response:
- In normal mode: forward to a backend server
- In lite mode: use cached response or route-based resolution
- Fire
ProxyPingEventto allow modification - Send
StatusResponseto client - Optionally handle
StatusPing(latency measurement)
pkg/edition/java/proxy/session_status.go
4. Login Phase
WhenNextStatus = 2, the client wants to join:
Step 4.1: Version Check
Gate first validates the client’s protocol version:Step 4.2: Rate Limiting
Login quota prevents authentication spam:pkg/edition/java/proxy/session_client_handshake.go:149-154.
Step 4.3: Pre-Authentication Event
ThePreLoginEvent fires before authentication:
- Deny the login
- Force offline mode for this player
- Set a custom reason for denial
Step 4.4: Authentication
In online mode, Gate authenticates with Mojang:hasJoined endpoint) to:
- Verify the player owns the account
- Retrieve their UUID and profile
- Fetch skin/cape properties
pkg/edition/java/auth/authenticator.go for authentication logic.
Step 4.5: LoginEvent
TheLoginEvent allows plugins to:
- Deny the login
- Set initial server
- Modify game profile
Step 4.6: Player Registration
Gate attempts to register the player:onlineModeKickExistingPlayers: true, existing connections are kicked to allow the new one.
See pkg/edition/java/proxy/proxy.go:704-745.
Step 4.7: Initial Server Connection
Finally, Gate connects the player to their initial backend server (determined by config orLoginEvent):
5. Play Phase
Once connected to a backend server, Gate enters “passthrough mode”: Key handlers:clientPlaySessionHandler: Handles client → backend packetsbackendPlaySessionHandler: Handles backend → client packets
| Packet | Direction | Purpose |
|---|---|---|
PluginMessage | Both | Custom protocol, server switching |
Disconnect | Backend → Client | Track disconnects, try fallback servers |
TabCompleteRequest/Response | Both | Command completion |
ClientSettings | Client → Backend | Track player preferences |
KeepAlive | Both | Connection health monitoring |
Chat | Client → Backend | Command interception |
pkg/edition/java/proxy/session_client_play.go and session_backend_play.go.
Server Switching
One of Gate’s most powerful features is seamless server switching:Server Switch Flow
Code path:player.CreateConnectionRequest(server)creates aConnectionRequestConnectionRequest.Connect()orConnectWithIndication()initiates the switch- Gate validates the target server exists
ServerPreConnectEventfires (can be denied or redirected)- New server connection is established
ServerConnectedEventfires- Old connection is gracefully closed
- Player’s
connectedServer_field is updated - Client receives respawn/config packets to switch dimension
pkg/edition/java/proxy/server.go and pkg/edition/java/proxy/session_backend_transition.go for implementation.
Packet Handling Architecture
Gate uses a layered approach to packet handling:Layer 1: Network (netmc)
Thenetmc package provides low-level packet I/O:
- Packet framing (length prefix)
- Compression (zlib)
- Encryption (AES/CFB8)
- Protocol version mapping
- Connection state management
Layer 2: Protocol (proto)
Theproto package defines packet structures:
packet.Handshakepacket.StatusRequest/StatusResponsepacket.LoginStart/LoginSuccesspacket.JoinGamepacket.PluginMessage
Layer 3: Session Handlers
Session handlers process parsed packets:handshakeSessionHandlerstatusSessionHandlerinitialLoginSessionHandlerclientPlaySessionHandlerbackendPlaySessionHandler
Layer 4: Event System
Significant actions trigger events:Connection State Machine
Each connection progresses through states: State registry: Gate maintains astate.Registry that maps:
- Packet ID → Packet struct for decoding
- Packet struct → Packet ID for encoding
Performance Optimizations
Zero-Copy Packet Forwarding
For packets that don’t need inspection, Gate uses zero-copy forwarding:Connection Pooling
Backend connections use connection pooling to reduce latency on server switches.Lite Mode Fast Path
When lite mode is enabled:- No player state tracking
- Direct connection piping
- Cached ping responses
- Route-based server selection
pkg/edition/java/lite/forward.go.
Asynchronous Event Handling
Events are fired asynchronously:Error Handling
Gate employs graceful error handling: Connection errors:- Network errors → clean disconnect
- Protocol errors → disconnect with reason
- Timeout errors → keep-alive checks
- Connection failed → try fallback servers
- Disconnected during play → return to lobby
- Config error → disconnect with admin notification
- Check if player has a fallback server list
- Try each server in order
- If all fail, disconnect player with reason
pkg/edition/java/proxy/player.go disconnect handling.
Next Steps
- Architecture: Learn about Gate’s component structure
- Editions: Understand Java vs Bedrock support
- Events Reference: See all available events

