x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Could I get some help understanding Roles and some issues with server RPCs?

I'm working on replicating a weapon class and using ShooterGame as an example, but I'm running to some issues and I wanted to see if I could get some clarification on what the proper roles for each party should be. In the examples you see things like:

 if (Role < ROLE_Authority)
 {
     ServerCall();
 }

The only problem is that this isn't working for me, because when I run from the editor both the listen server and the client are running as ROLE_Authority. If I check into RemoteRole it says that it is ROLE_SimulatedProxy. Which seems completely backwards based on the examples.

The reason I bring this up is because I'm trying to wrap my head around why this isn't working at all for me, and I have a feeling that whatever I'm missing is causing the roles to be wrong. My issue is that client -> server calls aren't working at all. I tried changing my code to do something like this:

 if (GetNetMode() == NM_Client)
 {
     ServerStartFire();
 }

And verified that it was executing that block, but it still doesn't seem to execute ServerStartFire_Implementation.

That being said, the replication from the listen server to the client is working fine. So, in my case, I'm able to see the shots replicated on the client, but not the other way around.

Thanks!

EDIT

I tried to start over with a new Actor to see if I could have done something wrong while implementing my weapon class, but the problem still exists here. Here's the code of the new class:

Example.h

 #pragma once

 #include "GameFramework/Actor.h"
 #include "Example.generated.h"

 /**
  * 
  */
 UCLASS()
 class AExample : public AActor
 {
     GENERATED_UCLASS_BODY()

     UFUNCTION()
     void Call();

     UFUNCTION(Server, Reliable, WithValidation)
     void ServerCall();
     
 };

Example.cpp

 #include "Mach.h"
 #include "Example.h"


 AExample::AExample(const class FPostConstructInitializeProperties& PCIP)
     : Super(PCIP)
 {
     bReplicates = true;
     bAlwaysRelevant = true; // Had to add this because it was complaining about no root component
 }

 void AExample::Call()
 {
     UE_LOG(LogTemp, Log, TEXT("Example Call"));

     switch (Role)
     {
     case ROLE_None:
         UE_LOG(LogTemp, Log, TEXT("ROLE_None"));
         break;
     case ROLE_SimulatedProxy:
         UE_LOG(LogTemp, Log, TEXT("ROLE_SimulatedProxy"));
         break;
     case ROLE_AutonomousProxy:
         UE_LOG(LogTemp, Log, TEXT("ROLE_AutonomousProxy"));
         break;
     case ROLE_Authority:
         UE_LOG(LogTemp, Log, TEXT("ROLE_Authority"));
         break;
     case ROLE_MAX:
         UE_LOG(LogTemp, Log, TEXT("ROLE_MAX"));
         break;
     }

     ServerCall();
 }

 bool AExample::ServerCall_Validate()
 {
     return true;
 }

 void AExample::ServerCall_Implementation()
 {
     UE_LOG(LogTemp, Log, TEXT("Server call implementation"));
 }

Then in my Character class I added the following in PostInitializeComponents:

 FActorSpawnParameters SpawnInfo;
 Example = GetWorld()->SpawnActor<AExample>(AExample::StaticClass(), SpawnInfo);

And then added the call in OnStartFire which is bound to Fire:

 Example->Call();

Here's what the logs show:

 [2014.05.23-22.54.30:644][551]LogTemp: Example Call
 [2014.05.23-22.54.30:644][551]LogTemp: ROLE_Authority
Product Version: Not Selected
Tags:
more ▼

asked May 22 '14 at 01:21 AM in C++ Programming

avatar image

tosslogic
88 8 10 14

avatar image [Epic] John Pollard STAFF May 23 '14 at 06:33 PM

That seems strange. Only the server should have the Role == ROLE_Authority, and RemoteRole should be ROLE_SimulatedProxy/ROLE_AutonomousProxy.

When the client spawns the actor, it will reverse the roles. So Role should should be ROLE_SimulatedProxy, and RemoteRole == ROLE_Authority.

Is this not what you are seeing?

avatar image tosslogic May 23 '14 at 10:18 PM

