Am I Server or Client?

I am starting to go crazy trying to check if the current instance of the game is the server or the client. According to all documentation and tutorials I can find there are two ways to check if you are the server or the client. 1. Role == Role_Authority. 2. HasAuthority().

From the tests I have been doing it does not seem like those two checks are actually checking if the instance of the game is running on the sever or client but seems more like it is checking if the actor that is calling it is possessed by itself or a player controller.

How the test I am doing works - below

I have created an actor that in the beginplay() function in its class does the if(Role == Role_Authority){ log “I have authority”}. This actor is placed in the level at runtime and is not spawned in after runtime. The actor has replicate checked as true.

Presumably from what ue docs say, this actor should only log “I have authority” on the server… Right? But it logs it on the clients AND the server as if every instance of the game has authority over this object.

So I thought to myself that maybe it is because it has the “Net load on client” checked as true so this is making it spawn on the client and the server and for some reason this gives the client authority… to test this I made the “Net load on client” == false. This is where my brain almost exploded… When the game boots up the actor no longer spawns on the client (or atleast does not render) but somehow it still logs “I have authority” on both the client AND the server. How is this possible if the actor is not even supposed to exist on the client???

I repeated the same test using HasAuthority() and get the exact same results.

Now the next thing which is what makes me believe that these checks actually are checking possession is if I make a client player possess the actor that is logging “I have Authority” in beginplay() and put a if(hasAuthority) or Role == Role_Authority then log “I have authority” else log “I don’t have authority”, it logs “I DONT have authority”. So when it is not possessed by a player it has authority but when it is possessed by a player it no longer has authority.

I did read that if a client spawns in an object then the client may have authority over that object. So I am trying to figure out how on earth do I make the server spawn in the object. The only way I can think of doing this is by checking if the instance of the game is the server and if it is then spawn in the object. But if hasauthority() does not actually check this then how do I do it???

1 Like

That is what I thought was the case with authority checks but it definitely does not seem like that is what is happening.

An example of something that seems to conflict with this understanding of Authority - I create an actor class >> I add a function Called TryDoSomething() to this actor’s class. TryDoSomething() is not a server, client or multicast, it is a normal function. In the function is a simple branch, if(HasAuthority()){GEngine->AddOnScreenDebugMessage(-1, 10, FColor::White, “Has authority”);} else {GEngine->AddOnScreenDebugMessage(-1, 10, FColor::White, “!HasAuthority”);} >> I call TryDoSomething() from the classes constructor. >> In the editor I make a BP based on this Actor class >> I Add a static mesh to Actor so clients will see it if it is loaded into level on their machine >> I put a copy of the Actors BP in the level by dragging and dropping it in.

With this scenario above if I do -

Uncheck all replication category settings including Net Load On Client in the actors BP and run game in dedicated Server mode with 2 players. Result: Neither of the players can see the actor’s mesh (which makes sense because “Net Load On Client” is unchecked) BUT both players see the “Has Authority” log on their screens. Remember that the log message is not called in a networked function and all replication settings are turned off. How does this happen?

If I run the game in listen/Host mode with 2 players only the host can see the actors mesh but still both players including host get the “Has Authority” log on their screen.

If I try the above scenarios with the actors “Replicate” and “Net Load On Client” settings checked as true, all players see the mesh (which makes sense) and all players get the log message “Has Authority” (which makes no sense, at least not to me).

I have finally figured out What HasAuthority actually means after a couple of days of testing. I think this will be very helpful to many people.

HasAuthority does not tell you if the instance of the game is the server or the client. It is telling you if the actor you are running the HasAuthority check on belongs to the server or the client. So you can have a game running on a client return true to HasAuthority even if that actor was not spawned by the Client.

So as an example - If the server spawns in a pawn that has Replicate set to true, the client’s games will spawn a copy of that pawn in their level. Originally I thought only the pawn that is on the server would return true to HasAuthority() because I thought HasAuthority() was checking if the pawn is the server’s copy of it. HasAuthority() is checking if the pawn belongs to the server or the client. If the server spawned in the pawn and replicated it to the clients then the pawn on the server and all the copies of it on the clients belong to the server and will all return true to HasAuthority(). If the client possesses the pawn then the copy of the pawn on their machine will return false to HasAuthority() because the client that possessed it now owns it instead of the server.

4 Likes

It is only when a client spawns an Actor that it will get authority, in any other case the server will have authority.

Any Actor already placed in the level will have server authority as well as any Actor spawned by the server. Classes like GameMode only exists on the server so here you don’t need to make any check.

3 Likes

Hello, I would suggest to call your TryDoSomething() method from the BeginPlay event instead because I don’t think NetRoles are properly defined during the construction phase. In fact, actors NetRole is initialized to ROLE_AUTHORITY in the constructor of AActor class.

Hi, thanks for your reply. I have done some more tests and I am even more confused now.

I have this actor called RuntimeServerSetup in the level at runtime. Like mentioned earlier, this actor is not set to replicate. As I expected, the clients remove this actor from their level at runtime because net load on client is disabled. If I put a authority check in the constructor which will use GEngine->AddOnScreenDebugMessage if it has authority, it logs a message on the server and all clients. I thought this might be because the Actor is being removed from the level during construction so it is logging the message to the screen of the client before it is removed from their level. To test this theory I moved the GEngine->AddOnScreenDebugMessage to BeginPlay(), I get the exact same result, all clients still log the message to the screen. So I decided to move the GEngine->AddOnScreenDebugMessage to the tick function thinking that it will not log to the screen of the clients because the actor definitely does not exist in the clients level at this point… But what do you know… It still floods the clients screens with the log message as if the actor is still in the clients level. The only explanation I can think of for this is that the GEngine->AddOnScreenDebugMessage will always log a message to all the clients and host screens because they are running on the same computer or same editor. I would be surprised if this is actually true because I have seen many tutorials use logging messages to the screen as a way to test networking.

I have been trying to figure out Unreal’s networking setup for a week now and I am getting pretty close to giving up on this game engine to be honest. To much stuff makes no sense.

The main question I am trying to answer… How on earth does an actor that should not even exist on a client manage to log messages to all clients screens? HOW? The actor is not replicated and the functions logging messages are not networked… So How?? =(

All debug messages using GEngine->AddOnScreenDebugMessage() will appear on all windows, if you’re testing a multiplayer game in the editor.

It’s pretty annoying. Epic should probably look into fixing this, as it’s caused a lot of confusion (as you’re experiencing).

We had to make our own Debug hud widget, with its own message queue, so we could have debug messages that would only show up in a single window.

I could be wrong on this, but if you disable Run Under One Process in the advanced play settings then it will work as expected.

thanks. this post gave me the answer i needed.

i found i could use IsNetMode to figure out if it’s server/client