+1 vote

To enable networking, one has to provide networking peer to the SceneTree, mostly by initializing NetworkedMultiplayerENet for creating servers and clients and be able to use high-level networking capabilities. Is it possible to use such a peer to do low-level networking along with RPC system as well (since it inherits PacketPeer)? I mean something like this:

func _process(delta):
    var peer = get_tree().network_peer
    if peer:
        if is_server():
            for peer_id in players:
                if buffer.size():
                    multiplayer.send_bytes(packet, peer_id)
                    buffer.resize(0)
        else if is_client():
            while peer.get_available_packet_count():
                var packet = peer.get_packet()

The reason I'm asking is that I stumbled upon a problem sending large data to network peers (in order to sync game world). The data size can range from 500kb to 5mb.

I tried to call RPC method with my data being nested Dictionaries with values including PoolByteArrays, but the client hangs. The reason for this is probably that the packet size might be too big to be handled by RPC system... Do I have to create additional PacketPeerUDP or something similar for handling large data transfering? I'm somewhat new to networking so feel free to enlighten me on the topic.

asked Jul 8, 2018 in Engine by Xrayez (1,156 points)

I would always chunk the data when udp is involved and if it exeeds lets say 255 bytes.
But on the other hand, since we have enet, maybe try to "reliably" send your data.
Try to also compress your data first.

Oh yeah I've even compressed my data but it still exceeds packet size. Seems like data chunking is the most logical solution... could probably use high-level networking for that too. Need to read up on the topic more.

2 Answers

+1 vote
Best answer

Yes, Godot master has a major change in its api.

http://docs.godotengine.org/en/latest/classes/class_multiplayerapi.html?highlight=multiplayerapi

Faless introduce Mutiplayer api. Multiplayer api have a function call sendbytes that lets you send raw packets. You can receive it with networkpeer_packet signal

answered Jul 19, 2018 by hungrymonkey (419 points)
selected Oct 12, 2018 by Xrayez

Somehow I overlooked the network_peer_packet signal... I've probably got confused with default networking implementation in the SceneTree and MultiplayerAPI.

I've connected the signal and can freely send bytes and receive them on clients now, thanks for pointing that out!

0 votes

Thanks to @hungrymonkey I've come up with something like this:

# Server/client
func _ready(delta):
    multiplayer.connect("network_peer_packet", self, "_on_packet_received")
    multiplayer.send_bytes(PoolByteArray([0, 1, 2, 3]))

# Client/server
func _on_packet_received(id, packet):
    print(packet)

I've also tried to send packets on an even lower level:

get_tree().network_peer.put_packet(packet)

In the network_peer_packet callback when trying to receive packets on client I got errors like:

ERROR: _process_get_node: Condition ' !F ' is true. returned: __null
   At: core/io/multiplayer_api.cpp:247
ERROR: _process_packet: Condition ' node == __null ' is true.
   At: core/io/multiplayer_api.cpp:187

Which is most likely expected because I'm trying to mix different APIs or whatever... Anyway since there's send_bytes introduced I don't think I need to go that low.

answered Jul 19, 2018 by Xrayez (1,156 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.