NetMode and Role mismatch

Hey guys,
I’m currently trying to use a ChildActorComponent to spawn an actor when my pawn is spawned.
However, first of all the server never creates the Actor I specified in the CAC. (I log the PostBeginPlay() to see who actually spawns it) [My workaround for this is to replicate the spawned actor, so it’s currently spawned by replication …]
Next: I check for the NetMode in the following example, which always returns to be a client, but when I check for the Role right after, it’s always ROLE_Authority:

//Function is being called on the client when LMB is pressed
void ASomeWeaponClass::startFire()
{
	TRACE("");
        ///Trace output:  [Client] ASomeWeaponClass:startFire() :
	if (Role < ROLE_Authority)
	{
                ///// I NEVER GET HERE 
                
		TRACE("Role < ROLE_AUTHORITY");
		serverStartFire();
	}
}

with TRACE(“”) being:

#define NETMODE_WORLD (((GEngine == NULL) || (GetWorld() == NULL)) ? TEXT("") \
	: (GEngine->GetNetMode(GetWorld()) == NM_Client) ? TEXT("[Client] ") \
	: (GEngine->GetNetMode(GetWorld()) == NM_ListenServer) ? TEXT("[ListenServer] ") \
	: (GEngine->GetNetMode(GetWorld()) == NM_DedicatedServer) ? TEXT("[DedicatedServer] ") \
	: TEXT("[Standalone] "))

#if _MSC_VER
#define FUNC_NAME    TEXT(__FUNCTION__)
#else // FIXME - GCC?
#define FUNC_NAME    TEXT(__func__)
#endif

#define TRACE(Format, ...) \
{\
	SET_WARN_COLOR(COLOR_CYAN); \
	FString Msg = FString::Printf(TEXT(Format), ##__VA_ARGS__); \
	UE_LOG(GeneralLog, Log, TEXT("%s%s() : %s"), NETMODE_WORLD, FUNC_NAME, *Msg); \
	CLEAR_WARN_COLOR(); \
}

I’m glad about every idea/help!
Thanks in advance!

Sounds like you’re spawning the weapon on the client instead of on the server. Can you show the weapon spawning code?

Sure!
This is Code I use to spawn that: (As I said, via the ChildActorComponent:)
In the .h file of my pawn:

	UPROPERTY(VisibleDefaultsOnly, Category = Weapon, replicated)
	TSubobjectPtr<class UChildActorComponent> SomeWeaponCAC;

.cpp:

(in the constructor of my pawn)

SomeWeaponCAC = PCIP.CreateDefaultSubobject<UChildActorComponent>(this, TEXT("Weapon"));
SomeWeaponCAC->SetIsReplicated(true);
SomeWeaponCAC->SetNetAddressable(); // Make DSO components net addressable

(I set the class to spawn in the BP of my pawn)
The CAC should spawn the Actor itself right? And as that Component should exist on every side … wait does it?
Does the Child Actor Component exist on the server as well?

I might be wrong, but my understanding is that ROLE is a property of an Actor while NetMode is a property of the System on which the code is running.

ie if NetMode of a particular machine is always the same no matter where you call it in the code. But ROLE changes with each Actor and depends on who owns the actor.

So the netmode of a client PC in network game with dedicated server is always NM_Client. But if the server is hosted by one of the players, then his netmode will be NM_ListenServer etc…

In your case, no matter where Actor is spawned, if you print out the value of NeMode from a client machine, it will always be NM_Client. But you said you had ROLE=Authority on the actor. So it sounds like the Actor was spawned from the Client machine and is owned by it.

To make sure you can write a function and call it from server an client and see what ROLE is in both cases.

Well the question now is … Does a Child Actor Component spawn the Actor on the server as well? Does it even exist there? As in my example it doesn’t really do anything on the server and therefore my Actor doesn’t exist on the server and that’s why it prints ROLE_Authority and Netmode_Client as it is indeed spawned on the client (apparently) and therefore the server isn’t the “real” authority (as intended)…

Unless you mark the Actor for replication, an Actor spawned on Client is not created at server. So this could be true for ChildActorComponent as well.
A ChildActorComponent object stores the actual ChildActor as one of its members I think. SO perhaps the component was replicated at server, but the Actor bound to it may not. This is just an assumption.

One way to test this would be to print out the values of ChildActorComponent and ChildActorComponent->ChildActor. See what they show in Server and Client.