Two players are punching each other. The attacker punches for 10 damage, the server will spawn an attachment with a BillboardGui that says “10” at their fist. The tricky part is the color. I want it to be green for the attacker and red for everyone else. I have three ideas to handle this:
The simplest way would be FireAllClients, with the clients checking for if local player == attacker (green), else (red). My problem is that I plan to have, say, 50 players in the server. At best, I could distance check and only send to players near the PvPers but that could still be upwards of 20 to 50 network calls every punch. More if both players are punching at the same time. I hear this is standard practice but I wanted to check with you guys to confirm this is fine cuz it sounds excessive.
Instead of that, I could have a Workspace.ChildAdded event in a local script, that checks for the damage number instance and changes the color as soon as it appears. My issue with this one is that I have StreamingEnabled and a big city. Hundreds of childadded events might pop in every second if they are running fast and I feel like even a simple if statement for each of them might not be a well optimized approach.
Humanoid.HealthChanged event on the client, which then sends 1 remote to the server to spawn the damage number instance. I already keep track of which players are fighting each other so I check for attacker vs everyone else there. For this to work, I’d have to only send it when Humanoid.Health is less than it’s previous value, but this means I’d have to keep track of a local variable for their health constantly. That’s prone to bugs and also by far the most complicated method for this. I feel like it’s a bit much just for damage number colors.
So. What do you guys think is the best approach and why?
No. 1 Should be your best choice.
Even if you aren’t firing remotes, creating a new instance on the server will still go over the network, as the clients have to be told that the instance exists somehow.
Pretty much, the server will fire the damage amount, position, and player to each client, then the client will create the billboard gui locally, colouring it as needed.
In general, computers are very fast, and most things will be more or less fine for them to handle (that’s not to say you should spam network requests willy-nilly). It’s usually a good idea to just do what comes to mind, and then if you notice a problem like lag, you can think about resolving that then. Until you notice a problem, you don’t have to worry about it.
No. 3 is also a valid solution, keeping track of last health is as simple as creating a table of humanoids to their health value, and updating it when it changes (and removing it when the humanoid is destroyed).
And to be honest, No. 2 is also valid. Computers are fast. You could use CollectionService and GetInstanceAddedSignal() if you don’t want to use ChildAdded.
Just use CollectionService :AddTag(), I am not sure how your code is structured but sending 6 remotes every combo seems unpractical.
Another option might be to keep track of all Humanoid Healths on all clients, I am not 100% sure which one is better performance-wise but I would go with CollectionService, the second option is just worth checking if you ever have free time to optimize your game to the fullest.
Besides your ideas, my best one would be to fire an individual remote event for each player. That way only the people fighting see the text and they see it differently.
For example, you detect when somebody hits another person, AttackEvent:FireClient(), then the ui that this event makes visible is green.
When you detect if a players health has gone lower, DamagedEvent:FireClient(), then you set a red ui to visible.
You can also use your approaches, number 1 seems alright, but if you want to try this you can
It’s funny how every response is for a different solution lol. The collection service tags is a good idea but maybe I don’t understand how those work well enough. In my mind, it’s just a fancy if statement. If x has collection tag then we care about it. But that’s still checking a property of the instance so is that not the same cost?
I believe the server should be changing the Humanoid’s health, and the client does all the visual effects with no other communication from the server. The health is already replicated, why do you need remotes? Allow the client to detect health changes and have it spawn “damage numbers” on it’s own, with no help from the server.
I’m not sure u should use the color green since, intuitively, it indicates something good like healing and not necessarily u damaging the opponent, if anything I’d recommend a different color like yellow or keeping it red since the player should know when they’re trying to deal damage anyway
I believe the first option is best, I don’t think RemoteEvents are as taxxing on the server as you understand them to be, but UnreliableRemoteEvents are even better, as @fl4mxr1 mentioned, a genius idea!
I actually did end up deciding on it being red for everyone. This was a fun thought experiment though. The solution I had ended up going with was indeed the unreliable remote events that was suggested. It was pretty much perfect for my situation.