ENetServer

Inherits: Object

High-level ENet server singleton with automatic threading and packet encoding.

Description

ENetServer is a singleton that provides a high-level interface for creating game servers using the ENet library. It handles networking on a separate thread, automatically encodes/decodes packets, supports multiple packet formats, node serialization, and configurable authentication.

The server automatically polls for network events on a background thread, ensuring the main game thread is never blocked by network operations. All signals are emitted on the main thread for safe interaction with the scene tree.

Example usage:

func _ready():
    ENetServer.peer_authenticated.connect(_on_peer_authenticated)
    ENetServer.packet_received.connect(_on_packet_received)
    ENetServer.create_server(7777, 32, 2)

func _on_peer_authenticated(peer: ENetServerPeer):
    print("Player connected: ", peer.peer_id)
    ENetServer.send_packet(peer.peer_id, {"type": "welcome"}, 0, true)

func _on_packet_received(peer: ENetServerPeer, packet: Variant, channel: int):
    if packet is Dictionary and packet.get("type") == "chat":
        ENetServer.send_packet_to_all(packet, 0, true, [peer.peer_id])

Tutorials

Methods

void

broadcast_packet(packet: Variant, channel: int = 0, reliable: bool = true)

Error

create_server(port: int, max_peers: int = 32, max_channels: int = 2)

int

get_authenticated_peer_count() const

AuthMode

get_authentication_mode() const

float

get_authentication_timeout() const

int

get_local_port() const

ENetServerPeer

get_peer(peer_id: int)

int

get_peer_count() const

Array[ENetServerPeer]

get_peers()

int

get_poll_rate() const

bool

has_event(event_name: String) const

bool

is_server_active() const

void

kick_peer(peer_id: int, reason: String = "")

void

register_event(event_name: String, callback: Callable)

Error

send_node_state(peer_id: int, node: Node, flags: int, channel: int = 0)

void

send_node_to_all(node: Node, flags: int, channel: int = 0)

Error

send_packet(peer_id: int, packet: Variant, channel: int = 0, reliable: bool = true)

void

send_packet_to_all(packet: Variant, channel: int = 0, reliable: bool = true, exclude: Array[int] = [])

void

send_packet_to_multiple(peer_ids: Array[int], packet: Variant, channel: int = 0, reliable: bool = true)

void

set_authentication_mode(mode: AuthMode)

void

set_authentication_timeout(timeout: float)

void

set_compression_mode(mode: CompressionMode)

void

set_custom_authenticator(callable: Callable)

void

set_poll_rate(rate_ms: int)

void

stop_server()

Error

trigger_event(peer_id: int, event_name: String, payload: Dictionary, channel: int = 0, reliable: bool = true)

void

trigger_event_to_all(event_name: String, payload: Dictionary, channel: int = 0, reliable: bool = true, exclude: Array[int] = [])

void

unregister_event(event_name: String)


Signals

custom_event_received(peer: ENetServerPeer, event_name: String, payload: Variant, channel: int) 🔗

Emitted when a custom event packet is received from a peer and successfully routed to a registered handler.


packet_received(peer: ENetServerPeer, packet: Variant, channel: int) 🔗

Emitted when a packet is received from a peer. The packet is automatically decoded.


peer_authenticated(peer: ENetServerPeer) 🔗

Emitted when a peer is fully authenticated and ready for game data.


peer_connecting(peer: ENetServerPeer, data: int) 🔗

Emitted when a peer first connects. You can call ENetServerPeer.reject() during this signal to reject the connection.


peer_disconnected(peer: ENetServerPeer, reason: String) 🔗

Emitted when a peer disconnects.


peer_prelogin(peer: ENetServerPeer, login_data: Dictionary) 🔗

Emitted when a peer enters the prelogin phase (if authentication is enabled). You should call either ENetServerPeer.authenticate() or ENetServerPeer.reject() during this signal.


raw_packet_received(peer: ENetServerPeer, data: PackedByteArray, channel: int) 🔗

Emitted when a packet is received, providing the raw byte data before decoding.


server_started(port: int) 🔗

Emitted when the server successfully starts.


server_stopped() 🔗

Emitted when the server stops.


unknown_event_received(peer: ENetServerPeer, event_name: String, payload: Variant, channel: int) 🔗

Emitted when a custom event packet is received from a peer but no matching event handler is registered locally.


Enumerations

enum AuthMode: 🔗

AuthMode AUTH_NONE = 0

No authentication required. Peers are immediately authenticated upon connection.

AuthMode AUTH_PRELOGIN_ONLY = 1

Peers must be manually authenticated via the peer_prelogin signal.

AuthMode AUTH_CUSTOM = 2

Custom authentication using the callable set with set_custom_authenticator().


Method Descriptions

void broadcast_packet(packet: Variant, channel: int = 0, reliable: bool = true) 🔗

Broadcasts a packet to all connected peers. Equivalent to send_packet_to_all() with no exclusions.


