Networking Chest Loot

Hello! I’m doing a Multiplayer Game RPG Client-Server (with c++).

I’m having problems with the structure of the networking chest. This chest generates a different loot per client. So, if this chest is in Server, how every client will have different variables/loot?

The interaction with the chest works but the loot is not spawning right now. I want every client will see only his/her loot. Here! There is another problem. I can’t spawn in Client because CHEATS! (I think they can cheat the spawnable loot). So the unique place is in Server, but… How 1client will see the loot and interact with?

You should always control the loot generation on the Server, and ultimately the Server should be adding the items to a replicated inventory if that’s what you need to do. You can call a Client RPC on the affected client to spawn their own version of the actors client-side if this is just a visual-only thing.

If you need to call RPC’s on those ‘Loot’ objects or if they need to be replicated, then you’ll have to spawn them on the server and come up with your own way to make them invisible for other clients.

You can override ‘Is Network Relevant For’ in the loot actors as a starting point:

virtual bool IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget, const FVector& SrcLocation) const;

I don’t know how but i did it! In Blueprint, because it’s easier to try things.

The chest call a Multicast Function from PlayerController. This one spawn the loot (in C++ i will use UWorld::SpawnActorDeferred to pass the PlayerController as variable) and the loot must change itself if it is in the correct client or in the server. The Server will interact with the loot… the SERVER MUST interact with it.

Any suggestions? ^^


Read this:

I was writing the code… and I had an error when I wrote in PlayerController the SpawnFunction (RELIABLE MULTICAST). Only it works if it is unreliable. So if you want to use a Reliable Multicast, the function must be in the Game State.

When I started to pass the functionality to code, I described that what I had done in Blueprints is not valid. Because the Loot when you approach moves to the player (the SetActorLocation is done in the tick of the Loot). I have to replicate it.

So, instead of being a multicast function that creates the objects, it is one on the server. With the Owner and the PlayerController I can know if the Loot is in the correct client.

Unfortunately the movement does not do it well. I repeat the object and its movement, but it does not move fluidly in client than in server. Surely it is for the refresh of the Net. So I tried to remove the bReplicateMovement and client and server move the object in their tick, but then the object is not seen in the client. Why??
The RootComponent is a SceneComponent. And the Loot has a StaticMeshComponent.

When the Loot is not the correct client, I hide the actor. As the server first creates the object, the correct client returns to show the Loot.
I need help with the movement of the Loot. Or with the tick or with bReplicateMovement.



  • Create the Loot Actor with a ProjectileMovementComponent.
    — bReplicate = true
    — bReplicateMovement = true
    — Set false (in blueprint) the: InitialVelocityInLocalSpace.
    — The actor will move with the variable VELOCITY of the ProjectileMovementComponent. The <<set>> is only in the server.
    — virtual void PostNetReceiveVelocity(const FVector& NewVelocity) override; (( to set the VELOCITY ))

  • The Loot Actor has as variable a PlayerController
    — To discover if this actor is in the client or client-server o server, I used the GetOwner() and the PlayerController variable and UGameplayStatics::GetPlayerController(this, 0).

  • The chest, in the server, will create the Loot Actor. You can use a RPC function in the chest (if the chest is a replicated actor) or PlayerController or GameState. The function is a Server Function.
    — That function will pass to the Loot Actor the PlayerController than touch the chest. That PlayerController will be the Owner and the PlayerController variable (set it in the function). I used a deferred spawn (( UGameplayStatics::BeginDeferredActorSpawnFromClass(…) )).

And that is all.