This video covers networking in the Godot game engine. First, we start off creating a simple UDP socket server and a client. We then illustrate the use of HTTPClient to make a REST web service request. We then create a simple ENet based client and server in Godot. Finally, we create a simple lobby and networked game using GDScript keywords master, slave, sync, and remote.
The Video
Code Samples
SimpleClient.gd
extends SceneTree func _init(): var socket = PacketPeerUDP.new() socket.set_dest_address("127.0.0.1",4242) socket.put_packet("quit".to_ascii()) print("Exiting application") self.quit()
SimpleServer.gd
extends SceneTree func _init(): var done = false var socket = PacketPeerUDP.new() if(socket.listen(4242,"127.0.0.1") != OK): print("An error occurred listening on port 4242") done = true; else: print("Listening on port 4242 on localhost") while(done != true): if(socket.get_available_packet_count() > 0): var data = socket.get_packet().get_string_from_ascii() if(data == "quit"): done = true else: print("Data received: " + data) socket.close() print("Exiting application") self.quit()
HTTPRequest.gd
extends Button func _ready(): $HTTPRequest.connect("request_completed",self,"_on_HTTPRequest_request_completed") func _on_Button_pressed(): $HTTPRequest.request("https://jsonplaceholder.typicode.com/todos/1",PoolStringArray([]),false) func _on_HTTPRequest_request_completed( result, response_code, headers, body ): if(response_code == 200): get_parent().get_node("Label").text = body.get_string_from_utf8()
Client.gd
extends Node2D func _ready(): var network = NetworkedMultiplayerENet.new() network.create_client("127.0.0.1", 4242) get_tree().set_network_peer(network) network.connect("connection_failed",self,"_on_connection_failed") get_tree().multiplayer.connect("network_peer_packet",self,"_on_packet_received") func _on_connection_failed(error): $labelStatus.text = "Error connecting to server " + error func _on_packet_received(id,packet): $labelServerData.text = packet.get_string_from_ascii() func _on_buttonConnect_pressed(): var network = NetworkedMultiplayerENet.new() network.create_client("127.0.0.1", 4242) get_tree().set_network_peer(network) func _on_buttonDisconnect_pressed(): get_tree().set_network_peer(null)
Server.gd
extends Label func _ready(): var network = NetworkedMultiplayerENet.new() network.create_server(4242, 2) get_tree().set_network_peer(network) network.connect("peer_connected",self,"_peer_connected") network.connect("peer_disconnected",self,"_peer_disconnected") func _peer_connected(id): text = text + "\nUser " + str(id) + " connected" get_parent().get_node("labelUserCount").text = "Total Users:" + str(get_tree().get_network_connected_peers().size()) func _peer_disconnected(id): text = text + "\nUser " + str(id) + " disconnected" get_parent().get_node("labelUserCount").text = "Total Users:" + str(get_tree().get_network_connected_peers().size()) extends Button func _on_buttonSendData_pressed(): print("Sending data to client") var textToSend = get_parent().get_node("textToSend").text get_tree().multiplayer.send_bytes(textToSend.to_ascii())
Lobby.gd
extends Node2D func _ready(): get_tree().connect("network_peer_connected", self, "_player_connected") func _player_connected(id): print("Player connected to server!") #Game on! globals.otherPlayerId = id var game = preload("res://Game.tscn").instance() get_tree().get_root().add_child(game) hide() func _on_buttonHost_pressed(): print("Hosting network") var host = NetworkedMultiplayerENet.new() var res = host.create_server(4242,2) if res != OK: print("Error creating server") return $buttonJoin.hide() $buttonHost.disabled = true get_tree().set_network_peer(host) func _on_buttonJoin_pressed(): print("Joining network") var host = NetworkedMultiplayerENet.new() host.create_client("127.0.0.1",4242) get_tree().set_network_peer(host) $buttonHost.hide() $buttonJoin.disabled = true
Game.gd
extends Node2D func _ready(): #First create ourself var thisPlayer = preload("res://Player.tscn").instance() thisPlayer.set_name(str(get_tree().get_network_unique_id())) thisPlayer.set_network_master(get_tree().get_network_unique_id()) add_child(thisPlayer) #Now create the other player var otherPlayer = preload("res://Player.tscn").instance() otherPlayer.set_name(str(globals.otherPlayerId)) otherPlayer.set_network_master(globals.otherPlayerId) add_child(otherPlayer)
Player.gd
extends Node2D slave func setPosition(pos): position = pos master func shutItDown(): #Send a shutdown command to all connected clients, including this one rpc("shutDown") sync func shutDown(): get_tree().quit() func _process(delta): var moveByX = 0 var moveByY = 0 if(is_network_master()): if Input.is_key_pressed(KEY_LEFT): moveByX = -5 if Input.is_key_pressed(KEY_RIGHT): moveByX = 5 if Input.is_key_pressed(KEY_UP): moveByY = -5 if Input.is_key_pressed(KEY_DOWN): moveByY = 5 if Input.is_key_pressed(KEY_Q): shutItDown() # Tell the other computer about our new position so it can update rpc_unreliable("setPosition",Vector2(position.x - moveByX, position.y)) # Move our local player translate(Vector2(moveByX,moveByY))