Syncronize dictionary or array

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Michalkap

How can i sync dictionary or array beetwen server and client?

:bust_in_silhouette: Reply From: godot_dev_

I can think of a couple ways. Let’s assume a client and server network setup

  1. The server hosts main copy of the dictionary/array, and every time a client needs the data structure, they request it from the server
  2. Both the client and server start with an empty data structure, and every time a user inputs an action, the input is send to the peer and the data structure is updated on both the client and server based on how the game acts given the input. In this case, you avoid sending the data structure itself and the update information over the network, instead you only send user input. This requires 100 % deterministic behavior by your code, otherwise the data structures may get desychronized (for example, move_and_slide isn’t deterministic because it relies on the delta of physics_process. You should implement your own move_and_slide in this example, which uses a static deleta). You need your code to process user input the same exact way on both peer’s machines.
  3. Both the client and server start with an empty data structure, and every time they make a change, they send the change to their peer (e.g, “add this entry”, “remove this entry”)

Choosing one of the options:

  • Option 1 would be the most straight forward but also the most naive, taking up the most bandwidth
  • Option 2 would be next the best choice, since it’s a bit simpler since you don’t have to worry about having 100 % deterministic behavior if all you are synchronizing is the data structure
  • Option 3 is the most complex but is arguably the best, since it should in theory be the most bandwidth friendly since only input is sent over the network.

Can You send me some code examples?
I couldn’t find anything about it by google.

Michalkap | 2023-05-26 16:25

Below is some code snippets that should help. Note that I haven’t tested it, but I took the logic from a project I am working on with working networking code, so at least the idea behind the logic of the code below is correct (I used Godot 3.1.2):

#network consummer logic
var peerCnx =null
var wrapped_peerCnx=null
func connectToServer():
    peerCnx = StreamPeerTCP.new()
    peerCnx.connect_to_host(ipaddr,tcpPort)
    wrapped_peerCnx = PacketPeerStream.new()
    wrapped_peerCnx.set_stream_peer(peerCnx)

func getObjectFromServer():
    
    if not peerCnx.is_connected_to_host():
        return null
    
    #wait for a packet to arrive
    if wrapped_peerCnx.get_available_packet_count ( ) > 0:            
        var obj = wrapped_peerCnx.get_var(true)            
        var error = wrapped_peerCnx.get_packet_error()            
        if error != OK:
            print("Error on packet get: %s" % error)
            return null                
        return obj
    else:
        return null

        
#network publisher logic
var peerCnx =null
var wrapped_peerCnx=null
var tcpServer=null
func startServer():
    tcpServer = TCP_Server.new()    
    if tcpServer.listen(tcpPort) != OK:    
        print("error starting server on port "+str(tcpPort))
    else:
        print("server listening on port: "+str(tcpPort))    
            
func sendObjectToClient(obj):    
    wrapped_peerCnx.put_var(obj,true)
    var error = wrapped_peerCnx.get_packet_error()
    if error != OK:
        print("Error on tcp packet put: %s" % error)
                
func listenForClientConnection():
    if tcpServer.is_connection_available ():            
        peerCnx = tcpServer.take_connection()
        wrapped_peerCnx = PacketPeerStream.new()
        wrapped_peerCnx.set_stream_peer(peerCnx)

godot_dev_ | 2023-05-26 17:32