How to solve networking in spell system?

Hello.

I’m creating a battle arena style game from the third person perspective. Since I’m new to UE4, I decided to start with creating basic features before trying to do implement the multiplayer features. As you probably guessed, this was a horrible idea.

Now that I’m trying to implement the whole server/client structure to ready implementations, I’m utterly stuck. I’ve now used about 16 hours viewing networking tutorials and reading documentation, yet I’ve not discovered how to practically implement it in my case.
I’m looking for help with my spell cast system (spells are referred as artifacts in my game). I hope that when I clear this out, I can figure out how to refactor the rest of my project to support multiplayer myself.

Currently, the server side seems to show everything correctly. When playing with the server pawn, the cooldowns, cast times and artifacts themselves work correctly. Also, when playing with the client pawn, the artifacts seem to spawn and work properly in the server window, however, the cast times and cooldowns do not work.

The things that I don’t understand happen in the client side window. When I cast an artifact projectile with either the client pawn or sever pawn, they move in weird directions with either very fast or very slow projectile speed. However, artifacts that spawn in a target location work also in the client side.

In short:

Client side window:

1. With server pawn: Artifacts spawn but travel very slowly and weird directions. The pawn also does a weird jumping animation.

2. With client pawn: Artifacts spawn but travel usually very quickly and weird directions. Cooldowns and CastTimes are not working.

Server side window:

1. With server pawn: Everything works correctly.

2. With client pawn: Artifacts work correctly, however, the cooldowns and CastTimes do not work.

Below I’ve provided pictures about my current ArtifactCasting system located in the character blueprint. There I have just thrown the server custom event in the middle and I don’t have an idea how it should be properly implemented.

Maybe if someone could shed some light about their thoughts on following matters:

  1. Should server know about players cooldowns?
  2. Should server know about players casting a spell? This is probably yes, if I want to show the cast animation to other players, right?
  3. What is the proper way to call a function if it comes from a client and I want the server to know it and then announce it to all other clients as well? Isn’t this the fundamental I’m trying to achieve? “Client checks if he can cast a spell → if yes → tell server that this client wants to cast a spell → server casts the spell and lets everybody know about it”?

The server should not only know about the cooldowns, but the server should be the one controlling cooldowns, spawning, spell movement, and everything to do with spells except for effects. The client side should access this stuff, using it for the effects that you apply to your ‘Artifacts’.

The server should be where the game is played, it knows about everything except for your UMG’s and Effects.

The client is like input to the server, it tells the server it wants to do something, then the server decides what should be done about it. So if you push the attack button, you send an RPC to the server to request an attack action. If successful, then it notifies the client.

Thank you for your answer, truly!

However, I have some follow up questions regarding it. Is there a reason why should server handle all the cooldowns of artifacts (other reason than possible cheating issues)? Isn’t this exactly the thing that client just needs to check first whether he can cast an artifact and then ask the server to do it?

I think the thing that keeps me from getting forward is that I don’t know how to access the specific character that asked to cast the artifact from the server… In other words if a client sends RPC to the server that he wants to do an attack command, how do I do the action from the server that the specific character does it (and change some character values according to it?).

Because earlier I tried to do things in following sequence:

  1. Client calls a custom event that says “hey server, I want do shoot a fireball (Run on server)”
  2. Server is like “ok calm down dude, I’ll cast it for u” → the following nodes from custom event tries to get actor properties to set up the casting and then spawn the artifact and do all the stuff that the artifact should (Picture 1)

However, it just doesn’t seem to work. The clients cast the fireball in 0,0,0.
If I want to set some character valuables from the server, do I need to use “cast on the owning client” custom events like I currently am (Picture 2)? Or is this false way to do it?

To clarify, I’ve managed to get to a point where the cooldowns and casttimes (Widget doesn’t show up for the client for some reason though) work properly also from the client pawn. The artifact projectiles still fly in awkward directions in the client window (but run correctly in the server).

Thanks again for the answer and I hope you get what I meant with these further details. I’m looking forward hearing from you!
Cheers,

Does someone have an idea why artifacts that should move somehow in my game appear wrongly in client windows?

