Is there more in-depth documentation on implementing authoritative servers than found here?
I’m working on a VR project, so I’d like the client to send HMD and controller position data, and apply head and controller tracking directly on the client, but still give the server authority over that movement to enforce constraints (e.g. can’t move through walls / into ‘restricted’ areas / etc).
It’s not clear to me who should ‘own’ the player avatar / XR rig / etc (client or auth. server) in this case; from what little documentation I’ve found, I suspect the idea is that the client should own all of that the same as with the normal ownership+lifetime flags approach, but that the server has the opportunity to override client-sent values as if it also had ownership.
How, exactly, would the server override what the client sent? How would those overridden values get propagated back to the client (and other clients)? Does the server have to listen to updates on relevant models and update them as needed, with those changes replicating as they would have had the server been owner?
How would I then manage interpolation on the client(s) between what the client sent and what the server corrected to? I wouldn’t want obvious rubber banding for either the originating client or other clients in the scene if the originating client, say, claimed to have moved 10ft past the point the server says it should have been limited to, and pushes that client back, for example.
Note: I’m familiar with Unity’s old netcode as well as Unreal’s replication model (among other multiplayer solutions), so I understand how multiplayer and network replication work in general; I’m looking for specifics with respect to Normal, especially given that RPCs are discouraged here, where those are a pretty core part of most client/server architectures.
Thanks to any pointers to documentation, articles, blog posts or other materials that may exist, and/or any advice or explanation you can offer!
Normcore Private supports shipping authoritative builds that have full control over all datastore updates. They can do things like validate position data from users before applying it to the datastore and relaying it out to other users, which would allow you to set specific zones that clients can go.
That said, I’d love to hear more about why you’re trying to do this. You can use an authoritative server build to prevent players from going into restricted areas, but if someone is modifying your game build to go into areas they shouldn’t be able to, they’re going to be able to ignore any messages from the server that try to position them back to a safe area. Other clients won’t be able to see them move into the restricted area, but if you’re trying to prevent them from accessing content within your title, you’d probably want to divide your space into multiple Normcore rooms and use the webhook API to gate access to each room: Webhooks | Normcore.
Dividing your space into multiple Normcore Rooms will allow you to also restrict which clients receive multiplayer updates for specific parts of your space.
The restricted areas example was just that, an example of one of the many ways a modified client could cheat in the absence of an authoritative server.
In that particular example, you’re absolutely right: a modified client could always ignore the server corrections. However, more importantly, other clients wouldn’t see that client moving somewhere it shouldn’t, and since the server knows where the client should be (and is, as far as other clients are concerned), it can then prevent further cheats – imagine a hacked client moves into a locked vault they don’t have the key to, to try and collect a valuable item inside: the server wont let them pick that item up, as it knows they aren’t actually in reach of it.
Authoritative server has been the de facto gold standard for cheat prevention all the way back to Quake, for well understood reasons. I’m don’t see how the client authority with ownership/lifecycle model Normal uses provides close to the same guarantees that server authority can, so I’m trying to understand how I can incorporate that when building on this platform.
If I understand correctly, Normcore’s model for supporting dedicated servers is to spin up one per ‘room’ – there isn’t a way to host multiple rooms per server or otherwise decouple the two? It seems to me that room servers should be relatively light weight processes as they’re purely concerned with state synchronization, so I wonder how heavy a dedicated server instance is relative to that?
In the end I guess I’m trying to understand if Normcore’s value compared to other, more traditional / in-engine networking solutions for Unity is still there if I want a server authoritative architecture.
Got it. I typically ask for context because it’s going to be much easier to solve for your specific title than to provide a generic solution that solves all cases for everyone.
That said, as far as advantages of Normcore over running your own authoritative servers go:
Normcore Private lets you run your own authoritative servers. So you’ll always be able to hit feature parity if you go that route. The main benefit over doing it yourself is you don’t have to manage your own servers, scaling infrastructure, devops, etc and you won’t have to write all of the transport logic either.
That said, our ownership APIs exist because they’re faster to work with than deploying a new server every time you make a change and they also cover 90% of authoritative logic cases. If you have to export/deploy a new server every time you change your game logic, you’re going to spend a lot more time (and money) each time you iterate on your game logic.
At the end of the day, Normcore is going to give you much more out of the box, and as you scale, you’ll be able to do the same things you would with your own authoritative system.
One other quick answer:
there isn’t a way to host multiple rooms per server or otherwise decouple the two? It seems to me that room servers should be relatively light weight processes as they’re purely concerned with state synchronization, so I wonder how heavy a dedicated server instance is relative to that?
For non-MMO titles, it’s standard practice to host each match in its own game process. In theory you could potentially do it more efficiently by combining servers, but in practice noisy neighbor effects, bugs that take out game servers, evenly distributing load across thousands of cloud instances, etc all make the one-game-per-process approach much better.