I’ve read all the official documentation, watched many tutorials, but still I’m struggling to understand and I’d appreciate some help.
Context: I am using 4.27.2 blueprints only and I have gotten successful multiplayer connection to myself through the default online subsystem by running as 2 standalone windows.
I want any client including the listen server to have the ability to create a certain actor that is replicated to all. Right now I am running an event from my custom player state that is set to run on server this creates an actor that is set to replicate. This from my testing works, but it doesn’t seem like the right way to do this.
From my current understanding the run on server setting is an RPC, but the documentation says it is unreliable and to use it for cosmetic and transient purposes. My game depends on this actor being created and replicated reliably. I want to click the option that says reliable, but I feel like it’s off by default for a reason.
How can I, from a client, create a replicated actor on the server without using this RPC event setting?
What is the drawback to setting an RPC event to be reliable?
Why is it that despite the documentation saying that player states are run on the server and replicated to all clients, that my client can run events on the player state that aren’t replicated?
If player states are replicated to all clients, does that mean a client could cheat by seeing a variable they shouldn’t be allowed to see if it’s stored in a player state? (Health, inventory, etc.)
I also have an issue with another problem. I created an actor, I want to replicate everything about the actor excluding one component, which is a UI widget. But when I set the actor to replicate, the UI widget visibility setting is replicated even though the component is not set to replicate. Why is this happening? Is the visibility setting for my widget stored in the actor and not the component?
It’s true that you shouldn’t do state change via RPCs, but it’s about the state of properties within actors. For example your character has variable Health (not replicated), and you update it via RPCs. That’s not good, because if a player joins the game in the middle of the match, it won’t get any of the RPCs called before so the Health will be wrong until you broadcast another update.
When it comes to spawning actor, it’s different. Because your actor is set to Replicated, it’s a state on its own. You can think of it like the state of the Level. Creating or destroying a replicated actor is changing the state of the level, and that is replicated reliably/persistently.
Pro : ensures the event will be executed on the other side, and if you call multiple reliable events they will be executed in the same order. In bad network conditions (packet loss), unreliable RPCs might not reach the other side at all.
Con : can clog up the network buffer, since reliable events are sent and re-sent indefinitely until the server confirms.
What do you mean player state that aren’t replicated? All player states are replicated to all, including yours.
Yes, but that cheater would modify the value only on its own machine. That change wouldn’t be replicated to server or other clients. So everybody would be seeing the right Health value except him. That’s why important gameplay events such as Death and Scoring should be decided on server. That’s why the GameMode object is not even available on client side.
Variables are only replicated from server to client(s), not the other way around.
The only way to replicate from client to server is via an RPC set to “Run on server (if owning client)”.
Regarding your other issue, component properties shouldn’t replicate if the component itself doesn’t replicate. How/where are you changing the visibility ? I suspect you’re doing it from an event which already triggers on all machines. Show a bit of code maybe.
If from a client I trigger a player state event that spawns an actor, and that event is not set to replicate, then the actor will only spawn for the client.
I’m worried that the cheater can see the values at all. My game depends on players having secret information, if they even know the value it’s like an instant win even if they can’t modify it. So if I want to keep information about the players that can only be seen upon certain checks, should I create an array to store all secret player data in the gamemode, or should I do that in the gamestate?
I am using the set visibility node in my custom event. This event triggers whenever the player looks at the actor, and it displays a screen space widget that says “press e to interact”, which should only show for the player looking at the actor, but currently it shows for all players. The event is run in the interactable actor, the event is triggered by the player character actor.
An event is just a piece of code. Player states being replicated means they exist on both server machine and client machines, and their lifecycle are tied together. But on its own, actor replication doesn’t imply anything regarding replication of their variables or events. If the event is not replicated, you can execute the event from server machine it will only execute on server machine, or you can execute it from client machine it will only execute on client machine. Adding replication to the event itself changes that behavior. Same for variables.
Then you need to avoid replicating information to client(s) until the time is right. This can be complex but the engine generally provide enough tools out of the box.
For example you can replicate Health only to the owner of the playerstate by enabling replication condition “OwnerOnly” (so you can show own health on HUD). Cheaters who access player state will only see default health as they won’t get any server updates so they can’t rely on it. Then if at some point you need to send that info to others, you can use a secondary variable like “PublicHealth”, which is gonna be replicated to all, but you’d only populate that variable when the gameplay condition is met, so it is not useable before.
That’s just an example, you can do lots with combinations of actor’s replication conditions (replicated to all, replicated only to owner) and variables replication conditions (replicated to all, replicated only to owner, replicated to all except owner).
Then this is the part that would be interesting to see. If you are running a trace from Character-Tick, then chances are you’re executing that for every character on every machine. Not only this would be causing your bug, but also is highly inefficient.
IF that’s what you are doing, then you probably want to run that trace only for the player that currently controls the character. You can check that with a “Is Locally Controlled” branch.
Okay, I was under the wrong impression that if something is replicated that means everything within it is replicated. But I now understand it’s a lot more compartmentalized, and that replicating an actor may replicate the position of the actor but it won’t replicate it’s events or variables unless I tell it too. I haven’t fully tested if my replication is working as intended yet, but I think I understand enough to figure the rest on my own now.
Ah, thank you. I don’t know how I missed that. At least I was running an event on a timer and not every tick, so my stupidity has it’s limits. Now it’s fixed by putting an Is Locally Controlled branch in front of my event timer starter.