Instances through remotes is a no-no for Client-Server. But what about the inverse?

I am trying to achieve a system where a door with a ProximityPrompt is triggered by a player on the server, but opens only to the client that triggered said door.
I aim to achieve it using a remote that is triggered by the server and detected by the client.
My problem is on figuring out how to make the client know what door the server is telling it to open. I’ve been told to never send instances through remotes, therefore I don’t know what is the best option.
Is sending instances through remotes just as unreliable if I’m sending from the server to the client as it is from the client to the server?
if so, should I give each door an ID and send that and then make the client look for it? What are ideal solutions?

Thanks in advance.

You can send instances through both :FireClient() and :FireServer(), but if that instance doesn’t exist on the server or client, it will be nil.
In the :FireClient() case, instances with a nil parent or descendants of models outside of the client’s streaming radius will be received as nil on the client
In the :FireServer() case, instances that were locally created on that client will be received by the server as nil
There are likely some other situations but these are the general cases that I know of

But is it bad practice to send and receive instances through remotes, or should I just pay attention to what I’m sending and receiving and I’ll be fine?
For my specific scenario, should I do such thing, or should I find an alternative such giving an IDs for each individual door and having the client look for it?

I wouldn’t say it’s bad practice, it just comes down to how you handle the nil instance situations.

As for your specific problem, if doors are being handled locally, why have the server as a mediator at all? You can use ProximityPromptService.PromptTriggered on the client which will fire whenever any prompt in your game is triggered by the client player*, and with an attribute or tag you can see if it’s a door prompt and open it there

1 Like

Firing a door model from Client to Server is fine to trigger oppening etc.
Althrough do validations on server please.

1 Like

Please don’t spread misinformation.
It is possible to essentially send their hash/pointer, and it will automatically grab an instance out of it.
Before making bold claims, please do research.

1 Like

Thanks for the mention. The problem I said was about creating instance that existing only on client.

Is this the ideal solution for such a problem?
And is it best practice in the Roblox development scene?

You can connect proximity prompt tirgger event from server. Then you can fire script to open the door.

Depending on implementation, yes.
If you are storing some data regarding door internally you are probably using some hash (dictionary) for it

Etc: {[Model]:{…data here}}

This would be the best solution.

1 Like

It isn’t a bad practice to do either, but I think you need to be aware of handling nil references:

  • Client → Server: If you don’t validate whatever the client sends to the server or handle the errors that come with allowing this, you open the possibility that exploiters send false data to the server. Like @Yarik_superpro said, you should validate what the clients send to the server.
  • Server → Client: Is safe, though there could be a hydration issue and the client doesn’t see what Instance reference the server sends over. Client-sided code could error here. One hydration issue @nkmisoup mentioned arises from the streaming of instances.

I believe the alternative of assigning each door an ID and then sending over the ID could be messed up if you decide to adjust the nomenclature of the IDs.

As for which is more optimized, I don’t know. I would assume that sending IDs is less costly for passing server-client barrier, but I can’t recall what optimizations Roblox has done to send Instance references. I am not sure if having the Instance nested deeply would force the client more time to find it based on the identification you assign it–versus just being sent the direct Instance reference from the server.

Partially related but mainly an aside: I believe the UniqueId property of Instances is nondeterministic and not replicated between the server-client boundary if you wanted to use this. Importantly, the UniqueId of an instance is not the same between the clients, other clients, and the server.

For your particular problem, just open the door on the client after activating the prompt’s .Triggered on the client. Connect any game logic functionality to .Triggered on the server to mark validated players as cheat protection.

1 Like

A problem however is that my door opening triggers are handled entirely by the server because there are some factors that the server must validate for opening determined doors, that the client cannot. That’s why I’m questioning the possibility of sending the door models through remotes.
In this case, would sending the door models through the remotes be the best approach? If not, then what?

You can try to run script on client side, instead of firing RemoteEvents.

Like I mentioned, my door opening triggers are handled entirely by the server, so that is not possible.

In this case, would sending the door models through the remotes be the best approach?

Short answer:

It isn’t the best, but it’s fine if you have a constant number of doors or are a lazy programmer like me. I also restate this in the last paragraph of my long answer.

Long answer:

For the client → server direction, I’d send an ID and use the server to match it to a prepopulated hash table pairing IDs to their respective door models (and whatever you need for your mentioned server-sided checking code). This is similar to what @Yarik_superpro said above. This takes advantage of the low memory footprint of the “key” ID when sending data to the server and the constant lookup time for the door model when utilizing a hash on the server. A maintenance downside of doing this would be having to update the hash alongside updating whatever ID you send over from the client, if you decide to do that.

For the server → client direction,

  • you can do the same thing (hash table lookup), but I’d recommend not doing this as the client has a lower memory reserve compared to the server. More doors means more entries in this “doors” dictionary. If you don’t know how many doors you’ll have, I wouldn’t recommend this as it serves as a potential memory leak for your players. If the number of doors you have is something that is constant on runtime, you could definitely use this dictionary approach on the client.
  • If you don’t know the number of doors, I’d recommend sending over the Instance reference directly. One could argue that the recv load of sending the Instance reference might be greater than that of sending over a door ID, but I believe that the time it takes to search for potentially nested Instances on the client might be more of a nuisance. I’m open to learn more about which could be optimized here. So, if you want to optimize your game’s client recv, an optimization here would be to switch to sending over IDs to the client and searching for an Instance with the associated identification–you can obviously optimize this if you know where to search for the doors (a descendant of X where X is not the entire workspace lol).

For both approaches, be sure to check for nil references on the receiving end.

Having an indefinite or nonconstant number of doors might require a large hash on the server. But the server has a high memory limit, so it doesn’t really matter unless you go crazy with the doors. Maintaining this means having to update the key-value pairs in the dictionary you create for assigning the IDs to their respective doors on the server. If maintaining this might be a struggle for you, just go with sending the Instance reference for both directions–this, as stated above, is not bad practice as long as you consider nil reference cases.. also mentioned in my other post above.

I am still learning Luau, so tell me if there could be any more optimizations to my approach(es).

2 Likes

My door amount is constant and quite small, therefore I’ll stick with the remote approach.
Assigning an ID to each door and storing their respective instances in a dictionary sounds like quite a good solution, but given what you said, it shouldn’t be necessary.
Godspeed, fellow dev.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.