Well, I am creating a multiplayer game and want to use Unity Transport, as it allows me to create and serialize messages the way I want. The current approach I’m using is that the client performs the simulation and sends the position and rotation to the server.
However, a question came to mind: how can I make the server authoritative, simulating the player’s movement based solely on their inputs? Would I have to instantiate the player on both the server and the client? I wouldn’t like to create a separate project for this, but I also don’t know how to make a root player simulate both the client and server in the same scene, considering that the player object on the client will interfere with the player object on the server.
Given the question, I question your approach.
Basically Netcode already does all that for you transparently. Why throw it out the window just so you can have your way? When you do that, you ought to have a good understanding of the fundamental networking concepts already established (meaning: the kind of question you’re asking shouldn’t give you a headache) otherwise it will be an extremely painful journey.
The basic premise of making a server authoritative is simply to run the simulation only on the server side. Period. What you instantiate on the server side is … nothing. On the client side: anything you like, as long as it corresponds to the given object that gets simulated.
You will need to identify these entities of course, by index or hash code, because you need to issue commands like “move player #4 to position xyz”. Actually, you’re not issuing commands. You take the delta state of the game simulation buffer - all positions, rotations, velocities etc and pack/compress that and send it out in a single frame ideally. You’re not sending one message per object, or even one message per each object’s actions or state changes - that would be very inefficient.
Every client state is simply a representation of the server simulation, and typically interpolated because the server simulation runs at a much lower tick rate (20 Hz is common). And then think of the game simulation solely (!) in terms of data, not objects. The objects (ie prefabs, effects, audio) are secondary concerns completely detached from the simulation.
It basically ought to be designed in a similar data-oriented manner as the Entities framework.
If you got all that down, then by all means use Transport. Otherwise you’ll be far better off using Netcode.
Thank you for your time. My goal is really to understand how things work under the hood, and not necessarily to create a game.
However, when you mention “What you instantiate on the server side is … nothing,” I may have missed something. How can the server simulate, for example, that the player collided with a wall when receiving player input and trying to move forward, if the player is just data and not instantiated to actually collide? (which is actually what I’m doing now)
Assume a classic 2D sprite action shooter. Collisions would simply be rectangle intersection tests. No need for 2D physics.
Even with 3D physics, if the collisions are primitives (and they should be) all you need is to create dummy objects that represent just the collider (type and size) - not the actual player prefab with the mesh. But you’re right, in this case you would usually instantiate a dummy collision object.
Still, if you know that all your objects are capsules, spheres or boxes and physics doesn’t do anything besides collision tests and applying gravity, it wouldn’t be difficult to simulate collisions just with simple distance tests and box intersections, with the capsule collider being a combined 3D distance (top and bottom sphere) and 2D distance test (assuming the capsule is always axis aligned).