Description
Describe the project you are working on
Topdown Shooter using Rollback (for Client-Side Prediction)
Describe the problem or limitation you are having in your project
I want every single entity to have an ID
which is the same among all players (server+clients)
So, for example player1 is always ID=1, or bullet of player5 is 527347, and this ID is the same among everyone.
So if I want to do any logic in a node (e.g. reparent the bullet, or remake the bullet, or destroy that crate), I want to pass just an integer ID to the RPC. Because in a complicated game state, it is unknown where a node is (which likely won't have any RPCs on it) - this also bypasses the problem which high-level api has, which is that RPC paths must be the same among players. This high-level api design choice, also prevents the implementation of fog-of-war
Describe the feature / enhancement and how it helps to overcome the problem or limitation
In any RPC, I send the network ID of the node and have my mind in peace, instead of ensuring the node is at that exact scene hierarchy for all players and sending a string for it. The problem here is that with client-side prediction, a player (usually local player) may have a node reparented before other players...
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
The above code shows that nodes - in C++ - already have a unique network ID. (Correct me if I'm wrong, I suck at C++)
But it isn't exposed in GDScript.
Also @Faless said that an RPC sends exclusively the following:
The Node Network ID OR the node path (only if the node path has not been already exchanged)
The function ID (reason why RPCs must match between server and client)
The argument count
The argument values
I assume the network ID is created only after the node path is exchanged? If so, a PR for this isn't so simple.
Anyway, a new function for every node like it currently has get_multiplayer_authority() -> int
get_network_id() -> int
which returns -1 if its not set yet (still nodepath)
If this enhancement will not be used often, can it be worked around with a few lines of script?
Yes. Each player has a Dictionary<int, Node>
and the server dictates the Network ID (or the owner of the node?)
Basically make a boilerplate/wrapper within every single RPC, which registers the Network ID. Usually by always having a new parameter in all RPC functions, with that parameter being the Network ID.
In my case, knowing the game format, I know the network IDs in advance because of the following technique:
My game has max 12 players. Each player controls 1 "hero". Whatever is spawned from that "hero" (e.g. projectile, buff etc) has a Network ID of the player id, multiplied by 10000. So a spawned object of player1 starts at 10000. The next one will be 10001. If player5 creates a projectile, it starts at 50000. So when an RPC of a new projectile arrives at the server and clients, from its owner (client), the Network ID is already pre-known - an increment of +1 since the RPCs I use are "unreliable_ordered".
But I am lucky for having a relatively small game state and knowing exactly what I want in advance. So the boilerplate isn't much of a chore. But such boilerplates make me wonder why RID of the server isn't synced as the Network ID itself, but thats offtopic
Is there a reason why this should be core and not an add-on in the asset library?
This is about improving core multiplayer by exposing an existing variable from C++, to GDScript