Can't get my replication working right

I can’t seem to get my replication working no matter how I try it. I’ve reviewed the tutorials and docs and I think I’m doing it correctly, but I guess I’m missing something. All I’m trying to do is get a number created, then increment it across all clients when I click a button. I have the variable replicated, and the BP set up to read the value from the class, but each client is maintaining it’s own value of the variable instead of using the same value.

Could somebody please take a look and tell me what I’m doing wrong?

GC_Character.h:

UCLASS()
class GALACTICCOMMAND_API AGC_Character : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	AGC_Character();

	UPROPERTY(Replicated, BlueprintReadOnly)
		int32 numPlayers;
	
	UFUNCTION(Server, Reliable, WithValidation, BlueprintCallable, Category = "GC_Server")
		void loginServer();

	UFUNCTION(Reliable, NetMulticast, BlueprintCallable, Category = "GC_Client")
		void updateNumPlayers(int32 num);
};

GC_Character.cpp:

#include "GalacticCommand.h"
#include "GC_Character.h"


// Sets default values
AGC_Character::AGC_Character()
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	bReplicates = true;
	bAlwaysRelevant = true;
}

void AGC_Character::GetLifetimeReplicatedProps(TArray<FLifetimeProperty> & OutLifetimeProps) const{
	DOREPLIFETIME(AGC_Character, numPlayers);
}

void AGC_Character::loginServer_Implementation(){
	numPlayers++;
	updateNumPlayers(numPlayers);
}

bool AGC_Character::loginServer_Validate(){
	return true;
}

void AGC_Character::updateNumPlayers_Implementation(int32 num){
	numPlayers = num;
}

Here is the BP that calls LoginServer and updates the text box:

I think I may have found the issue. I debugged the blueprint for my character and I think the issue is not so much with replication as with misunderstanding how replication works. In the above case, each instance is creating it’s own character object for each player. This means that when I update the numPlayers value, it’s only updating it locally for each character in each client. Basically, I’m treating it like it’s static when in fact that value is still instanced, just on each client. Will provide a solution for what I’m doing wrong when I figure it out.

Edit:

Got this working as expected. I had to use a static variable, which is fine because that’s what I was really trying to do anyway. I couldn’t straight replicate the static variable as I might have liked because that causes a crash in UE4. I suspect is has something to do with how the magic of DOREPLIFETIME works behind the scenes, since I think I remember reading it’s only called once per class.

My new code:

class GALACTICCOMMAND_API AGC_Character : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	AGC_Character();

	static
	UPROPERTY(BlueprintReadonly)
	int32 staticNumPlayers;

	UPROPERTY(Replicated, BlueprintReadOnly)
		int32 numPlayers;
	
	UFUNCTION(Server, Reliable, WithValidation, BlueprintCallable, Category = "GC_Server")
		void loginServer();

	UFUNCTION(Reliable, NetMulticast, BlueprintCallable, Category = "GC_Client")
		void updateNumPlayers(int32 num);

	UFUNCTION(BlueprintCallable, Category = "UI")
		int32 getNum();
};


**************************************************************************

int32 AGC_Character::staticNumPlayers;
// Sets default values
AGC_Character::AGC_Character()
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	bReplicates = true;
	bAlwaysRelevant = true;
}

void AGC_Character::GetLifetimeReplicatedProps(TArray<FLifetimeProperty> & OutLifetimeProps) const{
	DOREPLIFETIME(AGC_Character, numPlayers);
}

void AGC_Character::loginServer_Implementation(){
	numPlayers++;
	staticNumPlayers++;
	updateNumPlayers(staticNumPlayers);
}

bool AGC_Character::loginServer_Validate(){
	return true;
}

void AGC_Character::updateNumPlayers_Implementation(int32 num){
	staticNumPlayers = num;
}

int32 AGC_Character::getNum(){
	return staticNumPlayers;
}