Help Understanding Replication

Not sure if this has been asked before, so I apologize if its re-occuring. I understand how replication works and when its necessary very much so, but I am having trouble understanding why certain variables or info on the client cant be sent to the server, and why things created on the server cant seem to be sent to all clients unless its the owner.

In my game I need the server to receive the 1st person camera rotation from the client so that certain movements can be seen by other players that goes beyond just movement being replicated (where the eyes of the characters are looking and head rotation). Its very important since its a huge way to bring the player’s character to life online. The rotation variable wont be recognized by the server; however, it just nulls to 0 on all fields (but the client works fine). I’ve tried to run a variable on the server that is based on the camera rotation, but it doesnt work either.

On the other end, I need clients on their HUD to know about global variables that the server is in charge of, such as player index numbers (whos player 0, 1, etc). If the server doesnt manage this, every player controller thinks it is player 0 because its not globally aware via the server that other players exist; but the server does. I need the HUD to be able to recognize who player 0 is and 1, etc so the right elements can display in the lobby menu and what not.

If this is me not understanding Game Modes and Game States and Player States, that would be understandable. If you got any sick or average ideas on how I could go about this, Id much appreciate it sirs

Okay, I am fairly new to Replication as well so bare with me. In short you don’t need to replicate your camera to get rotations for movement. I have the Controller and the Pawn handle that, I actually “TearOff” my camera manager so that the client has full control of it and it’s not constantly bugging the server to perform movements. Basically the camera follows the Controller’s rotation, and the pawn also follows the controllers rotation. The Controller is constructed on the server, and replicated to it’s owning client. If you have 5 players, the server has 5 pawns and 5 controllers. Each client has 5 pawns, 1 controller, and 4 player states. Each client is able to rotate and move their pawn on their clients, that is then sent to the server where the server updates it’s own version of the controllers, and that gets replicated back down to each corresponding client. Replication is fun… and I’m not entirely sure all that is right lol but it DOES work on my game.

Now about the player index numbers. For every client, their own controller is the only one that exists locally, the others have a player state. That is also why on the clients their player index is 0. The server on the other hand has each player’s player index starting with the controller that owns the game. As a side note the Game Mode only exists on the server as well, Each client recieves a Game State.

SO… if you want to have each client know what their player index is on the server store it in the Player State. However you probably shouldn’t need to do this because most replication handles what controller did what automatically. However I don’t know your reasons so that is about all I can say about it.

One of the most important things to remember is that “The Server is GOD”. If the client wants to change something, they must tell the server they want to do it, then the server performs the operation and notifies the client the operation happened either by calling a client function, or replicating the changed properties down to the client (in which you can trigger other events on the client using a RepNotify function)

I have ready countless articles and wikkies and asked numerous questions on replication and I still feel I know next to nothing on this subject…

Indeed, she’s a mysterious maiden of these lands. Your response articulated most of what I already knew, but it did raise some good points all in an organized form so I appreciate that. I can better describe what Im trying to accomplish though.

  1. Server needs to receive the player’s camera rotation, capsule rotation, and some other client side variables. These are important for applying slope and deformer values on the character I’d like other players to see, not just owning client.
  2. Need to know how one could actually store values to a player state such as Player Name. I think I could probably use this actor like any other actor with blueprint, but not sure yet. I wont be looking into this too deep until I get Steam SDK into my UE4 though.

Overall it just seems arbitrary on the blueprint side of things to know what variables are client only, or server only unless its obvious with a graphic on the node itself. I need somethings on the client end to absolutely be recognized by the server, or else my mechanics are broken and thus my games potential. I might end up having to learn more C++ so I can just go to the source and make it work how I need. For now Im holding off on replication specifics but designing with it in mind just for single player.

Question 1:

  1. Create some actor or pawn or character with bReplicate = true
  2. Add function like “SetCameraRotation” to that actor with “Server” option
  3. Add function body “SetCameraRotation_Implementation” with code

When client call “SetCameraRotation” with FVector param - UE call “SetCameraRotation_Implementation” on server with same param inside server version of actor.