Well, that's essentially the problem I'm facing. Unless I'm doing something completely wrong, the roles seem to be swapped. RemoteRole is set to ROLE_SimulatedProxy and Role is set to ROLE_AutonomousProxy.

I could send you the whole cpp and h file if that'd be helpful.

avatar image tosslogic May 23 '14 at 10:58 PM

Updated with a full example showing the issue.

avatar image [Epic] John Pollard STAFF May 23 '14 at 11:04 PM

Role being ROLE_Authority on the server is correct. Are you saying you see both client and server printing this message? If you are using PIE this can happen, and you are just seeing the server output in both windows. If this is happening on two instances separately spawned, you should only see the message on the server (since this is a server call).

avatar image tosslogic May 23 '14 at 11:10 PM

Hi John, thank you for your help. Unless I'm misunderstanding, the logging the role is happening on the client, since I do that before calling ServerCall. Is my understanding incorrect? In either case it looks like ServerCall_Implementation is never getting executed, because the log line is never printed. This is the issue I'm experiencing that lead me to realize that the roles seemed backwards. Also, wanted to point out that I am running this from the editor with dedicated server checked.

avatar image [Epic] John Pollard STAFF May 23 '14 at 11:13 PM

I'm sorry yes, you should only see it on the client in that case, and that is odd that it is authority on the client.

How is this actor being created on the client?

avatar image tosslogic May 23 '14 at 11:16 PM

In this example I'm creating it in the character class in PostInitializeComponents:

 FActorSpawnParameters SpawnInfo;
 Example = GetWorld()->SpawnActor<AExample>(AExample::StaticClass(), SpawnInfo);

My weapon class is actually added through the blueprint editor, though. Both cases exhibit the same behavior.

avatar image [Epic] John Pollard STAFF May 23 '14 at 11:30 PM

That might be the problem. You are trying to send an RPC using an actor that was created locally on the client.

To send RPC's from client to server, the actor used to do this must either be a part of the level, or have been spawned on the server, and then replicated to the client. It's generally not safe to directly spawn actors on client unless you know you only need it on that client.

In this case, you could wrap a if ( Role == ROLE_Authority ) check around that spawn so it only spawns on the server initially only. Then make sure Example is a replicated property (UPROPERTY( Replicated ) above the property declaration).

You also need to make sure Example is marked to be replicated as an actor either be setting bReplicates to true in Examples constructor, or calling Example->SetIsReplicated( true ) after the server spawns it.

One last thing, you need to make sure to add the Example property to the GetLifetimeReplicatedProps function.

Now on the server, you should be able to call RPC's on Example that get replicated to the copy the client has.

avatar image tosslogic May 24 '14 at 03:51 AM

Yes, thank you! That was the problem. So, making sure the authority was the only one creating the actor in the first place fixed the issue. Thanks!

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Try if(HasAuthority())

more ▼

answered May 22 '14 at 02:51 AM

avatar image

Acren
460 46 50 70

avatar image tosslogic May 22 '14 at 06:23 PM

From the source, this does return (Role == ROLE_Authority);. Shouldn't the actor on the server have ROLE_Authority? Right now, this will get triggered on the client.

avatar image Acren May 23 '14 at 02:08 AM

Yeah, the server will have Authority. If you want to run client specific code, use if(!HasAuthority()) :)

I haven't used much code for networking, I have prototyped most of a networked game in blueprint though, so I'm familiar with the concepts.

In my game, there is pretty much no "client only" code. Even client calls to the server for things such as fire input just go through a "Run on server" replicated function on the controller, so that listen servers can use the same code.

What I do check for is ownership of the controller with IsLocalPlayerController() before sending input, otherwise I get input from the server player completely overriding the client input of that controller.

avatar image tosslogic May 23 '14 at 02:12 AM

Well, the problem is that in my case the client is set to ROLE_Authority. I've verified that it's running as a client using GetNetMode(), and verified that the meshes are replicated, this seems to be working fine. But, my custom actor specifically seems to have roles swapped. I'm thinking there's some definition or call I'm missing to set the roles correctly, but I'm not sure what and the documentation is really lacking.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question