Effect Auras

Hello!

So regarding a buff/debuff system: lets say you cast on yourself a +damage buff, or invisible (any beneficial buff) and you would want it to appear on the character in a state of aura. What would be the best way to do this? I tried via repNotify, which will update to all relevants clients when possible, however I am having troubles adding the particle system to the user. What would be the workline behind this, like spawning the actor (or particle?) on the server → getting the reference → adding it to the array of auras … or would I need to multicast the particle (if so how would I force delete it from the view of all clients when required, etc). Sorry, still learning particles/emitter and seems quite confusing.
Regards

bump!
also wanted to add that the particle on player “A” should be seen even if a player “B” logs in after the player"A" applied his buff, hence seeing the particle effect… RepNotify was no success doing this. I could do it with multicast, but then player “B” wouldnt see the particles on player “A” if he logged in and the player already had the particles/effect up :

merci-

When you use the word aura, what do you mean? A visualization that there is a buff running? That’s what it sounds like, while aura in games tends to mean that other characters can get affected by them.

So I have not done anything like this myself but I decided to give it a try. The focus will be on having an array of buffs and visualize each buff with a particle effect.
It turned out to be quite tricky. Here’s what I have so far:


First of all here’s a simple example.
In this concept there is only one buff in the game. Each buff would require its own variable.
This is just to show how one could spawn or destroy (or enable or disable) particle effects on the clients.

The above is not very practical. We want to use an array. Here is when it becomes difficult to help you. I have no idea what your buffs system looks like or how much control you are willing to give to the clients when it comes to potential cheating. And there is one thing I have noticed.
The repnotify for an array does not fire for the server as it does for a replicated variable.
In order for both the server and the clients to receive the same behavior the repnotify simply calls a function with the logic we want to use, and that function is called by the server directly when a buff is added:


(The thing to note here is that onrep only happens for clients)

And here are some things that I find tricky to solve:

  1. Adding buffs. If the array is replicated and on the repnotify we iterate through the array to apply buffs, then each time it is updated it will obviously also iterate through old buffs that we already have. Meaning, if you buff yourself with +2 hp, then cast another non-hp buff you will end up with 4 hp and double particle systems.

1.1. Trying to include a flag in the array to avoid “duplicates”, when a new buff is added, as it iterates it checks the flags. If the flag is true, skip it. If the flag is false, set it to true and spawn particle effect.
The problem here is that the server would be doing this too, modifying the array by setting the flag - meaning the replicated array is given to the clients with the flag set, so they never spawn the particle effect.

  1. Expiring buffs.
    When a buff expires, it is removed from the array with the appropriate logic. This will update the array to clients with less buffs than before. But they still have the particle effect running so how do we know when to delete it?

The challenge seems to be that replicating an array, you want players outside net cull distance or joining players to receive the entire array so they can spawn a particle effect for each buff. Yet when adding a buff, don’t want to repeat the old ones.

So I made this setup that is at least working. But it is not pretty.
There are some things to keep in mind. The buffs are very basic, I don’t know what yours looks like. The buffs are also just a name variable, since I use data tables which is holding all the data. The way I set it up assumes that you want the server to handle the modification of stats and the clients only gets to do FX. Importantly, I am not sure if I would use this setup if you want the clients to handle the buffs.

So, the setup:


(obviously the remove buffs event would need more work in practice but as far as disabling fx, this is enough).
The client sends the buffID they wish to apply to the server.
The server adds the buff to the array, causing it to update to clients. The server then performs whatever logic is needed to apply the buff values to variables. I my case simply:

Now to the heart of the problem. The client will receive the updated array without knowing if buffs were added or removed. (or even modified, but that is not taken into consideration here).
So we store the particle systems in a struct together with the buffID, in an array.
Now when the repNotify happens, we compare each buff in the new array to each particle systems array.
If there is a match, that particle system has already been added to the list and we don’t have to do anything. We set a flag and break the latter loop.
If there is not a match, that’s a new buff and by getting the buffID, get the particle system corresponding to that buff from the data table, and add it to the array.

  • I now notice there should a node after TRUE of the branch, setting the bool “match” to false for this to work correctly.

But another possibility is that a buff was removed. If that is the case, we will not detect the particle system that lingers in limbo using the above loop. We also need to compare each particle system to each buff.
If there is a match, the particle system has the corresponding buff running, so we can set a flag and break the latter loop.
If there is not a match, there exists a particle system that does not have a buff running. That particle system needs to be removed.
Now, because we can’t delete elements from an array while it is looping, we need to add its index to another array, practically marking it to be removed.
When all that is done, we loop through the marked indexes, delete the particle systems and removes the index.

To save on loops, you could first check which array is longer and run the appropriate system instead of both.

Using this, clients and server see a particle effect when a buff runs.
Only one particle system per buffID is spawned (even if there in this setup is no limit on actual buffs of the same buffID).
If clients are out of net cull distance, when they get inside net cull distance a particle system is spawned for each buffID.

Hopefully someone who worked with changing replicated arrays can give some pointers on how to do this better. well, I hope it helps even if its just a little bit.

Hi!

For some reason the SpawnParticleAttached doesnt work when I use it on the playercharacter’s server side (I guess I’ll try spawning from the controller’s server side like you did), which kinda killed the idea I had, which was setting the particle to replicate (in theory it wouldve worked), since if you add a ParticleComponent to the character, that particle is replicated automatically and works fine. When I tried the repNotify [spawning the effect there] it worked for all players connected, however when the user “A” had the buff up (hence an aura), the new user “B” that logged in couldnt see the aura user “A” had.
On the last picture/example, do you have something in On Rep Buffs (maybe something similar as the first example?)

Thanks for the help and the bps :slight_smile:
Oh, and what I have is something similar, just a buffsystem array (which was onRepNotify) and depending on the buff I was just spawning the particle on the RepNotify, and when changes were applied (set to 0) i would simply remove it.

Edit: seems like spawning particles on server-side is a no go :p, always returns “Accessed None blabla”, I guess I will need to spawn on the clientside and have a replicated variable with the particle reference so I can later delete it from the clientside.

It’s the same as the first example, the repNotify just calls the Buff Change Function.

I see you mentioning the server having trouble spawning particles twice. There’s a bug where RepNotify won’t be called on the server, that’s why the second picture in my first reply looks as it does, to go around that. Could that be the cause? Use a print string and see if the server says hello.