Allow the server to control all replication to and from clients

As a Roblox developer, it is currently too hard to control the “filtering” part of “filtering enabled”. Allowing clients to change some properties, disallowing some clients from seeing certain Instances, allowing some clients to view something under ServerStorage, etc. Ideally, all of these would be filterable (and modifiable in transit) via Lua callbacks (both send and receive), so you can control anything in a fine-grained manner.

Modifiable in transit allows the server for, for example, filter .Name changes initiated by a client so the game doesn’t get banned for being unfiltered :stuck_out_tongue: (looking at you F3X)

If this issue is addressed, it would improve my development experience because replication is a very powerful system that developers currently have no control over. Allowing developers to access that system could allow many useful things that currently aren’t possible (like showing different things to each client or giving only one class access to an Instance). More info below.

Just imagine how cool it would be to replicate a different value for the same property to different clients.

This could become an absolute mess if done/used incorrectly, but it could be extremely useful and powerful as well!

More information below.

So, filtering is enabled now. It has been for years, and it has been pretty great. But the server can’t control that filtering at all. Sure, there are ways to communicate data values from client to server and vice versa using RemoteEvents and RemoteFunctions, but replication itself is still fixed. Sometimes, you have to come up with some weird things to get around replication bugs, and sometimes you’re unable to fix something critical like that RightGrip replication bug. I propose a new feature set that lets the server control client -> server replication and server -> client replication.

Right now, certain Instances exist that are server side-only, and certain Instances exist that are client-side only. But from these points, nothing can cross the boundary. I can’t grant one (and only one) client access to a model in ServerStorage, I can’t have one privileged client replicate their instance to the server. Serialization can only go so far for giving clients Instances, and having to route requests to change properties on Instances through RemoteEvents can be inconvenient.

Example use case 1:
Creating parts or instances that are server side-only. Turning off replication for an instance so that if it’s parented to the DataModel, the client won’t even get notified of its existence.

Example use case 2:
Preventing some local parts (even the very small subset that Roblox allows) from replicating. For example preventing the character position from replicating (this is physics replication fostered by network ownership, not necessarily property replication, but I digress). This places less stress on the server to return the part to its original position every physics step if you want to freeze someone in place, but this could be complicated to implement since there would then be no way to read what the client wants to replicate to the server, unless some new mechanism is introduced. Additionally, the RightGrip bug that has been making rounds lately could have been patched by game creators more easily if we had the ability to stop it from replicating to the server in the first place.

Example use case 3:
Allowing only one client to view something. For example, have it in ServerStorage and grant one player access to it. If you have only values/data, you can easily tell just one client about it through RemoteEvents or RemoteFunctions, but if you want the convenience of replicating an instance to them, you either have to serialize it and do weird stuff, or simply make it accessible to all clients and have the other clients (which could be controlled by exploiters) willingly not do anything with that instance, or delete it (which can be intercepted by exploits).

Example use case 4:
Building tools. Controlling replication directly could remove some of the burden on RemoteEvents. Rather than telling the server to update the part, then receiving the change from the server, you can make the change yourself, and the server can allow it to replicate. This can actually allow some legacy building tools to work in a game where you do not need anything resembling access permissions. You might even be able to use the HopperBin ones. If you do want access permissions, that’s fine! You would be able to have the server filter the values before replication from client -> server is complete, so the value that makes it to the server (and to other clients) is nice and approved.

In this feature request, I propose the following:

  • The server can allow certain properties on certain Instances to replicate from a client/multiple clients to the server side.

    • The server can also filter these changes before they are replicated to the server, in which case the filtered version will be replicated to all clients (optionally including the originating client). The server can also completely deny a replication, and decide whether or not to tell the originating client to set the value back. Example: Filtering part names or limiting part positions/size, for building tools. Disallowing clients from creating a bajillion RightGrip instances.
  • The server can prevent Instances from replicating to any clients, or particular clients. If the client knows about this instance then the server can tell the client that it has been deleted, and no new changes will be streamed to that client.

  • The server can allow new Instances created by the client to replicate to the server. These also pass through a filter just like the properties, and the server can change properties on it or deny its replication entirely. Should also have the option to notify the client of the Instance’s changes, or deletion, if applicable.

  • The server can grant the client access to instances that currently do not replicate. For example, objects in ServerStorage. You can grant access to one client or all clients (although objects intended for all clients would definitely be better parented to ReplicatedStorage). By granting access to an object, all of its ancestors would have to replicate to the client, but not necessarily any of its siblings. If an ancestor that shouldn’t replicate to a client also has no children that should replicate to that client, that ancestor should become deleted from the client as well.

These replication abilities should work with any Instance. If I want to make a server-only part or Instance, let me turn off replication to clients before I parent it to the DataModel. If a client parents a new instance to Workspace, maybe I wanna see, or accept it into the server side!

This is an extremely complex (and opinionated) featureset to request, and I would love to hear your thoughts on it. Let me know what you think. I would also love to hear about how Roblox’s replication system works, and if it would even be possible to integrate it with Lua/u in this way, or if that would be too much of a bottleneck.