I’m currently working on a game where players can move between different zones (rooms) which can be connected through various entrances (doors).
To spare you the details, I’ve already thought of a way to detect rooms which are connected and the ones which aren’t - for example, two rooms can be connected if a door between them is open, or disconnected if it’s closed.
Now, here is a thing I’d like to achieve:
I want to prevent players from seeing or receiving updates on players who are in different, disconnected, rooms. For example:
Room A and room B are connected by a door.
If the door is CLOSED, any players in room A shouldn’t see or receive updates about players in room B, and vice versa.
If the door is OPEN, then both rooms “connect”, and players can see each other as usual.
The goal is mainly to reduce the effectiveness of ESP / wall-hacks and even to potentially optimize performance by controlling who gets replicated to each client.
The only method I’ve considered so far is to use dummy characters on each client and handle replication manually through RemoteEvents.
However, I’m concerned this might lead to messy replication logic and weak lag compensation.
So, is there any cleaner or more reliable approach to this? Any tips, tricks or ideas would be much appreciated!
You are gonna have to deal with heavy remote event usage if you want to do this. It might be a better idea to reconsider if this feature is really necessary or not, especially when it’s only for patching an exploit.
Instead of letting the client automatically stream everything around their character, you can make the server know which areas are important for each player. If in area is not on that list, the player wont send the data about the players inside it to the client. An exploiter can’t see what their client never receives.
The key is to make all players in a single connected “island” of rooms share the exact same ReplicationFocus part.
-- Server-side code
local Zones = {
RoomA = {
FocusPart = workspace.Zones.RoomA.FocusPart,
ConnectedTo = {} -- what its connected to
},
Room999 = {
FocusPart = workspace.Zones.Room999.FocusPart,
ConnectedTo = {} -- what its connected to
}
Keep track of your rooms and their connections
-- Server-side code
local Zones = {
RoomA = { Connections = {} },
RoomB = { Connections = {} },
-- etc.
}
Track Players: always know which zone each player is currently in
Update on Change: When a door opens/closes or a player changes zones, run an update function.
$) Assign Focus: This function finds all “islands” of connected rooms. For each island, it sets the ReplicationFocus of all players inside to a single, shared part.
Concept of how the logic might lookl ike
-- Server-side code
function updateAllPlayerFocus()
local players = game.Players:GetPlayers()
local processedPlayers = {} -- avoid checking the same group twice
for _, player in ipairs(players) do
if not processedPlayers[player] then
-- Find all players in the same "island" of connected rooms as this player
local playerGroup = findConnectedPlayerGroup(player)
-- Create or get a single part for this group to focus on
local focusPart = getOrCreateFocusPartForGroup(playerGroup)
-- Set everyone in the group to focus on that ONE part
for _, member in ipairs(playerGroup) do
member.ReplicationFocus = focusPart
processedPlayers[member] = true -- Mark as done
end
end
end
end
If a player is alone in a sealed-off room, you can either give them their own focus part or set their ReplicationFocus to nil to restore default behavior.
This is server authoritative, which helps you with
Hmm, this seems like it could help me achieve this, but I still am unsure about it.
Doesn’t ReplicationFocus only affect everything except other players’ characters? I think I read somewhere that this doesn’t affect other characters as they’re always replicated, though I could be imagining things and mixing this with the default streaming behavior.
Also, if that isn’t the case, say for example if room A and room B are close together, wouldn’t everything around the ReplicationFocus still replicate - including characters in room B?
From what I understand, ReplicationFocus just tells the server where the player’s “focus” is, and everything around that instance gets replicated - not everything inside that instance? By default the ReplicationFocus is the player’s HumanoidRootPart, but it replicates everything around it, not inside it.
Anyways, thanks for the reply and help! I’ll do some tests and update this post with a reply once I figure some stuff out.
EDIT: It seems that I was wrong about characters always being replicated, however based on some testing I’ve did it seems as the second case (ReplicateFocus replicating everything around said instance) is correct, unfortunately.
Yeah.
But I think you can try separating players on the server. You can try moving the actual characters of different room groups to different, far away from each other points in the workspace. A LocalScript can then adjust the player’s camera to make it look like they never left the real map. Which makes the actual physical distance the main factor for replication, which is exactly what you need.