Hello!
Describe the project you are working on:
I'm working on a 3D multiplayer game.
Describe how this feature / enhancement will help your project:
Currently high level networking API is great in itself but it's lacking one of the main features -- the ability to simply spawn objects over the network. This is a major pain point for most of networking games. I believe it is possible to come up with generalized enough system for networked instatiation so that many projects would benefit from it.
Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:
I've already implemented a simple system for that as an add-on for Godot 3.1.
If you wish to see the overview of the system please take a look at the first half of this video:
https://youtu.be/0kXzSleNixo
Also you can read the "Design Choices" paragraph in this repo:
https://github.com/razzeeyy/godot-networked-instancing-example#design-choices
In short the system provides 2 new types of nodes, first one is the SyncRoot which is used as a general replication root, and second one is the SyncNode which is used to mark scenes to be networked if a scene with this node is added as a child of the SyncRoot. So it achieves that feeling of "it just works" -- you instatiate and parent the objects locally and they're networked automatically.
Describe implementation detail for your proposal (in code), if possible:
Refer to this repository for implementation details:
https://github.com/razzeeyy/godot-networked-instancing-example
More specifically files of interest is:
SyncNode: https://github.com/Razzeeyy/godot-networked-instancing-example/blob/master/addons/sync_sys/sync_node.gd
and
SyncRoot: https://github.com/Razzeeyy/godot-networked-instancing-example/blob/master/addons/sync_sys/sync_root.gd
Currently the system assumes files on the cllient and the server are the same and leverages Node.filename property to achieve this seamless networked instantiation. I'd also like to have it work with simple Nodes/Scripts but I can't come up with a good implementation solution for that currently, I'd love to hear your ideas if you have some.
Also it does some simple replication just by sending a dictionary over the network at a specified interval. This saves writing extra rsets and rpcs just to pass around some frequently changing state. (I'd agree that replication functionality isn't really needed in this addon, and maybe even harmful in a way in its current concrete implementation. Regard it just as a proof of concept.)
If this enhancement will not be used often, can it be worked around with a few lines of script?:
Well as you can see I already did worked around with a few lines of code. Although not as complete work around as it would be.
Is there a reason why this should be core and not an add-on in the asset library?:
I believe networked object spawning/despawning is a core feature of most high-level networking libraries out there (as an example Unreal has it, Photon has it, UNET has it, Forge Networking has it, yadda yadda). And I'd really want to see high level networking functionality in godot improve and provide even better experience and match the expectation of what high level api should really be like.
P.S. also a similar issue was discussed at the general tracker: https://github.com/godotengine/godot/issues/16793
P.P.S. I know this wall of text would be hard to read, sorry. I've never been great at writing essays, so if any moderators would make an effort to reformat this text in a more readable way I appreciate that.
Thanks.
While this is a cool system, I think it could be made part of the high level networking API instead of a node. What do you think?
As stated by the author, it's just a proof-of-concept to demonstrate how it's not trivial to implement via script, but indeed it has to work internally to be efficient and reliable.
For instance, many of these replication metadata could be added via PROPERTY_USAGE_* enum or similar, and of course utilize PropertyInfo for that. I've already described some of these concepts in godotengine/godot#16793 though, some of them might be a bit far-fetched but still...
Surprisingly, I've accidentally stumbled upon this at roadmap.
Would be great if that kind of node listed on the roadmap got implemented.
Meanwhile I'm using high level api and my library and the more and more I come across high level api shortcomings, like server re-broadcasting any recieved data to all clients by default, having multiple masters for the given node is difficult. Basically high level api still requires a lot of work from user to be robust/secure when developing networking with it.
The most complete networking model in my opinion is the one from Unreal Engine (although I'm not sure if we can copy it blindly cause copyrights and stuff) it even assumes rpc validation by default.
Would be nice if as much of community came together and had a talk about most feature complete high level api design, because I feel like implementing it (even step by step) is still having the possibility to go in the wrong direction because people don't really share what use cases for networking they need and maybe some of them having the same pain points as me but maybe some people have completely different kinds of trouble...
Meanwhile I'm using high level api and my library and the more and more I come across high level api shortcomings, like server re-broadcasting any recieved data to all clients by default, having multiple masters for the given node is difficult. Basically high level api still requires a lot of work from user to be robust/secure when developing networking with it.
The message broadcasting issue is covered in https://github.com/godotengine/godot/issues/27932.
The most complete networking model in my opinion is the one from Unreal Engine (although I'm not sure if we can copy it blindly cause copyrights and stuff) it even assumes rpc validation by default.
We can't indeed. We shouldn't even look at its source code :slightly_smiling_face:
assumes rpc validation by default
Isn't that a really bad practice?
assumes rpc validation by default
Isn't that a really bad practice?
What I meant is that it has a mechanism for rpc validation implemented already.
Sorry for ambiguity.
And well about security... You'll want rpc to pass anyways (assuming the method is allowed for rpc) and even in unreal most rpc validation callbacks are stubs with return true (especially during development) so it won't hurt much. But the ability to simply write 1 extra function to reject rpc's that bear the data that isn't valid for the current gamestate is really usefull, right now in Godot it can be done too but requires more code.
Regarding security, I've been pushing for encrypted udp. @Faless was able to get DTLS for packets sending and receiving, but we still need to design the ENET over DTLS layer.
I've made some updates to my addon and now it can do automatic replication of transforms and rigidbodies. Maybe we can do something similar in godot out of the box.
Reference implementations:
If you're interested in my addon you can see the readme here https://github.com/Razzeeyy/godot-networked-instancing-example
Here is my plugin for replication: https://github.com/Jummit/Godot-Replicator-Node-Plugin
Just add a Replicator node to an object and specify which properties should be replicated. It's as simple as that.
@Jummit actually good implementation for replication, even more flexible than mine.
Can be really great when combined with spawning.
@Jummit actually good implementation for replication, even more flexible than mine.
Can be really great when combined with spawning.
Thanks! Something I want to add to my addon is interpolation, probably using a tween for every property, so that there is no teleportation.
Hello @Razzeeyy, @Xrayez, are you currently working or planning to work on this feature? I would like to give it a try in the upcoming months if any of you aren't working on it :)
@SkyLucilfer you mean on the C++ side? I haven't got further than rest of the folks here and it's not on my priority list, so go ahead! Lets hope @Faless can start working on this in 4.0 perhaps (Godot's networking guy).
Most helpful comment
Regarding security, I've been pushing for encrypted udp. @Faless was able to get DTLS for packets sending and receiving, but we still need to design the ENET over DTLS layer.