I don't know how I should use the server and client

Usually for my scripts I make animations and the parts for projectiles on the server but recently I saw a video by sleitnick saying you should never make animations on the server and I saw a projectile video by qweekertom showing a rocket model being only visible on all clients.

How would I make visuals show for every client on the server? I could use FireAllClients or loop through player and fire to clients from there but the Roblox AI Assistant says its very imperformant and could cause issues.

Do I just use FireAllClients and work my best to optimize it to avoid these repercussions?

3 Likes

you could always use a for loop to check each player’s character is close enough to play the animation, then just fire the event to nearby players.

What if I were to make punching particles on the client and punching had a cooldown of 0.5 seconds? Players would still be firing an event each .5 seconds.

Fire the event once at the start of the animation with a “start” value and then once again at the end of the full thing.

What if the server were to constantly fire to clients (I’m using punching as an example).

1 Like

In games like The Strongest Battlegrounds there is a huge amount of visuals and you can see them across the map.

while task.wait() do
	game:GetService("ReplicatedStorage").Event:FireAllClients()
end

I tried this and it lagged my game but my Network(KB/S) didn’t raise because of it.

2 Likes

Ideally you’d be using the client more than anything else. All you really need to do is fire to the server.

Maybe the server changes an attribute on your character. If a nearby player sees that attribute change, use their localscript to play the animation.

1 Like

The clients and their localscripts see all property and attribute changes made by server scripts automatically.

Making the client see that attribute change would probably have more of a negative impact on performance because I would have to do something like a RunService to check for attributes and players in a certain magnitude.

Like Sleitnick forcingly addressed, animations should be done on the client, as well as with about everything that has no affect on the game, (over course though with sanity checks). The problem is, is that I don’t know how I’m supposed to keep my game performant while keeping less stress on the server.

No, just use the GetAttributeChangedSignal connection. No constant checking at all.

It’s like .Touched.

3 Likes

Just tell all clients to do X animation. And then the clients will animate whenever the server tells it to.
For example:
Create explosion at position Vector3.new(105, 12, -45) of size 10. Then that client that recieved that event will create that explosion. It’s as easy as that.

The client can also create parts for effect and then delete them when the effect ends. Like a rocket or paint splat.

Sleitnick says to not do animations on the server though.

I was thinking more like

Client:
Fire server → animationName

Server:
Change player attribute Animation

Client:
Sees animation in attribute changed signal, play animation.

game.ReplicatedStorage.DoTheAnimation:FireAllClients()
-- on client
game.ReplicatedStorage.DoTheAnimation.OnClientEvent:Connect(function()
  -- use TweenService to animate
end)

Oh I see, I’ll try using attributes instead of firing events.

It’s just that firing to every client has a bad impact on performance.

How would I make it so the GetAttributeChangedSignal stops because after I change the attribute, the GetAttributeChangedSignal continues to repeat in a loop since it is changed twice.

I’ve done something like this before and my studio has crashed.

Only change it on the server and only play it on each client after the ChangedSignal event. Don’t play it when the player pushes the punch button, just wait for the ChangedSignal. Or, you can see if the animation is already playing and then return out of the Changed event early after setting the attribute.

2 Likes

what if I were to do something like:

Server function()
   ChangeAttribute()
   task.wait(3)
   SetAttributeBackToOriginalState()
end

The attribute changed would play forever after I have changed it, even if I put an if statement it would still forever loop in the game.

I also am trying to replicate your idea but its not working:

local counter = 0

while true do
	counter += 1
	for i,v in game.Players:GetPlayers() do
		if counter >= 10 then
			print("")
			v:SetAttribute("Cool",true)
		else
			print("1")
			v:SetAttribute("Cool", false)
		end
	end
	task.wait(.1)
end
local player = game.Players.LocalPlayer
task.wait()
player:SetAttribute("Cool", true)

player:GetAttributeChangedSignal("Cool"):Connect(function(attribute)
	print("Success")
end)

Everything prints on the server but nothing on the client.

2 Likes

Nevermind I was changing the attribute inside the local script, my bad. I also just realized the GetAttributeChangedSignal won’t fire if it has already been set to something which I didn’t think was true because of some weird thing called LocalTransparencyModifier.