Error create_server(port: int, max_peers: int = 32, max_channels: int = 2) 🔗

Creates and starts the server on the specified port. The server will listen for connections and automatically start the polling thread.

Returns @GlobalScope.OK on success, or an error code on failure.


int get_authenticated_peer_count() const 🔗

Returns the number of peers that are fully authenticated (ENetServerPeer.STATE_AUTHENTICATED).


AuthMode get_authentication_mode() const 🔗

Returns the current authentication mode.


float get_authentication_timeout() const 🔗

Returns the authentication timeout in seconds.


int get_local_port() const 🔗

Returns the local port the server is bound to.


ENetServerPeer get_peer(peer_id: int) 🔗

Returns the peer with the specified ID, or null if no such peer exists.


int get_peer_count() const 🔗

Returns the total number of connected peers.


Array[ENetServerPeer] get_peers() 🔗

Returns an array of all connected peers.


int get_poll_rate() const 🔗

Returns the current polling rate in milliseconds.


bool has_event(event_name: String) const 🔗

Returns true if a custom event handler is registered for the specified event name.


bool is_server_active() const 🔗

Returns true if the server is currently active.


void kick_peer(peer_id: int, reason: String = "") 🔗

Disconnects the specified peer with an optional reason. Server will emit peer_disconnected with this reason.

# Kick a peer if they are AFK
ENetServer.kick_peer(peer_id, "Kicked for being AFK")

void register_event(event_name: String, callback: Callable) 🔗

Registers a custom event callback. The callable will be executed whenever a custom event packet with the matching event_name is received from any client.

func _ready():
    ENetServer.register_event("player_jump", _on_player_jump)

func _on_player_jump(peer: ENetServerPeer, payload: Dictionary, channel: int):
    print("Player ", peer.get_peer_id(), " jumped to ", payload.get("position"))

Error send_node_state(peer_id: int, node: Node, flags: int, channel: int = 0) 🔗

Sends a serialized node state to the specified peer. The flags parameter controls what data is sent. See NodeSyncFlags.


void send_node_to_all(node: Node, flags: int, channel: int = 0) 🔗

Sends a serialized node state to all connected peers.


Error send_packet(peer_id: int, packet: Variant, channel: int = 0, reliable: bool = true) 🔗

Sends a packet to the specified peer. The packet can be of any type (Dictionary, String, int, etc.) and will be automatically encoded.

# Send a simple String
ENetServer.send_packet(peer_id, "Welcome to the server", 0, true)

# Send a Dictionary packet
ENetServer.send_packet(peer_id, {"type": "ping", "timestamp": Time.get_ticks_msec()}, 0, true)

void send_packet_to_all(packet: Variant, channel: int = 0, reliable: bool = true, exclude: Array[int] = []) 🔗

Sends a packet to all connected peers, optionally excluding specific peer IDs.

# Example: Send a chat message to everyone except the sender
var exclude_list : Array[int] = [sender_peer_id]
ENetServer.send_packet_to_all({"type": "chat", "msg": "Hello"}, 0, true, exclude_list)

void send_packet_to_multiple(peer_ids: Array[int], packet: Variant, channel: int = 0, reliable: bool = true) 🔗

Sends a packet to multiple specified peers.


void set_authentication_mode(mode: AuthMode) 🔗

Sets the authentication mode for the server. This controls how new connections are handled.


void set_authentication_timeout(timeout: float) 🔗

Sets the timeout in seconds for authentication. Peers that don't authenticate within this time will be disconnected.


void set_compression_mode(mode: CompressionMode) 🔗

Sets the compression mode for network packets. See CompressionMode.


void set_custom_authenticator(callable: Callable) 🔗

Sets a custom authentication callable that will be invoked for each peer during the prelogin phase.

The callable must return a Dictionary or emit a signal depending on your auth routine.

func _ready():
    ENetServer.set_authentication_mode(ENetServer.AUTH_CUSTOM)
    ENetServer.set_custom_authenticator(_custom_auth_logic)

func _custom_auth_logic(peer: ENetServerPeer, data: Dictionary) -> void:
    if data.get("token") == "secret123":
        peer.authenticate() # Approved
    else:
        peer.reject("Invalid token") # Denied

void set_poll_rate(rate_ms: int) 🔗

Sets how often (in milliseconds) the polling thread checks for network events. Lower values mean lower latency but higher CPU usage. Default is 10ms.


void stop_server() 🔗

Stops the server, disconnects all peers, and stops the polling thread.


Error trigger_event(peer_id: int, event_name: String, payload: Dictionary, channel: int = 0, reliable: bool = true) 🔗

Triggers a custom event on the specified peer by sending a specially formatted packet containing the event_name and payload.


void trigger_event_to_all(event_name: String, payload: Dictionary, channel: int = 0, reliable: bool = true, exclude: Array[int] = []) 🔗

Triggers a custom event on all connected peers, optionally excluding specific peer IDs.


void unregister_event(event_name: String) 🔗

Unregisters a previously registered custom event handler.