Avoiding the Workspace to replicate from server to client

The players are stationary, the projectiles evidently are not.

The goal is to the Workspace not to replicate from the server, if possible, if not, we’re discussing the alternatives.

If the client doesn’t get the other player’s location replicated from the server in the first place then they cannot see it.

1 Like

As long as you don’t expect clients to lower their FOV then that part should be fine. You can easily have the server and client communicate to create localized parts. As long as the FOV isn’t changing super quickly there shouldn’t be much performance issues.

I would think the projectiles would just been handled by the server and replicated to everyone, that way players know who/what killed them and the server doesn’t have to work with any spoofed client information/parts.

If you put script.Parent = nil the script will still work, and it can’t be deleted.

I think that the topic is being derailed to a discussion about exploiting.

It is a fact that there isn’t a foolproof method to stop exploiting only using client-sided methods. Refer to @AMD_chan’s Exploiting Explained for more information.

The problem here is:

  • I don’t want to let the client to see the server’s Workspace. Period. I would then handle Workspace replication my way.
  • If I let the client see the server’s workspace, I have no guarantee I can delete the unallowed parts from the client. This is a particular case where I can’t really implement sanity checks.
  • I still want the Workspace to dynamically calculate physics, so moving it to ServerStorage is not an option unless I like to waste time recoding the collision solver on a platform that is less efficient.
1 Like

If you’re concerned about exploiters seeing more than they are supposed to, just kick() whenever an object that’s isn’t allowed being replicated onto the players client is found.

That means that the server would literally kick everyone: The server replicates everything in the Workspace by default, so every client would see something they shouldn’t.

That is false information. I don’t really want to derail away from this topic, but the code will still execute, and therefore can be edited (I believe it goes into the RAM, but don’t quote me).

There is no way to stop exploiters from viewing everything - besides not giving them it

What you are doing is making it harder to find the script, but if you really try, you can find the script one way or another.

Sidenote,

script = nil

Removes all references towards the script, and is probably better for what you sound like you want to do.

1 Like

Personally, i’m not sure if exactly what you’re asking for is possible (without using some of the hacky methods stated above), as such it might be worth making a feature request instead.

Why ServerStorage ?

Sure it helps with security, but having the replication being done via remotes etc could possibly lower overall game performance. Mind you, I’m no expert, personally I would put the game map in ReplicatedStorage and have a localscript handle the replication manually.

Does this pose a security risk ? Yes.
Can you patch them ? Yes.
Can your patch be exploited ? Yes.

On the topic of security, no matter what exploit you encounter, there’s always a way to patch it. Likewise, no matter what patch you write, there will always be a way to exploit it. This is the reality that you have to face security-wise. There’s no ultimate patch for anything.

OP wants to avoid direct server replication, this isn’t about security so why speak of it right ? However one could argue that efficiency and quality does come to mind on any programming topics.

Surely security matters, but before we get to that, let’s look at a couple pros and cons,

1) ServerStorage

  • More secure than clientsided method handlers [ PRO ]
  • Slower than clientsided method handlers [ CON ]

2) ReplicatedStorage

  • Replication can be done without having to go through possible latency delays [ PRO ]
  • Easily exploitable [ CON ]

This brings us back to the old debate of Security vs Gameplay, personally I would suggest handling them on the client side, because statistics. You have to consider this, with server handlers, you’re looking at a guaranteed gameplay-affected experience for all players in your game.

On the other hand, with client-handlers, you’re looking at the issue of Security and Exploiters, the possibility of ruined gameplay experience for some players.

Between this two, it’s better to pick the latter, statistic wise. In no way am I saying that security is mediocre and redundant. In fact, security is always something I think about first when I’m programming, but while doing so. One must never sacrifice general gameplay for improved security.

With every method there’s flaws to account for. And in your case, that’s the only suggestion I could think of really. In no way will this be the best solution, it is simply my humble opinion. Someone else may stumble upon this and suggest a method unknown to us, and in that event we shall learn and improve ! :smile:

14 Likes

If you handle the view range locally then you won’t be able to punish exploiters for increasing their view range.

It’s still possible to get localscripts after they’ve been nilled.

If you have somewhat of an idea of where the player’s view is, and what they can see - if a user is repeatedly getting shots on players far beyond their view range (I’m not sure how big you map/view range is) then you could always punish them.

As others have said, I do feel as though for the best experience to follow @Zenuvius’s post (Here’s the post )

Security measures can always be put into place, but honestly I don’t feel as though there’s much point dribble feeding the client the information, rather than all at once.

1 Like

That’s what I’m saying

Also can’t an exploiter just speed around the map at lightning speed by moving their character and get all the map info? Or are you protecting against fast movement?

3 Likes

This cannot be more true:

On the topic of security, no matter what exploit you encounter, there’s always a way to patch it. Likewise, no matter what patch you write, there will always be a way to exploit it. This is the reality that you have to face security-wise. There’s no ultimate patch for anything.

1 Like

I doubt it is possible to change the behavior of replication, however, I would like to offer you some alternatives.

You could send data to the client using RemoteEvents. A local script would place the models accordingly, Since the player won’t move, you only need send data every time their view range updates, unless there is another player in view, in which case you would need to update that player’s cannon/turret.

To shoot, you would send the server a Vector 2 (since the game is 2.5 D). The server can detect hits using simple linear algebra.

For the sake of simplicity and performance when calculating hits, you could simplify a player’s hit box to a circle, while defenses such as walls, could be simplified to lines.

This solution is not ideal, just like Zenuvius pointed out. It may compromise performance, but it will certainly be hard, if not impossible, for exploiters to work around it.

1 Like

You could write your own replication module, store the map in ServerStorage and send data to each client through RemoteEvents, every part being linked with its serverside companion. You could even lower network traffic by sending relevant data that the client could maybe reconstruct rather than sending data for every single instance (ex: updating one part’s position in a model rather than sending every part when calling SetPrimaryPartCFrame). With that, I’d say you’ll have more than enough bandwidth to work with

4 Likes

Exactly, this reminds me of some kind video compression: In each frame, you only save the values of pixels that have changed, not the value of every single pixel.

This might make the client code more complex, but in my opinion, it is worth it.

2 Likes

I have a late suggestion; you could try setting all the characters’ Parent properties to nil. Exploiters could however run code that stores all the characters in a table before the client removes them from view.

To combat this, I’d further recommend keeping the characters parented to the Workspace, then setting each of their BaseParts’ parents to nil. When you need them back in view, simply parent that component back to the character rig.

This can get complicated, but you can leave the Workspace empty server-side so the contents don’t replicate, and send only the information the clients should have access to through RemoteEvents so they can reconstruct the map on their ends.

If you need characters, you could try putting an empty Model in StarterPlayer and then put in all the character stuff client-side once the empty character model spawns. I never tried that though, so if you do try, expect things to go weird.