Architecture Overview
Gate is built with a modular, event-driven architecture that provides high performance and flexibility. This page explains the core components and how they interact.High-Level Architecture
Gate consists of several key layers that work together:Core Components
Gate Instance
The rootGate struct (pkg/gate/gate.go:127-132) orchestrates multiple proxy editions:
- Manages lifecycle of both Java and Bedrock proxies
- Coordinates startup/shutdown sequences
- Handles configuration loading and validation
- Integrates optional components (Connect API, Web API)
- Java proxy is always created (mandatory)
- Bedrock proxy is created if enabled in config
- Additional services (Connect, API) are registered
- All components start in parallel via
process.Collection
pkg/gate/gate.go:45-124 for the complete initialization logic.
Java Proxy
TheProxy struct (pkg/edition/java/proxy/proxy.go:42-70) is the heart of the Java edition support:
1. Player Registry
Tracks all connected players with two indices:playerNames: Case-insensitive username lookupplayerIDs: UUID-based lookup for guaranteed uniqueness
pkg/edition/java/proxy/proxy.go:692-755 for registration/unregistration logic.
2. Server Registry
Manages backend server registrations:- Servers can be added via config or API
- Config-managed servers are tracked separately
- Supports dynamic registration/unregistration
- Validates server names and addresses
pkg/edition/java/proxy/proxy.go:469-523 for server management.
3. Event System
Gate uses a powerful event-driven architecture:- Events are fired for all significant actions
- Plugins subscribe to events to extend functionality
- Events can be cancelled or modified
- Asynchronous event handling by default
ConnectionEvent: New client connectionLoginEvent: Player authenticationServerConnectedEvent: Player joined backend serverDisconnectEvent: Player disconnectedPluginMessageEvent: Custom protocol messages
pkg/edition/java/proxy/events.go.
4. Command System
Built-in command framework with:- Command registration and routing
- Permission checking
- Tab completion support
- Brigadier-style command trees
Bedrock Proxy
The Bedrock proxy (pkg/edition/bedrock/proxy/proxy.go:55-63) is a lightweight wrapper around Geyser:
- Bedrock proxy requires Java proxy (mandatory dependency)
- Geyser translates Bedrock protocol to Java protocol
- Floodgate handles authentication for Bedrock players
- All Bedrock players appear as Java players internally
pkg/edition/bedrock/proxy/proxy.go:67-126 for startup logic.
Key Abstractions
Player Abstraction
ThePlayer interface (pkg/edition/java/proxy/player.go:52-130) provides a unified API for interacting with connected players:
connectedPlayer (pkg/edition/java/proxy/player.go:132-168)
Key fields:
MinecraftConn: Network connection wrapperprofile: Game profile (name, UUID, properties)connectedServer_: Current backend server connectionconnInFlight: Server connection being establishedconnPhase: Current connection phase (handshake, login, play, etc.)
Server Abstraction
Servers are represented by two key types:ServerInfo
Basic server metadata:pkg/edition/java/proxy/server.go:115-119.
RegisteredServer
Full server registration with player tracking:registeredServer with player list management.
Connection Abstraction
Gate wraps network connections withMinecraftConn which provides:
- Protocol version negotiation
- State management (handshake → login → play)
- Packet compression
- Encryption support
- Read/write timeouts
- Context-aware cancellation
Session Handlers
Gate uses a state machine pattern for handling different connection phases. Each phase has a dedicated session handler:| State | Handler | Purpose |
|---|---|---|
| Handshake | handshakeSessionHandler | Initial protocol negotiation |
| Status | statusSessionHandler | Server list ping responses |
| Login | initialLoginSessionHandler | Authentication and profile setup |
| Config | configSessionHandler | 1.20.2+ configuration phase |
| Play | clientPlaySessionHandler | Active gameplay, packet forwarding |
pkg/edition/java/proxy/session_client_handshake.go:46-53 for the base handler structure.
Thread Safety
Gate is designed for high concurrency: Locking strategy:- Player registry uses
muPRWMutex - Server registry uses
muSRWMutex - Individual players have their own mutex for state
- Read-heavy operations use RLock for better performance
- Each connection runs in its own goroutine
- Packet reading is asynchronous
- Event handlers run concurrently (fire and forget)
Rate Limiting
Gate includes built-in protection against abuse: Connection quota (connectionsQuota):
- Limits new connections per IP address
- Configured via
quota.connectionsin config - Checked in
HandleConnbefore processing
loginsQuota):
- Limits authentication requests per IP
- Prevents Mojang API abuse
- Configured via
quota.loginsin config
pkg/edition/java/proxy/proxy.go:129-143 for quota initialization.
Configuration Management
Gate supports hot-reload of configuration:- Config changes detected via file watch
- New config is validated
ConfigUpdateEventfired with old and new config- Components subscribe and apply changes selectively
- Some changes (like bind address) trigger restarts
pkg/gate/gate.go:271-297 for reload implementation.
Lite Mode
Lite mode (pkg/edition/java/lite) is a special routing mode:
- Minimal memory footprint
- No player state tracking
- Direct connection forwarding
- Route-based server selection
- Cached ping responses
pkg/edition/java/proxy/session_client_handshake.go:98-112 for lite mode branching.
Package Organization
Next Steps
- How It Works: Learn about connection flow and packet handling
- Editions: Understand Java vs Bedrock support
- Configuration: Configure Gate for your needs

