Closed dsnopek closed 2 years ago
I like the scope of the proposal, but I don't think this is tackling the problem in the correct place (also see https://github.com/godotengine/godot/pull/62870#issuecomment-1179732935).
I admit greatly over designing the original concept, and I've been working on a rewrite and modularization branch as suggested in the PR above, but the gist is that most of those functions should be extensible via the MultiplayerAPI
, not in MultiplayerPeer
.
I'll come up with a more formal implementation proposal in the next few hours.
So, these are the functions you would be able to implement in GDScript, and you would be in charge of emitting peer_connected
/peer_disconnected
/etc yourself.
# Connection
void _set_multiplayer_peer(MultiplayerPeer) virtual
MultiplayerPeer _get_multiplayer_peer() virtual const
PackedInt32Array _get_peer_ids() virtual const
int _get_unique_id() virtual const
int _poll() virtual
# RPC
int _get_remote_sender_id() virtual const
Variant _rpc(peer: int, object: Object, method: StringName, args: Array) virtual
# TBD Generic object configurations (e.g. replication API).
int _object_configuration_add(object: Object, config: Variant) virtual
int _object_configuration_remove(object: Object, config: Variant) virtual
I'm not sure if pre-encoding the arguments in a PackedByteArray is always desired, maybe we could add an extra utility method for doing that.
Ideally we could also change the MultiplayerPeer
interface to return Variant
in get_unique_id
and in its signals and do you could do your own mapping if needed.
Thanks, @Faless!
For Godot 4, that sounds like a much nicer way to make a new backend for the High-Level Multiplayer API. I'll take a deeper look into your PR, and see if I can implement my Nakama backend with it!
But for Godot 3, would it be possible to add something like the MultiplayerPeerCustom
that I describe in my proposal?
For reference, the GDNative/GDExtension code that I wrote for this is now public:
@dsnopek It looks like that the repository is still private, but in general having a MultiplayerPeerCustom
with the functionalities you describe in the proposal could be really good for 3.x
:+1: , so since it seem you've done most of the work already feel free to open a pull request on the 3.x
branch and I'll review it ASAP, so we can better discuss potential changes.
@Faless:
It looks like that the repository is still private
Ack! Sorry :-) Hopefully, it'll really be public sometime soon
feel free to open a pull request on the 3.x branch and I'll review it ASAP, so we can better discuss potential changes
Here you go: https://github.com/godotengine/godot/pull/63163
Thanks!
Closed via godotengine/godot#63163 (3.x) and godotengine/godot#63262 (4.x)
Describe the project you are working on
Implementing a High-Level Multiplayer API backend that uses Nakama (on behalf of Heroic Labs)
Describe the problem or limitation you are having in your project
In order to use the High-Level Multiplayer API over Nakama, the game developer first has to somehow authenticate with Nakama, and create a Nakama socket, so that a match can be setup (via one of the ~4 methods to create a match that Nakama allows) to relay the RPC's sent by Godot. They probably also want to have the ability to send other messages over this match or use other Nakama features on the same connection. This means the developer needs to be able to use a full Nakama client.
The Nakama client library for Godot is written in GDScript. But currently, it's only possible to add a new High-Level Multiplayer API backend in C++ (via GDNative/GDExtension or a module).
Of course, it would be possible to implement a full Nakama client library for Godot in C++, but it wouldn't be able to have the same API as the GDScript version (it currently does lots of clever things with
yield
andGDScriptFunctionState
and fake namespaces). Also, the Heroic Labs folks want something to just "drop in" to the existing client and get this functionality.Describe the feature / enhancement and how it helps to overcome the problem or limitation
If there was a way to implement a custom
MultiplayerPeer
from GDScript, then this could easily be added to the existing Nakama client library for Godot written in GDScript.Using GDNative (in Godot 3.x) and GDExtension (in Godot 4.x), I made a
NakamaMultiplayerPeer
class for this purpose and it works pretty good! You can find the code here:However, looking at the code, there's nothing Nakama-specific about it! It really only facilitates doing all the important stuff from GDScript. And it's so small and simple, that I hoped that it could maybe get added to the engine, so that GDNative/GDExtension isn't necessary.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
I propose adding a
MultiplayerPeerCustom
class, that exposes the following additional methods to GDScript:initialize(self_id: int) -> void
: to setup and set the network unique peer id, similar toWebRTCMultiplayerPeer.initialize()
set_connection_status(status: int) -> void
: changes the connection status, and also emits some of the connection related signals likeconnection_succeeded
,connection_failed
andserver_disconnected
deliver_rpc(data: PackedByteArray, from_peer_id: int) -> void
: takes any data received over the connection, and queues it to be delivered to the right NodeAnd the following signal:
rpc_generated(to_peer_id: int, data: PackedByteArray)
: emitted when an RPC is generated locally, so that the GDScript code can take the data and pass it over its connectionSo, once the connection is setup, the GDScript code will to the
rpc_generated
signal and pass that data into its connection, and any data that it receives on that connection will get passed todeliver_rpc()
.The GDScript code also needs to emit other signals on the
MultiplayerPeerCustom
object (from the parentMultiplayerPeer
class), likepeer_connected
andpeer_disconnected
as it finds out from it's connect that new peers have connected or disconnected.I'll make a draft PR with this proposed implementation soon.
If this enhancement will not be used often, can it be worked around with a few lines of script?
It's not possible to implement a new backend for the High-Level Multiplayer API purely from GDScript, it requires GDNative/GDExtension or a custom module.
Is there a reason why this should be core and not an add-on in the asset library?
Like I said above, it is 100% possible to make a GDNative/GDExtension that adds this class (I've already done it!).
However, this additional class would be very small and very simple, not adding very many bytes to the engine. And it's a shame that GDNative/GDExtension is necessary just to facilitate doing something from GDScript.