Spawn an actor doesn't replicate if spawned by another blueprint

To do it way I described initially, which is more efficient and more secure, your ABaseBolt would exist in level or be spawned by Server. It would be owned by Server. Client Character would ask Server to spawn projectiles using an RoS RPC, as you would normally. It really is as simple as two images I posted for that solution.

You mention needing lots of custom information for each player, and that being reason behind wanting a Client owned ABaseBolt. Instead, you can collect information for Client’s spells on a Client-owned class, such as Character or Player State, and then pass that information to ABaseBolt through RPC that calls spawn event. That way anything spawned by ABaseBolt on Server will have get all information it needs to make it unique to player. This is similar to how you used GetSpawnProjectileTransform information and passed that to spawn projectile functionality. It’s going to be unique to your game, so I’m not really able to come up with exact answer you need, but that’s basis of it.

I don’t quite understand it but I will do as you said :slight_smile:
thank you very much

If you want to use Run on Server RPCs, they need to be called from an Actor that is owned by Client. You can’t set ownership on an Actor unless it is set to Replicate. If you plan to follow this course, you would need to spawn ABaseBolt (as you already do), but only on Server. That will be set to Replicate, so setting Owner through Owner pin on Spawn Actor from Class node will work. Otherwise, this whole setup will not work.

way UE4 handles network is with Server/Client model. This means majority of actual gameplay decisions are made on Server and then communicated to Clients. Anything important enough to be communicated to all players should therefore occur on Server.

Sometimes you’ll want to have Client do something that affects world or other Clients, but Client itself can’t do that, because information does not flow from Clients to other Clients, and in most cases does not flow from Client to Server. In this case, using an RPC on a Client-owned actor (such as Character) that is set to Run on Server will communicate desired change to Server, which can then perform desired action and replicate that change to all Clients.

Since ABaseBolt is attempting to spawn a projectile, which will be visible and affect all Clients, it needs to do this on Server. In order to have Client ask it to talk to Server to perform this action, it needs to be owned by Client.

Anything owned by Client can conceivably be adjusted by Client. So all that information (effects, damage, whatever you have in there) can be adjusted without Server’s permission. If done locally, this won’t affect anything: we don’t care what Client is doing on its end if it doesn’t affect other Clients. Over network, however, this can be super bad.

part that’s confusing you is event that you’re attempting to Run on Server. problem is that Run on Server won’t work, because Client can’t tell Server to run something if it doesn’t own Actor making request. So it’ll happen on Client machine, but Server never gets request and thus Server and other Clients never see event occur.

To fix this, all you need to do is set ABaseBolt ( Actor spawning projectile) to Replicate (so that any change to it, such as a change in ownership, is replicated to all Clients). Then, if Server is one that spawns this Actor (rather than Server and all Clients, as you had it originally), it can change ownership on Actor’s instance to appropriate Client. Then, voila! Client owns its instance of ABaseBolt, and can ask Server to run spawn projectile event on its instance.

I think that I finally get it.

basically whenever I want to run a function on server, blueprint that contains that call and everything used by it need to be replicated otherwise server cannot make it’s own version of it.

I still have a doubt if you mind but I’m really gratefull for you assistance and if you think that I wasted too much of your time feel free to drop this conversation! I totally understand it and you absolutely did far too much! thanks!

  1. let’s say that I make a variable on a player controller, then set it replicated. Then I change it from client instead of using server. being replicated server will update it’s value too. (just like other way around)

  2. so if I spawn a replicated actor from a client, server will know that there is an additional actor (cause it is replicated), but It will not display it cause it didn’t run spawn method itself.

  3. so If I spawn a projectile, make it replicated, nobody will actually see projectile unless they run same spawn method themselves.

  4. so I tought that everytime I run a function on server, server will first run it, and then also all clients will also run it.

Now this can’t be true, cause If I remove “run on server method”, and directly call spawn method, if I do that on Player listener CLIENT WILL SEE THAT TOO! so client didn’t run it’s own version of method! I presume it can see projectile just cause it is replicated!

and this drives me insane, does it means that a replicated variable can only be edited/created by server? if a client try to spawn something replicated it will just be treated as something not replicated?

btw
I tried to make ABaseBolt and ASuperSpell as replicated and they still do not works (sadly in meantime I rewrote it as a component). if you can spare a look ^^ https://onedrive.live.com/redir?resid=243D556470911B2F!111421&authkey=!AO4MQb-7VFroc1U&ithint=file%2C7z

This is where networking and replication starts to get tricky, and takes a lot of forethought.

So when you run spawn event on Server, it creates that Actor on Server. If that actor is set to Replicate, Server will also tell each Client that actor exists, and so Clients will see it.

Similarly, if you use an RoS RPC to have Server spawn actor, Server is still doing all that work (except on requesting Client, because that work has already been done by that particular Client).

If, as you describe above, all Server and all Clients attempt to spawn an actor, they will EACH spawn an actor. So if your Character Blueprint attempts to actor without any network consideration, there will be an instance on each Client that only those Clients can see, as well as one on Server for EACH Client that attempted to spawn. Remember that Character actor, like most actors, exists on Server AND on Client.

That leads to many instances of same actor, some of which are set to properly replicate and some of which aren’t, depending on who spawned them. Additionally, depending on how you set your references, if you attempt to reference spawned actor, you may be referencing incorrect one.

This can obviously cause a lot of confusion. That’s why it’s generally better to let Server do its job, which is to run game for Clients and communicate all important information (such as projectiles, damage, health, etc) to Clients.

And yes, that’s correct, re: replicated variables. Remember that all communication happens from Server to Client or Server to all Clients, and not from Client to Server (except when using a Run on Server RPC). It won’t matter if a variable is replicated if you attempt to change it on Client.

I’ll take a look at your updated project when I get a chance, and let you know why it’s not working.

You’re still not spawning ABaseBolt with an RoS event.

Instead of using LoadSpells function in SpellCasterComponent, use an Event so you can make it an RPC. Then you can follow same setup as shown in images above.

I have to be honest, this is way too strange!
I will not be able to sleep for weeks if I use this approach but it works now. thanks :slight_smile:

so much useful info in one thread, it could be included in docs as an example, Thank You!

1 Like