I tested by setting the ArtifactParent replication to none, which did what I assumed, so now only the server window saw what’s really happening on the screen. Then I set that to replicate and now all the clients saw the artifacts spawning in their screens also. However they moved to weird directions. Next, I set the replicate movement to true. This check box doesn’t affect to how clients see things…

This seems to be the major issue in my blueprints currently. I’ve provided two pictures, one of which shows the correct working of an artifact in all windows (RingOfFire). While the other one shows how artfacts doesn’t seem to replicate the movement correctly (RocketLauncher).

What could be wrong?

“Is there a reason why should server handle all the cooldowns of artifacts (other reason than possible cheating issues)?”

Security is the main reason. Another reason might be if you want players to know about other players’ cooldowns and show them in the UI or something like that.

“Isn’t this exactly the thing that client just needs to check first whether he can cast an artifact and then ask the server to do it?”

Ideally, you’d do the check twice. Once on the client to check whether there’s even any point in asking the server, and a second time to make sure the client didn’t cheat.

“I think the thing that keeps me from getting forward is that I don’t know how to access the specific character that asked to cast the artifact from the server… In other words if a client sends RPC to the server that he wants to do an attack command, how do I do the action from the server that the specific character does it (and change some character values according to it?)”

You can parameters to the server events same as for all other events. Just pass your character as well as any other needed information through to the server. Alternatively, you could define the function in the character casting the spell or somewhere where you can easily access the character (such as a character component).

The projectile needs to be spawned on the server. Make sure that the class is marked as Replicating.

Hey, Thanks for your insights!

I’ve defined the whole casting system in the character blueprint. However, it won’t work if I don’t send everything as parameter to the server. Say, my character has a variable “bombCount”. Then if I send an event to a server which then calls a function from character blueprint which decrements the “bombCount”, it won’t work. The server does not know which “bombCount” to decrement then (I guess). So should I always send the casting character to the server also so it knows whom’s variables it should use or do I keep calling everything twice, once in server and once on owning client?

My projectiles are spawned on server, and the class is marked as replicate (as I said, they do appear on client windows). However, the projectiles movement ain’t working. It shoots itself to random directions. My projectiles move themselves on event begin, could this be the issue that it haven’t spawned yet on the client window?

Oops my bad. I mean the projectiles move themselves on their inheritated “CastMe” function, which is called after the projectile is spawned as shown in original post, last picture

I’ve managed to hunt down the fault which was the reason projectiles didn’t work properly on client windows. They did spawn on the server, however the “CastMe” inherited function which is called right after (function of ArtifactParent, which all children specifies), didn’t get called in client’s end. Or to be more precise, the function wasn’t replicated to clients even the server called it. I was able to find this issue by giving a spawning artifact a 0.5 sec delay before movement and noticed that the 0.5s before movement looks on server exactly the same as it does on client’s window all the time. Then I realized that it must be the “CastMe” function.

Now that I put that on multicast from the server side, it did start to work also in clients windows, but now server called that custom event twice somehow (I really don’t know why all artfacts from server pawn moved twice as fast). However, DoOnce node fixed that for me…

Now there are some random issues, like every 10th artifact cast on client still travel weird directions :confused: Setting the custom event which calls CastMe to “reliable” breakes everything… Why can’t I demand for it to be reliable?

All in all, I’m pretty close to solution. Now I need to get the HUD widget to show.

If someone could still shed some light why reliable calls on CastMe function breaks everything (multicast), but most of the time everything works if I set that to unreliable. After that, I think we can set this question to resolved :slight_smile:

Here is gif which shows that everything seems to work. Maybe the blast radius is a bit in desync, but well yeah, I think I’ll manage. GIF | Gfycat

To clarify my final question:

  1. I spawn a replicated actor in the server.
  2. I call a function which moves this spawned actor. However, if I call it only at the server, clients won’t see the movement (even the actor is replicated -.-), but if I multicast the movement function, it works.
  3. If I set the multicast function to reliable, it won’t work on clients side. The movement is unpredictable and 10x faster. Why?