### Host a Game with SteamMultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/README.md Use this snippet to start hosting a game. Ensure Steam is initialized and the server relay is enabled. ```gdscript var peer = SteamMultiplayerPeer.new() peer.set_server_relay(true) var error = peer.create_host(0) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) peer.peer_connected.connect(func(id): print("Player joined: ", id)) ``` -------------------------------- ### Client Setup Sequence Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/architecture.md Outlines the process for a client to establish a connection to a host. Involves creating necessary network components and initiating the connection request. ```text 1. SteamMultiplayerPeer::create_client(host_id, port) ├─ Set server = false ├─ Set unique_id = generate_unique_id() ├─ _create_listen_socket(port) ← P2P requires listening too ├─ _create_poll_group() ├─ add_peer(host_id, port) │ └─ SteamNetworkingSockets::ConnectP2P() ├─ Set connection_status = CONNECTION_CONNECTING └─ Return OK 2. Client initiates connection to host 3. Waits for peer_connected signal ``` -------------------------------- ### Example: Set max_channels for simple games Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/configuration.md Configure SteamMultiplayerPeer to use 2 communication channels, which is sufficient for simpler games like turn-based titles. ```gdscript # For simple turn-based games, fewer channels is fine ProjectSettings.set_setting("steam/multiplayer_peer/max_channels", 2) ``` -------------------------------- ### Host or Join a Game Using Steam Lobbies Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/README.md These examples demonstrate how to host a game within a Steam Lobby or join an existing one. ```gdscript # Host a game in a lobby var error = peer.host_with_lobby(lobby_id) # Or join a lobby var error = peer.connect_to_lobby(lobby_id) ``` -------------------------------- ### Host Setup Sequence Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/architecture.md Illustrates the steps involved in setting up a host using SteamNetworkingSockets. Includes creating a listen socket, poll group, and configuring connection refusal. ```text 1. SteamMultiplayerPeer::create_host(port) ├─ Set server = true ├─ Set unique_id = 1 ├─ _create_listen_socket(port) │ └─ SteamNetworkingSockets::CreateListenSocketP2P() ├─ _create_poll_group() │ └─ SteamNetworkingSockets::CreatePollGroup() ├─ set_refuse_new_connections(false) └─ Set connection_status = CONNECTION_CONNECTED 2. Listen socket begins receiving incoming connection requests ``` -------------------------------- ### Host with Lobby Setup Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/architecture.md Explains how to host a game session using a Steam lobby. This involves creating a host and then adding existing lobby members as peers. ```text 1. SteamMultiplayerPeer::host_with_lobby(lobby_id) ├─ Validate: user is member and owner ├─ Store lobby ID in tracked_lobby ├─ create_host(0) ├─ Iterate existing lobby members └─ add_peer(member_id) for each non-self member 2. Register LobbyChatUpdate callback 3. When members join: add_peer() connects to them 4. When members leave: lobby_chat_update() disconnects them ``` -------------------------------- ### Basic Host Setup with SteamMultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md Use this pattern to initialize SteamMultiplayerPeer as a host. It configures networking, creates the host, and connects to Godot's multiplayer system. Listen for peer connection and disconnection events. ```gdscript extends Node var multiplayer_peer: SteamMultiplayerPeer func _ready(): multiplayer_peer = SteamMultiplayerPeer.new() # Configure networking multiplayer_peer.set_no_nagle(true) multiplayer_peer.set_server_relay(true) # Create host var error = multiplayer_peer.create_host(0) if error != OK: print("Failed to create host: ", error) return # Connect to Godot's multiplayer system get_tree().multiplayer.set_multiplayer_peer(multiplayer_peer) get_tree().multiplayer.set_transfer_mode(MultiplayerPeer.TRANSFER_MODE_UNRELIABLE) # Listen for peer events multiplayer_peer.peer_connected.connect(_on_peer_connected) multiplayer_peer.peer_disconnected.connect(_on_peer_disconnected) print("Hosting game") func _on_peer_connected(peer_id: int): print("Player joined: ", peer_id) # Notify other players broadcast_game_state() func _on_peer_disconnected(peer_id: int): print("Player left: ", peer_id) # Clean up peer-specific state func broadcast_game_state(): multiplayer_peer.set_target_peer(0) # Broadcast rpc("update_game_state", get_game_state()) func get_game_state(): return {"time": Time.get_ticks_msec(), "players": get_tree().get_nodes_in_group("player")} ``` -------------------------------- ### Host Multiplayer Game on Default Port Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/configuration.md Example of hosting a regular multiplayer game using the default virtual port (0). ```gdscript var game_peer = SteamMultiplayerPeer.new() game_peer.create_host(0) ``` -------------------------------- ### Verifying Lobby Membership before Connecting Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md Before calling connect_to_lobby, this example shows how to check for ERR_CANT_CREATE, which can indicate non-membership in the target lobby. Ensure you have joined the lobby first. ```gdscript # Verify lobby membership before connecting var lobby_id = 109775240910345216 # (Ensure you called SteamMatchmaking().JoinLobby() first) var error = peer.connect_to_lobby(lobby_id) if error == ERR_CANT_CREATE: print("Not a member of the lobby") ``` -------------------------------- ### Example: Set max_channels for multiple channels Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/configuration.md Configure SteamMultiplayerPeer to use 8 communication channels, suitable for games requiring parallel streams like chat or large data transfers. ```gdscript # For games needing multiple parallel channels (chat, game state, large transfers) ProjectSettings.set_setting("steam/multiplayer_peer/max_channels", 8) ``` -------------------------------- ### Using Multiple Channels for Network Traffic Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md This example shows how to set up and use distinct channels for different types of network traffic. Configure the maximum number of channels in your project settings. Note that SteamMultiplayerPeer currently routes all packets through the default channel, with channel selection available at the SteamPacketPeer level for advanced use cases. ```gdscript extends Node var multiplayer_peer: SteamMultiplayerPeer # Channel constants const CHANNEL_MOVEMENT = 0 const CHANNEL_CHAT = 1 const CHANNEL_CRITICAL = 2 func _ready(): multiplayer_peer = SteamMultiplayerPeer.new() # Configure channels in project settings: # steam/multiplayer_peer/max_channels = 4 multiplayer_peer.create_host() get_tree().multiplayer.set_multiplayer_peer(multiplayer_peer) func send_movement_update(position: Vector3): # Frequent updates on movement channel (unreliable) multiplayer_peer.set_target_peer(0) get_tree().multiplayer.set_transfer_mode(MultiplayerPeer.TRANSFER_MODE_UNRELIABLE) var data = position.to_bytes() multiplayer_peer.put_packet(data) func send_chat_message(message: String): # Chat on dedicated channel (reliable) multiplayer_peer.set_target_peer(0) get_tree().multiplayer.set_transfer_mode(MultiplayerPeer.TRANSFER_MODE_RELIABLE) var data = message.to_utf8_buffer() multiplayer_peer.put_packet(data) func send_critical_event(event: String): # Critical events on critical channel (reliable) multiplayer_peer.set_target_peer(0) get_tree().multiplayer.set_transfer_mode(MultiplayerPeer.TRANSFER_MODE_RELIABLE) var data = event.to_utf8_buffer() multiplayer_peer.put_packet(data) # Note: Currently SteamMultiplayerPeer routes all packets through default channel # Channel selection is available at the SteamPacketPeer level for advanced usage ``` -------------------------------- ### Set SteamMultiplayerPeer Debug Level Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/types.md Example of setting the debug level for SteamMultiplayerPeer. Use constants from the DebugLevel enum. ```gdscript var peer = SteamMultiplayerPeer.new() peer.set_debug_level(SteamMultiplayerPeer.DEBUG_LEVEL_PEER) ``` -------------------------------- ### Recovering from ERR_CANT_CREATE (Host) Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md When ERR_CANT_CREATE occurs during host creation, it may indicate Steam initialization issues. This example demonstrates a fallback strategy by retrying after a delay. ```gdscript var error = peer.create_host(0) if error == ERR_CANT_CREATE: print("Failed to create host - Steam may not be initialized") # Fallback to local multiplayer or retry after delay await get_tree().create_timer(2.0).timeout error = peer.create_host(0) ``` -------------------------------- ### Host Chat Server on Different Virtual Port Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/configuration.md Example of hosting a separate chat or test server on a different virtual port (5) to ensure independence from the main game. ```gdscript var chat_peer = SteamMultiplayerPeer.new() chat_peer.create_host(5) # Different virtual port ``` -------------------------------- ### Handle SteamPacketPeer Connection State Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/types.md Example of checking the connection state of a peer using a match statement. Use constants from the PeerState enum. ```gdscript var peer = steam_multiplayer_peer.get_peer(2) var state = peer.get_state() match state: SteamPacketPeer.STATE_CONNECTING: print("Still connecting...") SteamPacketPeer.STATE_CONNECTED: print("Ready to send packets") SteamPacketPeer.STATE_PROBLEM_DETECTED_LOCALLY: print("Connection error") ``` -------------------------------- ### Get Nagle Algorithm Setting Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Retrieves the current status of the Nagle algorithm. This helps in understanding the current latency and packet transmission behavior. ```gdscript func get_no_nagle() -> bool ``` -------------------------------- ### Get Connection Status Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Returns the current connection state of the peer. Use this to check if the connection is disconnected, connecting, or fully connected. ```gdscript func get_connection_status() -> int ``` -------------------------------- ### Get No-Delay Setting Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Returns the current state of the no-delay setting, indicating whether packets are delivered immediately or subject to TCP buffering. ```gdscript func get_no_delay() -> bool ``` -------------------------------- ### RPC Communication Example Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/README.md Define and call Remote Procedure Calls (RPCs) to execute functions on remote peers. Use @rpc decorator for server-side or any-peer execution. ```gdscript @rpc("any_peer") func my_function(param): print(param) my_function.rpc(42) # Sent to all peers ``` -------------------------------- ### Send Raw Data with Custom Flags Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-packet-peer.md Sends raw data to this peer on a specific channel with custom flags. Use this for fine-grained control over packet transmission, including reliability and delay settings. Example demonstrates sending reliable data. ```gdscript func send(channel: int, data: PackedByteArray, flags: int) -> Error ``` ```gdscript var packet_peer = steam_multiplayer_peer.get_peer(2) var data = PackedByteArray([1, 2, 3, 4]) var flags = k_nSteamNetworkingSend_Reliable packet_peer.send(0, data, flags) ``` -------------------------------- ### Get Packet Channel Index Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Retrieves the channel index for the current incoming packet. ```gdscript func get_packet_channel() -> int ``` -------------------------------- ### Get Available Packet Count Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-packet-peer.md Returns the number of packets waiting to be read from this peer. ```gdscript func get_available_packet_count() -> int ``` -------------------------------- ### Get Packet Transfer Mode Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Returns the transfer mode (reliable or unreliable) of the current incoming packet. ```gdscript func get_packet_mode() -> int ``` -------------------------------- ### Get Packet Sender Peer ID Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Retrieves the peer ID of the sender for the current incoming packet. ```gdscript func get_packet_peer() -> int ``` -------------------------------- ### Initialize as Host (Server) Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Initializes the SteamMultiplayerPeer as a server to accept incoming connections. This must be called before any peers can connect. Use a virtual port to manage different network channels. ```gdscript var peer = SteamMultiplayerPeer.new() var error = peer.create_host(0) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) else: print("Failed to create host: ", error) ``` -------------------------------- ### create_host Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Initializes this peer as a server (host) that accepts incoming connections. This method must be called before any peer connections can occur. ```APIDOC ## create_host ### Description Initializes this peer as a server (host) that accepts incoming connections. Must be called before any peer connections can occur. ### Method func create_host(virtual_port: int = 0) -> Error ### Parameters #### Path Parameters - **virtual_port** (int) - Optional - Virtual port number for multiplayer connections. Must be 0-65535. Multiple virtual ports allow separate multiplayer channels. ### Return type Error ### Returns - `OK` if host created successfully - `ERR_ALREADY_IN_USE` if already connected or hosting - `ERR_CANT_CREATE` if listen socket or poll group creation fails ### Example ```gdscript var peer = SteamMultiplayerPeer.new() var error = peer.create_host(0) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) else: print("Failed to create host: ", error) ``` ``` -------------------------------- ### Get Debug Level Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Retrieves the current debug logging level. This allows you to check the verbosity of diagnostic output being generated by the peer. ```gdscript func get_debug_level() -> int ``` -------------------------------- ### create_client Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Initializes this peer as a client connecting to a specific Steam user acting as the host. After calling this method, the connection status will be CONNECTION_CONNECTING. ```APIDOC ## create_client ### Description Initializes this peer as a client connecting to a specific Steam user acting as the host. ### Method func create_client(steam_id: int, virtual_port: int = 0) -> Error ### Parameters #### Path Parameters - **steam_id** (int) - Required - 64-bit Steam ID of the host to connect to - **virtual_port** (int) - Optional - Virtual port number matching the host's listening port ### Return type Error ### Returns - `OK` if client created and connection attempt initiated - `ERR_ALREADY_IN_USE` if already connected - `ERR_CANT_CREATE` if socket creation fails ### Behavior After calling this method, the connection status will be `CONNECTION_CONNECTING`. Listen for the `peer_connected` signal to know when the host is ready, or check `get_connection_status()`. ### Example ```gdscript var peer = SteamMultiplayerPeer.new() var host_steam_id = 76561198000000000 # Example Steam ID var error = peer.create_client(host_steam_id, 0) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) peer.peer_connected.connect(_on_peer_connected) ``` ``` -------------------------------- ### Accessing and Sending Data to a Connected Peer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-packet-peer.md Get a reference to a specific connected peer and send data directly to it if the connection is established. ```gdscript var peer = steam_multiplayer_peer.get_peer(2) if peer: # Access peer info var steam_id = peer.get_steam_id() var state = peer.get_state() # Send data directly if state == SteamPacketPeer.STATE_CONNECTED: var data = PackedByteArray([1, 2, 3]) peer.put_packet(data) ``` -------------------------------- ### Basic Client Connection with SteamMultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md Use this pattern to connect as a client to a specific host using their Steam ID. It initializes SteamMultiplayerPeer, creates the client connection, and sets up event listeners for connection status. ```gdscript extends Node var multiplayer_peer: SteamMultiplayerPeer var host_steam_id: int func connect_to_host(host_id: int): multiplayer_peer = SteamMultiplayerPeer.new() host_steam_id = host_id # Configure networking multiplayer_peer.set_no_nagle(true) multiplayer_peer.set_server_relay(true) # Create client var error = multiplayer_peer.create_client(host_steam_id, 0) if error != OK: print("Failed to create client: ", error) return # Connect to Godot's multiplayer system get_tree().multiplayer.set_multiplayer_peer(multiplayer_peer) # Listen for connection events multiplayer_peer.connected_to_server.connect(_on_connected_to_server) multiplayer_peer.connection_failed.connect(_on_connection_failed) multiplayer_peer.peer_connected.connect(_on_peer_connected) print("Connecting to host...") func _on_connected_to_server(): print("Connected to host") func _on_connection_failed(): print("Connection failed") func _on_peer_connected(peer_id: int): print("Another client connected: ", peer_id) ``` -------------------------------- ### Get Maximum Packet Size Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-packet-peer.md Returns the maximum size for a single packet, which is 524288 bytes (512 KB) for Steam Networking Sockets. ```gdscript func get_max_packet_size() -> int ``` -------------------------------- ### Initialize as Client Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Initializes the SteamMultiplayerPeer as a client to connect to a specific host identified by their Steam ID. The connection status will be 'CONNECTING' after this call. Listen for the 'peer_connected' signal for confirmation. ```gdscript var peer = SteamMultiplayerPeer.new() var host_steam_id = 76561198000000000 # Example Steam ID var error = peer.create_client(host_steam_id, 0) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) peer.peer_connected.connect(_on_peer_connected) ``` -------------------------------- ### Get Steam ID of Connected Peer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-packet-peer.md Retrieves the 64-bit Steam ID of the peer on the other end of the connection. Useful for identifying connected users. ```gdscript var packet_peer = steam_multiplayer_peer.get_peer(2) var steam_id = packet_peer.get_steam_id() print("Connected to Steam user: ", steam_id) ``` -------------------------------- ### Initialize and Configure SteamMultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/configuration.md Use this function to set up a SteamMultiplayerPeer, configuring network tuning, debugging, and connection parameters before establishing a host or client connection. It also sets the global multiplayer peer and transfer mode. ```gdscript func setup_multiplayer_peer(is_host: bool, host_id: int = 0) -> SteamMultiplayerPeer: var peer = SteamMultiplayerPeer.new() # Configure network tuning (before connecting) peer.set_no_nagle(true) # Reduce latency peer.set_no_delay(false) # Default buffering is fine peer.set_server_relay(true) # Better NAT traversal # Configure debugging peer.set_debug_level(SteamMultiplayerPeer.DEBUG_LEVEL_PEER) # Establish connection var error: int if is_host: error = peer.create_host(0) # Virtual port 0 else: error = peer.create_client(host_id, 0) if error != OK: printerr("Connection failed: ", error) return null # Set up multiplayer system get_tree().multiplayer.set_multiplayer_peer(peer) get_tree().multiplayer.set_transfer_mode(MultiplayerPeer.TRANSFER_MODE_UNRELIABLE) # Start refusing new connections after game starts # peer.set_refuse_new_connections(true) # Uncomment when game is live return peer ``` -------------------------------- ### Get Server Relay Setting Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Checks if the server relay mode is currently active. This is important for diagnosing connectivity issues in restricted network environments. ```gdscript func get_server_relay() -> bool ``` -------------------------------- ### Connect to a Host with SteamMultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/README.md Use this snippet to connect to an existing game host. Replace 'host_steam_id' with the actual Steam ID of the host. ```gdscript var peer = SteamMultiplayerPeer.new() peer.set_server_relay(true) var error = peer.create_client(host_steam_id, 0) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) peer.connected_to_server.connect(func(): print("Connected!")) ``` -------------------------------- ### SteamMultiplayerPeer() Constructor Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Creates a new SteamMultiplayerPeer instance. This instance must be initialized with one of the connection methods (e.g., create_host, create_client) before it can be used for networking. ```APIDOC ## SteamMultiplayerPeer() ### Description Creates a new SteamMultiplayerPeer instance. Must be initialized with one of the connection methods before use. ### Returns SteamMultiplayerPeer instance ### Example ```gdscript var peer = SteamMultiplayerPeer.new() ``` ``` -------------------------------- ### Get Internal Godot Peer ID Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-packet-peer.md Returns the internal Godot peer ID assigned to this connection. This ID is used by SteamMultiplayerPeer to manage peers. ```gdscript var packet_peer = steam_multiplayer_peer.get_peer(2) var peer_id = packet_peer.get_peer_id() print("Peer ID: ", peer_id) ``` -------------------------------- ### Direct Peer-to-Peer Communication with SteamMultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md This snippet demonstrates how to initialize SteamMultiplayerPeer as a host, process incoming packets, and send messages directly to specific peers or broadcast to all. ```gdscript extends Node var multiplayer_peer: SteamMultiplayerPeer func _ready(): multiplayer_peer = SteamMultiplayerPeer.new() multiplayer_peer.create_host() get_tree().multiplayer.set_multiplayer_peer(multiplayer_peer) set_process(true) func _process(delta): # Check for incoming packets while multiplayer_peer.get_available_packet_count() > 0: var sender_id = multiplayer_peer.get_packet_peer() var mode = multiplayer_peer.get_packet_mode() var error = multiplayer_peer.get_packet(var packet_buffer) if error == OK: handle_packet(sender_id, packet_buffer, mode) func handle_packet(peer_id: int, data: PackedByteArray, mode: int): var message = data.get_string_from_ascii() print("From peer %d: %s" % [peer_id, message]) func send_to_peer(peer_id: int, message: String): multiplayer_peer.set_target_peer(peer_id) var data = message.to_ascii_buffer() var error = multiplayer_peer.put_packet(data) if error != OK: print("Failed to send: ", error) func broadcast_message(message: String): multiplayer_peer.set_target_peer(0) # Broadcast var data = message.to_ascii_buffer() var error = multiplayer_peer.put_packet(data) if error != OK: print("Failed to broadcast: ", error) ``` -------------------------------- ### SteamMultiplayerPeer Configuration Methods Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/README.md These methods allow for fine-tuning the network behavior of the SteamMultiplayerPeer, including disabling the Nagle algorithm, enabling immediate transmission, and configuring relay behavior. ```APIDOC ## SteamMultiplayerPeer Configuration ### `set_no_nagle(bool)` / `get_no_nagle()` #### Description Enables or disables the Nagle algorithm for packet transmission. #### Method `set_no_nagle` / `get_no_nagle` #### Parameters - **bool** (bool) - `true` to disable Nagle, `false` to enable. ### `set_no_delay(bool)` / `get_no_delay()` #### Description Enables or disables immediate transmission of packets, bypassing buffering. #### Method `set_no_delay` / `get_no_delay` #### Parameters - **bool** (bool) - `true` to enable immediate transmission, `false` to disable. ### `set_server_relay(bool)` / `get_server_relay()` #### Description Enables or disables the server relay fallback mechanism. #### Method `set_server_relay` / `get_server_relay` #### Parameters - **bool** (bool) - `true` to enable server relay, `false` to disable. ### `set_debug_level(level)` / `get_debug_level()` #### Description Controls the verbosity of debug output. #### Method `set_debug_level` / `get_debug_level` #### Parameters - **level** (DebugLevel enum) - The desired debug level (`DEBUG_LEVEL_NONE`, `DEBUG_LEVEL_PEER`, `DEBUG_LEVEL_STEAM`). ``` -------------------------------- ### Define PeerIDPacket Struct Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/types.md Defines the internal structure for exchanging peer IDs during connection setup. This struct is used in the handshake process between host and client. ```cpp struct PeerIDPacket { uint32_t peer_id = 0; }; ``` -------------------------------- ### host_with_lobby Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Initializes this peer as a host and automatically connects to all current Steam lobby members. The calling Steam user must be both a member and the owner of the specified lobby. ```APIDOC ## host_with_lobby ### Description Initializes this peer as a host and automatically connects to all current Steam lobby members. ### Method `host_with_lobby(lobby_id: int) -> Error` ### Parameters #### Path Parameters - **lobby_id** (int) - Required - 64-bit Steam lobby ID from SteamMatchmaking ### Response #### Return type `Error` #### Returns - `OK` if host created and lobby connections established - `ERR_ALREADY_IN_USE` if already connected - `ERR_CANT_CREATE` if not a member of the lobby or not the lobby owner ### Example ```gdscript var peer = SteamMultiplayerPeer.new() var lobby_id = 109775240910345216 # From lobby creation var error = peer.host_with_lobby(lobby_id) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) ``` ``` -------------------------------- ### Retrieve SteamPacketPeer for a Peer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Gets the SteamPacketPeer object associated with a specific internal peer ID. This allows for low-level packet handling for that particular peer connection. ```gdscript var packet_peer = peer.get_peer(2) if packet_peer: var steam_id = packet_peer.get_steam_id() print("Peer 2 Steam ID: ", steam_id) ``` -------------------------------- ### RPC-Based Network Communication with SteamMultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md Demonstrates how to use Godot's RPC system for reliable and unreliable network communication between peers. This includes sending position updates and spawning effects, with server-side logic for relaying messages. ```gdscript extends Node var multiplayer_peer: SteamMultiplayerPeer @rpc("any_peer", "unreliable") func update_position(new_pos: Vector3): if multiplayer.is_server(): # Server: relay to all other clients rpc("update_position", new_pos) else: # Client: update local position = new_pos @rpc("authority") func spawn_effect(position: Vector3): # Only the server can trigger this on clients var effect = preload("res://effect.tscn").instantiate() effect.global_position = position add_child(effect) func _process(delta): # Handle input var move = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") if move.length() > 0: position += move * 100 * delta # Send update to all clients update_position.rpc(position) # Server setup func _ready(): multiplayer_peer = SteamMultiplayerPeer.new() if is_server_host(): multiplayer_peer.create_host() else: multiplayer_peer.create_client(get_host_steam_id()) get_tree().multiplayer.set_multiplayer_peer(multiplayer_peer) ``` -------------------------------- ### connect_to_lobby Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Initializes this peer as a client and automatically connects to the Steam lobby host and other members. Automatically connects to the lobby owner (as primary host) and to all other lobby members. Lobby membership is tracked continuously; the `peer_connected` and `peer_disconnected` signals fire as members join/leave. ```APIDOC ## connect_to_lobby ### Description Initializes this peer as a client and automatically connects to the Steam lobby host and other members. ### Method `connect_to_lobby(lobby_id: int) -> Error` ### Parameters #### Path Parameters - **lobby_id** (int) - Required - 64-bit Steam lobby ID from SteamMatchmaking ### Response #### Return type `Error` #### Returns - `OK` if client created and connections established - `ERR_ALREADY_IN_USE` if already connected - `ERR_CANT_CREATE` if not a member of the lobby ### Example ```gdscript var peer = SteamMultiplayerPeer.new() var lobby_id = 109775240910345216 var error = peer.connect_to_lobby(lobby_id) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) ``` ``` -------------------------------- ### Get Unique Peer ID Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Retrieves the internal peer ID assigned to this instance. The server is always ID 1, while clients receive randomly generated IDs. ```gdscript func get_unique_id() -> int ``` -------------------------------- ### Incoming Peer Connection Handling Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/architecture.md Details the sequence of events when a remote peer initiates a connection. Covers Steam callbacks, connection acceptance, and the transition to a connected state. ```text 1. Remote peer initiates ConnectP2P() to our listen socket 2. Steam fires SteamNetConnectionStatusChangedCallback_t ├─ Status changes to STATE_CONNECTING 3. network_connection_status_changed() callback fires ├─ Check if from our listen socket ├─ Check if we're refusing connections ├─ SteamNetworkingSockets::AcceptConnection() ├─ SteamNetworkingSockets::SetConnectionPollGroup() ├─ _add_pending_peer() │ └─ Create SteamPacketPeer │ └─ Add to steam_connections map │ └─ Set state = STATE_CONNECTING 4. Steam fires STATE_CONNECTED callback ├─ ping(our_peer_id) → Send to remote peer 5. Remote peer sends ping with their peer ID ├─ process_ping() extracts their ID ├─ Call upgrade_peer() │ ├─ Move from steam_connections to peers │ ├─ Emit peer_connected signal ├─ Both sides ready to exchange game data ``` -------------------------------- ### Create SteamMultiplayerPeer Instance Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Instantiates a new SteamMultiplayerPeer object. This object must be initialized with a connection method (e.g., create_host, create_client) before it can be used for networking. ```gdscript var peer = SteamMultiplayerPeer.new() ``` -------------------------------- ### Get Packet from Queue Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-packet-peer.md Retrieves the next packet from this peer's queue. Dequeues the oldest packet and populates the buffer. Returns OK if successful, ERR_UNAVAILABLE if no packets are available. ```gdscript func get_packet(r_buffer: PackedByteArray) -> Error ``` -------------------------------- ### Properties Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Configurable properties for the MultiplayerPeer. ```APIDOC ## Properties | Name | Type | Default | Getter | Setter | Description | |---|---|---|---|---|---| | no_nagle | bool | false | get_no_nagle() | set_no_nagle() | Disable Nagle algorithm for lower latency | | no_delay | bool | false | get_no_delay() | set_no_delay() | Enable immediate packet delivery | | server_relay | bool | false | get_server_relay() | set_server_relay() | Enable server relay for NAT traversal | | debug_level | int | 0 | get_debug_level() | set_debug_level() | Debugging verbosity level | ``` -------------------------------- ### Initialize Steam Multiplayer Peer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md Handles the creation of a host or client Steam MultiplayerPeer and checks for initialization errors. Ensure the peer is successfully created before setting it to the game tree. ```gdscript func setup_multiplayer(is_host: bool, host_steam_id: int = 0): var peer = SteamMultiplayerPeer.new() var error: int if is_host: error = peer.create_host(0) else: error = peer.create_client(host_steam_id, 0) if error != OK: printerr("Failed to create multiplayer: ", error) return false get_tree().multiplayer.set_multiplayer_peer(peer) return true ``` -------------------------------- ### Host a Steam Lobby and Connect Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md Use this function to host a new public Steam lobby and set up the multiplayer peer to act as the server. Ensure SteamMatchmaking is used to create the lobby before calling this function. ```gdscript extends Node var multiplayer_peer: SteamMultiplayerPeer var current_lobby_id: int func host_lobby(): # Create a Steam lobby first (using GodotSteam) var lobby = SteamMatchmaking().CreateLobby(k_ELobbyTypePublic, 4) current_lobby_id = lobby.ConvertToUint64() # Set up multiplayer peer with lobby multiplayer_peer = SteamMultiplayerPeer.new() multiplayer_peer.set_server_relay(true) var error = multiplayer_peer.host_with_lobby(current_lobby_id) if error != OK: print("Failed to host lobby: ", error) return get_tree().multiplayer.set_multiplayer_peer(multiplayer_peer) multiplayer_peer.peer_connected.connect(_on_peer_connected) print("Hosting lobby: ", current_lobby_id) ``` -------------------------------- ### SteamPacketPeer State Machine Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/architecture.md Illustrates the state transitions for a SteamPacketPeer connection, from initial connection attempts to a dead state. Shows alternative paths for remote closures or local problems. ```text STATE_NONE ↓ (connection created) STATE_CONNECTING ↓ (route established) STATE_FINDING_ROUTE ↓ (connected) STATE_CONNECTED ← can send/receive packets ↓ (disconnect initiated) STATE_FIN_WAIT ↓ (both sides acknowledged) STATE_LINGER ↓ (cleanup complete) STATE_DEAD Alternative paths: STATE_CONNECTING → STATE_CLOSED_BY_PEER (remote closed) STATE_CONNECTING → STATE_PROBLEM_DETECTED_LOCALLY (error) ``` -------------------------------- ### Send Peer ID Handshake Packet Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-packet-peer.md Sends a peer ID handshake packet used internally to exchange peer IDs during connection setup. Returns OK if sent successfully, ERR_UNAVAILABLE if peer is not connected. ```gdscript func ping(peer_id: int) -> Error ``` -------------------------------- ### Host Lobby Only If Owner Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md Ensure the user is the owner of the lobby before attempting to host. If not the owner, the user should join as a client instead. This avoids `ERR_CANT_CREATE` errors. ```gdscript # Only the owner can host if SteamMatchmaking().GetLobbyOwner(lobby) == SteamUser().GetSteamID(): var error = peer.host_with_lobby(lobby.ConvertToUint64()) else: # Join as client instead var error = peer.connect_to_lobby(lobby.ConvertToUint64()) ``` -------------------------------- ### Get Steam Packet Flags Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/architecture.md Determines the appropriate Steam networking send flags based on the current transfer mode and optional flags like NoDelay and NoNagle. The function combines base flags with optional flags using bitwise OR. ```cpp int _get_steam_packet_flags() { int32_t flags = (k_nSteamNetworkingSend_NoNagle * no_nagle) | (k_nSteamNetworkingSend_NoDelay * no_delay); switch (get_transfer_mode()) { case TRANSFER_MODE_RELIABLE: return k_nSteamNetworkingSend_Reliable | flags; case TRANSFER_MODE_UNRELIABLE: return k_nSteamNetworkingSend_Unreliable | flags; case TRANSFER_MODE_UNRELIABLE_ORDERED: return k_nSteamNetworkingSend_Reliable | flags; // Fallback } } ``` -------------------------------- ### Class Hierarchy Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/architecture.md Illustrates the inheritance relationship between Godot's core networking classes and the custom Steam-based implementations. ```text MultiplayerPeer (Godot core) ↑ └── SteamMultiplayerPeer PacketPeer (Godot core) ↑ └── SteamPacketPeer ``` -------------------------------- ### Configure max_channels in project.godot Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/configuration.md Set the maximum number of communication channels for SteamMultiplayerPeer directly in the project.godot configuration file. ```ini [steam/multiplayer_peer] max_channels = 4 ``` -------------------------------- ### SteamMultiplayerPeer Methods Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/README.md This section details the core methods available in the SteamMultiplayerPeer class for managing multiplayer sessions, including hosting, connecting, and interacting with Steam Lobbies. ```APIDOC ## SteamMultiplayerPeer Class Methods ### `create_host(virtual_port)` #### Description Starts the multiplayer peer as a host, allowing other players to connect. #### Method `create_host` #### Parameters - **virtual_port** (int) - The virtual port to use for networking. ### `create_client(host_steam_id, virtual_port)` #### Description Connects the multiplayer peer to a host server using the provided Steam ID. #### Method `create_client` #### Parameters - **host_steam_id** (uint64) - The Steam ID of the host to connect to. - **virtual_port** (int) - The virtual port used by the host. ### `host_with_lobby(lobby_id)` #### Description Hosts a game and automatically manages connections for members of a specified Steam Lobby. #### Method `host_with_lobby` #### Parameters - **lobby_id** (uint64) - The ID of the Steam Lobby to host the game within. ### `connect_to_lobby(lobby_id)` #### Description Connects to a game hosted within a specified Steam Lobby as a client. #### Method `connect_to_lobby` #### Parameters - **lobby_id** (uint64) - The ID of the Steam Lobby to connect to. ### `add_peer(steam_id, virtual_port)` #### Description Manually adds a connection to an additional peer using their Steam ID and a virtual port. #### Method `add_peer` #### Parameters - **steam_id** (uint64) - The Steam ID of the peer to add. - **virtual_port** (int) - The virtual port for the peer connection. ### `get_peer(peer_id)` #### Description Retrieves the low-level `SteamPacketPeer` object for a specific peer. #### Method `get_peer` #### Parameters - **peer_id** (int) - The ID of the peer to retrieve. #### Returns - `SteamPacketPeer` - The low-level peer object. ### `set_target_peer(id)` #### Description Sets the destination for outgoing packets. #### Method `set_target_peer` #### Parameters - **id** (int) - The target peer ID. Use 0 for broadcast, a positive ID for a specific peer, or a negative ID to exclude a peer. ### `put_packet(data)` #### Description Sends a packet of data to the target peer. #### Method `put_packet` #### Parameters - **data** (bytes) - The data to send. ### `get_packet()` #### Description Receives a packet of data. #### Method `get_packet` #### Returns - (bytes) - The received packet data. ### `close()` #### Description Disconnects from the network and cleans up resources. #### Method `close` ``` -------------------------------- ### Set Up Steam Multiplayer Connection Signals Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md Connects signals for monitoring peer connections, disconnections, and connection status changes. Implement handlers for these signals to manage game state and user feedback. ```gdscript func _setup_multiplayer_signals(peer: SteamMultiplayerPeer): peer.peer_connected.connect(_on_peer_connected) peer.peer_disconnected.connect(_on_peer_disconnected) peer.connected_to_server.connect(_on_connected_to_server) peer.connection_failed.connect(_on_connection_failed) peer.server_disconnected.connect(_on_server_disconnected) func _on_peer_connected(peer_id: int): print("Peer connected: ", peer_id) func _on_peer_disconnected(peer_id: int): print("Peer disconnected: ", peer_id) # Clean up peer-specific game state func _on_connection_failed(): print("Connection failed") # Show error to user, offer retry ``` -------------------------------- ### Verify Lobby Membership Before Hosting Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md Before calling `host_with_lobby`, verify that the user is a member of the specified lobby. This prevents `ERR_CANT_CREATE` errors due to invalid membership. ```gdscript var lobby = SteamMatchmaking().GetLobbyByIndex(0) if SteamMatchmaking().GetLobbyOwner(lobby) == SteamUser().GetSteamID(): var error = peer.host_with_lobby(lobby.ConvertToUint64()) # Now safe to proceed ``` -------------------------------- ### Host Steam Lobby with MultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Initializes the peer as a host and connects to all current Steam lobby members. Requires the calling Steam user to be a member and owner of the lobby. ```gdscript func host_with_lobby(lobby_id: int) -> Error: # Initializes this peer as a host and automatically connects to all current Steam lobby members. pass ``` ```gdscript var peer = SteamMultiplayerPeer.new() var lobby_id = 109775240910345216 # From lobby creation var error = peer.host_with_lobby(lobby_id) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) ``` -------------------------------- ### Recovering from ERR_UNCONFIGURED Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md Demonstrates how to handle the ERR_UNCONFIGURED error when attempting to send a packet before a connection is established. It suggests waiting for the 'peer_connected' signal. ```gdscript var error = peer.put_packet(data) if error == ERR_UNCONFIGURED: print("Not connected. Connection status: ", peer.get_connection_status()) # Don't send; wait for peer_connected signal await peer.peer_connected error = peer.put_packet(data) ``` -------------------------------- ### Configure max_channels via ProjectSettings API Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/configuration.md Dynamically set the maximum number of communication channels for SteamMultiplayerPeer using the ProjectSettings API in GDScript. ```gdscript ProjectSettings.set_setting("steam/multiplayer_peer/max_channels", 4) ``` -------------------------------- ### Enable TCP_NODELAY for Ultra-Low Latency Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/configuration.md Combine `set_no_nagle(true)` with `set_no_delay(true)` to bypass all transmission buffering for the lowest possible latency. This may increase packet overhead and bandwidth usage. ```gdscript # Ultra-low-latency competitive mode peer.set_no_nagle(true) peer.set_no_delay(true) ``` -------------------------------- ### Checking for Successful Operation Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md Use this pattern to verify if an operation like creating a host completed successfully. It checks the returned error code against OK. ```gdscript var error = peer.create_host(0) if error == OK: print("Host created successfully") ``` -------------------------------- ### Accessing Direct SteamPacketPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md Demonstrates how to obtain and interact with the low-level SteamPacketPeer object for a specific peer. Use this when you need to access individual peer states or send custom data directly. ```gdscript extends Node var multiplayer_peer: SteamMultiplayerPeer func _ready(): multiplayer_peer = SteamMultiplayerPeer.new() multiplayer_peer.create_host() multiplayer_peer.peer_connected.connect(_on_peer_connected) func _on_peer_connected(peer_id: int): # Access the low-level peer object var packet_peer = multiplayer_peer.get_peer(peer_id) if packet_peer: print("Peer %d is: %s" % [peer_id, packet_peer.get_steam_id()]) print("State: %d" % packet_peer.get_state()) func send_custom_packet(peer_id: int, data: PackedByteArray): var packet_peer = multiplayer_peer.get_peer(peer_id) if packet_peer and packet_peer.get_state() == SteamPacketPeer.STATE_CONNECTED: var error = packet_peer.put_packet(data) if error != OK: print("Send failed: ", error) func check_peer_state(peer_id: int): var packet_peer = multiplayer_peer.get_peer(peer_id) if packet_peer: var state_names = { 0: "NONE", 1: "CONNECTING", 2: "FINDING_ROUTE", 3: "CONNECTED", 4: "CLOSED_BY_PEER", 5: "PROBLEM_DETECTED_LOCALLY", } var state = packet_peer.get_state() print("Peer %d state: %s (%d)" % [peer_id, state_names.get(state, "UNKNOWN"), state]) ``` -------------------------------- ### Connect to Steam Lobby with MultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/steam-multiplayer-peer.md Initializes the peer as a client and connects to the Steam lobby host and other members. Automatically connects to the lobby owner and all other members, firing signals for joins/leaves. ```gdscript func connect_to_lobby(lobby_id: int) -> Error: # Initializes this peer as a client and automatically connects to the Steam lobby host and other members. pass ``` ```gdscript var peer = SteamMultiplayerPeer.new() var lobby_id = 109775240910345216 var error = peer.connect_to_lobby(lobby_id) if error == OK: get_tree().multiplayer.set_multiplayer_peer(peer) ``` -------------------------------- ### Connection Status Monitoring with SteamMultiplayerPeer Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md Shows how to monitor the connection status of SteamMultiplayerPeer using signals and periodic checks. This includes handling peer connections/disconnections and checking the overall connection state. ```gdscript extends Node var multiplayer_peer: SteamMultiplayerPeer func _ready(): multiplayer_peer = SteamMultiplayerPeer.new() # Set up callbacks multiplayer_peer.peer_connected.connect(_on_peer_connected) multiplayer_peer.peer_disconnected.connect(_on_peer_disconnected) multiplayer_peer.connected_to_server.connect(_on_connected) multiplayer_peer.connection_failed.connect(_on_connection_failed) multiplayer_peer.server_disconnected.connect(_on_server_disconnected) # Monitor status periodically var timer = Timer.new() add_child(timer) timer.timeout.connect(_check_status) timer.start(1.0) func _on_peer_connected(peer_id: int): print("Peer %d connected" % peer_id) update_ui_peers() func _on_peer_disconnected(peer_id: int): print("Peer %d disconnected" % peer_id) update_ui_peers() func _on_connected(): print("Connected to server") multiplayer_peer.set_debug_level(SteamMultiplayerPeer.DEBUG_LEVEL_PEER) func _on_connection_failed(): print("Connection failed") func _on_server_disconnected(): print("Server disconnected - host left") # Return to lobby or main menu func _check_status(): var status = multiplayer_peer.get_connection_status() var status_str = { 0: "DISCONNECTED", 1: "CONNECTING", 2: "CONNECTED" }[status] print("Status: %s, Peers: %d" % [status_str, get_tree().get_nodes_in_group("player").size()]) func update_ui_peers(): var peer_count = 0 for peer_id in get_tree().get_connected_peers(): if peer_id > 1: # Skip server peer_count += 1 print("Total players: ", peer_count) ``` -------------------------------- ### Enable Peer-Level Debug Logging Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/errors.md Enable peer-specific event logging to diagnose connection issues. Output is directed to Godot's console. ```gdscript peer.set_debug_level(SteamMultiplayerPeer.DEBUG_LEVEL_PEER) # Peer events ``` -------------------------------- ### Handle Peer Connection Events Source: https://github.com/godotsteam/multiplayerpeer/blob/main/_autodocs/usage-patterns.md These functions are callbacks for when a new peer connects or the client successfully connects to the server. They are essential for managing game state and player presence. ```gdscript func _on_peer_connected(peer_id: int): if multiplayer_peer.is_server(): print("New player: ", peer_id) else: print("Another player connected: ", peer_id) func _on_connected_to_server(): print("Successfully joined the game") ```