I am currently developing an AI which is capable of seeing the player and shows them a UI that basically shows up a detection bar as long as the player stays on sight.
The thing is, I’ve already made a function to check if the player is being seen from the main server module but how can I send to the client that it is being seen without killing both the client and server with constant firing of RemoteEvents.
You could create a cacheTable on the server, insert the players name and make it’s variable == to true. Then after that do simple checks if it’s in the cacheTable not to send to client, however if it’s not then send to client. (FireClient). You could also make a function for if it’s not being seen to remove the players name from the table.
Store the name of the player(s) in a table when they are seen and when they are seen :FireClient(table), recieve it on the client and check if table.Find(table, game.Players.LocalPlayer.Name). If they find it then do what you want if not, dont show. Could be a really easy thing to do.
Or even just enable and disable it on the server. Such as when you see the player…
local posPlay = game.Players:FindFirstChild(foundPlayer)
if posPlay then
posPlay.PlayerGui.UINAMEHERE.Enabled = true
Horrible idea, never do anything with UI on the server.
For the original question, make an attribute on the player or character, and set it on the server when they’re being seen. Then on the client, use AttributeChangedGetSignal to find when the attribute changes. No need for remotes.
Thus far, I haven’t found any repercussions, or at least ones I know of from enabling/disabling a player’s UI from the server.
I also find changing what the UI displays from the server is convenient if it pretains info I don’t want seen by other players, since not creating an attribute on the character prevents exploiters from finding what it is via searching for the attribute in workspace.
Isn’t that only in the event where the remote wouldn’t be spammed? Wasn’t OP trying to avoid rapid firing the remote? Because in that case, I don’t see the harm doing it from the server since there’s already going to be issues arising from remote spam between client and server. Unless we do it the way you suggested ofc, where you just have the UI adjust itself based on an attribute. But doing it serversided would prevent the need for making an attribute visible to exploiters, unless that isn’t necessary in OP’s case. Either way I don’t disagree with you, obviously UI is best clientsided if it can be done, but wouldn’t seversided UI’s have similar comprmises to UI changes sent through remote spam anyways?
Remote spam is still more performance friendly than changing UI on the server. If he needs to be changing the UI very often then its gonna be worse than remote spam.
As an example, I’ve made a Tower Defense enemy system which is client rendered, I fire a remote every 10 heartbeats with every enemies info inside a dictionary. None of the parts are on the server, only on the client. It can handle a few thousand enemies pretty easily, with low ping and frames.
Having a few thousand enemies all rendered on the server just wouldn’t work, it’d be terrible for server performance.
Remotes are usually very small bits of info, but even sending dictionaries with hundreds of tables inside it is better than doing the work on the server.
Yeah, tweening on the server should be avoided at all costs. Instead of sending a remote for stamina, I’d definitely use an Attribute, as that’s much better than remotes. But of course it depends on if you want exploiters to see that info or not. For something like stamina it shouldn’t matter but maybe stamina is really important for your game or something.
Send ‘true’ to client, client adds 1 to counter
Send ‘false’ to client, clients subtracts 1 from counter
On client, when the counter first becomes > 0, display gui until counter == 0
local VisibilityRemote = Instance.new("RemoteEvent")
VisibilityRemote.Name = "VisibilityRemote"
VisibilityRemote.Parent = game:GetService("ReplicatedStorage")
VisibilityRemote:FireClient(Player, true) -- Visible to npc #1
VisibilityRemote:FireClient(Player, true) -- Visible to npc #2
VisibilityRemote:FireClient(Player, false) -- No longer visible to npc #1
VisibilityRemote:FireClient(Player, true) -- Visible to npc #3
VisibilityRemote:FireClient(Player, false) -- No longer visible to npc #3
VisibilityRemote:FireClient(Player, false) -- No longer visible to npc #2
local VisibilityRemote = game:GetService("ReplicatedStorage"):WaitForChild("VisibilityRemote")
local Viewers = 0
Viewers += bool and 1 or -1
print(bool and "+Viewer" or "-Viewer")
while wait(1) do
if Viewers > 0 then
print(Viewers == 1 and "I am visible to an enemy." or "I am visible to "..Viewers.." viewers.")
print("I am not visible.")
00:30:49.406 ▶ I am not visible. (x4) - Client - LocalScript:12
00:30:53.238 ▶ +Viewer (x2) - Client - LocalScript:5
00:30:53.455 ▶ I am visible to 2 viewers. (x3) - Client - LocalScript:10
00:30:56.271 -Viewer - Client - LocalScript:5
00:30:56.488 ▶ I am visible to an enemy. (x2) - Client - LocalScript:10
00:30:58.288 +Viewer - Client - LocalScript:5
00:30:58.288 -Viewer - Client - LocalScript:5
00:30:58.521 ▶ I am visible to an enemy. (x3) - Client - LocalScript:10
00:31:01.305 -Viewer - Client - LocalScript:5
00:31:01.571 ▶ I am not visible. (x15) - Client - LocalScript:12