Networking: why RepNotify Attributes when you can replicate movement and skills ID only?

​Hi !

I’ve been playing with GAS recently for a multiplayer RPG project and this question can’t get off my head: why should I RepNotify every Attribute?

It’s really network consuming so why not only load attributes when the actor becomes relevant (Net Load, COND_InitialOnly), then reliably replicate only movement and abilities (the enum ID) ?

Further explanation in case I’m not clear: what do you think about the idea of NOT replicating attributes on server change, as long as you handle properly Relevancy of actors: attributes are synced everytime an actor becomes relevant. Then I could update locally these local attributes (every time I as a client receive the request to fire an ability from a relevant actor) and it should still have the same value as the server as long as I at least replicate movement/skills ID correctly

What would go wrong? Is it about the risk of desync?

If a player cheats attributes locally, well… it just screws its own instance, server won’t be affected. Also note that no RNG is involved (ie no critical chance).

Since I am not aware of tutorials / projects that do things this way, I guess other actors attributes would end up desyncing from server at some point or something, but I cant seem to find out in which cases

Could you help me out with this problematic?

EDIT: Updated subject and post from why replicate attributes to why RepNotify Attributes rather than just replicate them conditionnally with COND_InitialOnly

I don’t have an answer to your question, but you really need to change the font on this. It’s barely legible. I had to highlight the text in order to read it.

Oh I didn’t notice the color I’m sorry, pasted it from my text editor I have no idea what happened, fixed it :slight_smile:

It wouldn’t make sense to not replicate them. It’s like asking “why replicate any variables”.

The values are replicated because they are the latest authoritative values calculated by the Server. If clients calculated those values locally instead, then they would never be in sync with the true state of the game. Clients can’t predict everything reliably.

Also, if an actor isn’t relevant to a client - then nothing about that actor replicates. It doesn’t exist as far as that client is concerned, and the Server won’t send updates to that connection until it’s relevant again.

If you think attributes are network hungry, don’t look at movement packet traffic. :slight_smile:

Thank you for taking the time to respond. You confirmed I understand relevancy properly. But the following part of your answer is precisely what I’m having a hard time to wrap my head around :

. Why? When relevant, the actor is loaded with its attributes, he attacks me, I calculate damage locally given the loaded attributes, how would I end up having different values the server has? I have no doubt you are right, I just don’t get why. From what I can see (not much) while values wont be literally synced since attributes are not replicated on change, they should stay the same as calculations should be based on the same values therefore ending up with the same result, be it with 2 or 20 players around.

Well I guess I will have to inform myself on the movement subject at some point, for now it seems out of my league. With Able, I’ll still have to implement my own movement component to save up some bandwidth?

Able doesn’t touch character movement (beyond talking to it occasionally), that would be a whole other plugin and a half. However, CharacterMovement works for Fortnite (which has to deal with mobile and all sorts of fun connections) so I wouldn’t touch it unless you have to. In general, I would only start to optimize bandwidth towards the end of a project when you have a more accurate picture and where hot spots are.

To touch on TheJamsh’s point, if you just bet that the client will get every skill or whatever to calculate the stats, then you’re taking a dangerous gamble. Take this trivial example:

Player A is on one side of the world. Player B is on the other. Due to the distance, it’s likely that Player B will be out of Player A’s net relevancy. So, it’ll receive no updates about that Actor. Player B buffs up his stats (Str+, Lck+, etc), then goes to join Player A. Player A will see a normal Player B, no buffs, no nothing - because he never saw those updates and you aren’t replicating those stats when he joins Player A.

Another example:
Player B, decides to buff himself and Player A, and is spamming his buff skills (first strength, than luck, then health or whatever on each player). In your view (and maybe Player A’s) - all those buffs go off without a hitch. However, on the server, it rejects the Health buff on Player A because it says the skill was still on cooldown. You both go into a Dungeon and Player A dies instantly at half HP (because the server doesn’t think he has that buff). He respawns thinking “That was weird”, and it happens over and over - all the time because the SERVER who is authoritative had a different picture.

So from a security, network, and gameplay viewpoint - you have to replicate those values. There’s no other way if we’re not talking about a 100% deterministic local simulation that is separate from the network entirely (Cloth for example).

^ This ^ … It can be worth thinking in different perspectives. Imagine you have a simple 3-player arena shooter (everyone is on screen / relevant all the time). To test the game you run a Listen-Server in PIE with 2 Clients (minimum practical config for testing). So now you have 3 windows in front of you, showing the POV of 3 different players. But in practice to code this, you need to realize that you actually have 9 different player POV’s to consider (3 different windows x 3 players). If you start letting each local player work off a mixture of local and networked data, you’re going to see 3 different realities or inconsistencies.

The Server will be the overriding authority if something is replicated / rpc’d. But otherwise you’re going to have chaos potentially… Especially if Client1 is being attacked by Client2, but Client2 has a different view of reality about the attack-strength or their own armor / health versus Client1’s. What if all three players attack each other at the same time? BTW: The font is still unreadable in dark mode. It can help to cut it all into Notepad or something basic and paste it back. Try to test in ‘dark-mode’ plus ‘epic-forum-style’ in more than one browser if possible, as maybe that’s the problem. It looks ok in white not dark atm. :wink:

That’s an interesting point :

. I thought when the actor becomes relevant, server would send its own currents attributes and active passives along with the actor, wouldn’t it? Maybe I explained the case badly: Attributes are rep with Condition_InitialOnly but not RepNotified.

About your second example, if the server rejects a buff request fired by PlayerA to himself and PlayerB, PlayerB will never receive it obviously, but I thought GAS handled the cancellation process, so that PlayerA would receive the rejection and roll it back and nothing happened for him either, but I might be wrong.

Indeed I understand your answers and I absolutely agree : not replicate attributes on change (by attributes I meant Health Mana and AttackPower etc) means chaos the second client values are not the same the server has. Hence why I was asking what could make these values differ as long as there is no rng involved (such as critical chance or missing chance).

I updated the font again, sorry, seems this time it is fine.

What an interesting way of climbing the ladder :stuck_out_tongue: Hopefully the only thing going from client to server being input and movement, and server being the authority it is able to refuse actions (such as buying an object if he knows you don’t have the money) those things won’t happen

Anyway I’ll update my code and add a RepNotify on attribute changes so I don’t take the risk of having desync issues

I think I’ve understood what made my question so misleading. I updated subject and post from why replicate attributes to why RepNotify Attributes rather than just replicate them conditionnally with COND_InitialOnly.
Obviously if I never replicate Attributes it would never be synced.

You might need rpcs to bandaid things and they could be in the end more expensive than simply let replication system do it’s work.

I think it’s reasonable for inventories, you don’t want a player inventory replicated all the time, but not a so good idea for character stats like a moba which is what GAS was built for.

I am pretty sure if the system was not done properly and was bad network performance wise, Epic would have changed it or fixed it, and not use it in a 100 player battle royale game. And attributes like all properties will only replicate when they have been changed. So if you don’t change them they will not replicate. You only pay bandwidth when you are modifying the attributes.