Example:
Header:

UFUNCTION(Server, Reliable, WithValidation)
	void SERVER_Fire();
	bool SERVER_Fire_Validate();
	void SERVER_Fire_Implementation();

UFUNCTION(NetMulticast, Reliable)
	void MULTICAST_Fire();
	void MULTICAST_Fire_Implementation();

CPP:

bool ASomePawn::SERVER_Fire_Validate(){ return true; }
void ASomePawn::SERVER_Fire_Implementation()
{
	MULTICAST_Fire();
}

void ASomePawn::MULTICAST_Fire_Implementation()
{
	..Some code..
}

Client1 call SERVER_Fire → SERVER_Fire_Implementation called on server and it call MULTICAST_Fire → all client call MULTICAST_Fire_Implementation.

So that way client can call function on all client and server with any param you want.

I am still not entirely sure why you can’t use the controller’s rotation as that should be the primary usage for rotating your character for determining character animations, even if the camera and the character move together it is really the controller that is making the camera and the character move. But… if that is the need then you will have to do it in C++ by creating a custom controller and setting the camera manager to replicate and pass it into the DOREPLIFETIME macro. You may also need to create a custom camera manager to replicate the properties you need replicated. OR you can also do what @Detech describes which is to send the rotation of the camera each time it is moved (via input control functions) by calling a server function from the client that WILL also work.

For number 2 the answer is yes. I believe the player state exists always, on the server and the clients for every pawn/controller and you can create and assign a custom one in blueprints. Player State is where you put the player’s name and any information useful for displaying the character’s information.

Okay been a while since I looked at this question and reread it. I get what you are trying to do, replicate head orientation to all the clients. @Detech is pretty correct on this one.

You’d need to capture the current “look” rotation. Now I have this working on my system using the controllers rotation as my “eyes”. The Server knows my controllers rotation and replicates that to the owning client, you’d have to set it up to replicate the rotation to the other clients. You could store the controller’s Look rotation on the ACharacter or the APlayerState objects that are replicated down to all the clients. I would think storing it on the Character would be ideal that way your animation system isn’t trying to grab Player State for orientation but I also think PlayerState would be the most appropriate location for it.

I think I got a better method! Taken directly out of the AActor object on how UE4 guys control the method of replicating an actor’s movement. Basically you define the property you want replicated, and set it up appropriately. However instead of keeping that secondary property synced with the actual rotation of your “Look” vector using something cumberous as Tick or updating each time you move the mouse, you override the actors “PreReplication” function that is called right before the actor is updated.

void PreReplication( IRepChangedPropertyTracker & ChangedPropertyTracker )
{
    this->yourLookVector = this->GetLookVector()
    Super->Prereplication(ChangedPropertyTracker)
}

now Right before this actor is replicated you can update the values you want replicated to the server. You can then setup an OnRep_LookVector() function that is called on your clients to update the the look vector of the pawns.

Ah indeed, Im pretty new to C++ and currently learning it. Despite what I’ve learned the UE4 functions and things still seem a bit greek to me so i have yet to figure it out and sit down and really dig into it. I have been using Blueprint at an advanced level though. I do roughly understand what you’re both suggesting though and am curious how I could add it to Character Programming that has been made in Blueprint? And if it has to be made outside of blueprint, would I be able to simply add that to it? Sounds promising though

Being an Experienced C++ guy, working with UE4 was still pretty Greek to me at first lol. Epic does a lot of things on top of C++ using the Unreal Build Tool (such as the UPROPERTY and UFUNCTION macros). But C++ alone is a pretty steep learning curve haha.

As for doing some of these things in Blueprints you can DEFINITELY do Detech’s method. My method would require you to make adjustments to the Code to possibly make it work in blueprints, specifically a BlueprintImplementableEvent called during PreReplicate to gather the information. Afterward you could define your struct in blueprint and when your event is fired you set the properties of that struct that is replicated… frankly it’s a bit of uncharted waters for that one but theoretically it should work. (or you can do it on tick but their may even be an OnPreReplicate blueprint event already)