#multiplayer
1 messages · Page 120 of 1
oh ok
thank u all for kind words I will take a rest and start again with clear mind , the thing why I am so deppressed it that it's 1 year now since I started and I have done ton of work and I again started struggling at thing I thought I already solved long time ago so instead solving collectibles functions and combat system between planes I need solve replication again ☠️☠️☠️🥲
and I am also aware one day I will have to refactor controls system too...
Yeah I get that. Keep in mind if you touched something a lon gtime ago and then come back to it, you can easily forget little things you learned while you were working on whatever that feature was back then
I tried last night making the character follow the player that picked them up by using Apply Root Motion To ACtor Force every 0.1s. That did not work out well lol.
It's so bad
I didn't have high hopes. Originally I thought I wouldn't use attachment. I had even coded it to use attachment, but then deleted it before even the first play through test because I thought "that won't work, the CMC will be fighting the position too much"
I'm honestly surprised attachment works, because I thought each frame the CMC checks the players position vs where it thinks the player should be and then corrects it. If the player is not adding input, but the position is moving, I would have thought it would have tried to force the character back to where you picked them up.
(in a server/client scenario)
I'm going to try it now though
Hm... well attach to actor doesn't seem to be doing anything at all for some reason
I can see that I have two valid character actors
is it because I have to set movement mode to something other than walk first?
@thin stratus isnt character because of CMC very expensive for network thought
I think so yeah, if you keep movement allowed it might override stuff
makes sense
Yes and no.
Fortnite runs with 100 of them. They optimized a lot and use ReplicationGraph, but 32-64 CMCs or so are usually not a problem if the rest of the game is properly optimized
lol ok, setting the movement mode to none definitely made something happen. The character just disappeared from view. So I am making progress. Probably need to make them actually attach to a socket or something.
probably made collision mess up hard core because the character went at my feet
lol
Well, I definitely got them attached.
Need to adjust collision I am guessing
Hey. I have a lobby timer stored on the game state. To update UI Values for each clients, I create a delegate on the GS, broadcast it on the GS, bind it in the UserWidget. Working for server, but function is not called on client, missed something on multiplayer compendium?
Hi. Use Multicast RPC
Or OnRep function for property
Trying to store ref to pawn in playercontroller on beginplay, but it's only happening on client. What's the right way to do this?
In another project I would spawn players in RPCs and store ref which worked, but starting from third person tutorial, wondering how I can store ref quickly
Or, am I supposed to just make a helper function to 'get my casted pawn' and call that each time i need a ref instead
There is no guarantee pawn will be controlled at beginplay
Do it elsewhere
OnControllerChanged I guess it's called nowadays
I'm not sure what I am doing wrong. If I attach the enemy player character to mine without the target being in ragdoll, the best I can do, regardless of which socket I pick, the character picked up gets stuck inside my character and shoots them both into the sky
if I turn on ragdoll, then the attachment method still returns true, but they stay on the ground and do not move
I've tried playing with collision settings
making it to where everything but world static and world dynamic is ignored; still those two things happen while physics is enabled on the target.
I can see in the scene explorer that it shows a character attached to mine... not sure why the movement isn't updating then
(during ragdoll)
AController::OnPossess might be suitable
On clients OnRep_Pawn
Um yeah
Can someone help me with the sprinting and crouching system?
alr got some animations
Sprinting and crouching systems?
UE already has crouch built in for the Third Person Template
Running is probably best done in the CMC
Ok, so I figured out the problem where the character was not getting attached to the right spot - I was forgetting to attach to the mesh and instead was attaching to the character actor.
But the problem still stands where I can't seem to attach a character rag dolling - are these settings nort right?
I can see the rag doll actor attached to me, but it isn't following me around. I've seen others say that they have set the movement mode to none to do what I am trying to do, but I am not sure if that is supposed to work while rag doll is active.
Mine is 1st person
It doesn't matter
Same mechanics
If I remember right, the CMC already has it built in
That's why you can see capsule half height crouched or somethingh
Why is it that actors that aren't being replicated every frame destroyed on clients? It was surprising to see that being out of the relevancy range is not the only thing that will destroy networked actors on clients
I'm trying so hard to use EOS in my game, and no matter the tutorial i cant seem to get it working, it gutting and i need help if anyone is able to provide
Yes, CMC has crouch built in, however for first person it just teleport the camera resulting in a poor implementation, so custom implementation is always preferred so the camera is animated instead.
I would just handle the camera myself
No need to change the CMCs crouch
Is https://docs.unrealengine.com/5.3/en-US/multiplayer-programming-quick-start-for-unreal-engine/ flawed? (I mean I doubt it. I just think I'm missing something)
I tried applying this logic to a health component. The health component is set as a subobject on its owning actor and isReplicated is true for it. Otherwise I just borrowed the code from this guide and applied it to the component itself.
I can't seem to get the message from OnHealthUpdate to pop up on my client when it takes damage because the set method only updates health on the server. Not sure if the logic is flawed or I'm missing something?
Hi. Try this tutorial https://www.youtube.com/watch?v=Fd9m4cG2hnU
Unreal Engine 5 Epic Online Services - Set Up EOS for Your Multiplayer Game
Set up Epic Online Services for your multiplayer game!
Epic Online Services Dev Portal:
https://dev.epicgames.com
EOS Documentation:
https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/Online/EOS/
Multiplayer Plugin:
https://github.com/DruidMech/Multipla...
Issue is he is using a plugin he built that uses c++
im using blueprints
Ofcourse^^
ohh
Its the optimal path 🥳
how can prevent the built-in crouch move the camera? its something I been searching / trying with no luck
in a first person perspective
You can simply not use a CameraComponent, but instead make a PlayeraCameraManager child (assigned in the PlayerController defaults) in which you can set the offsets yourself via its update functions.
The update functions usually provide you with a ViewTarget, being the Character. At that point you can return a Transform for the Camera based on IsCrouched etc
Hi All! I'm trying to test lyra with keyboard and gamepad in "dual mode" <keyboard has focus at 1st window for 1st player, pad - 2th window with opponent > but somehow "route gamepad" option from editor menu doesn't want to work, any advice or tip? Does anyone has similar issue ?
is it bad way to replicate event :/
Is it not possible to have a unreliable multi rep? Tried to have an event that is multi and unreliable but it never triggers for other clients, instead if I set it to reliable then it finally triggers
If it's within a dormant actor, you need to ForceNetUpdate as well
I'm still working through this whole "ragdoll characters when attached don't follow the parent" problem. Is what I want not possible out of the box? It can't be a replication issue, because I'm simply playing in a single process in PIE with no dedicated server option
I can attach player characters that are up and moving
once ragdoll hits, the scene explorer shows that I attached the character, but that character stays on the floor and doesn't move.
Does anyone have experience with Snapnet? https://www.snapnet.dev/
No, but it sounds like a shell for SkyNet, meaning we are about to be taken over by machines.
So it has to be something to do with ragdoll. I can see that the capsule never attaches, even though the scene panel shows that the actor gets attached and the attach to actor returns true underneath my character in both scenarios (non-rag doll and ragdoll targets) - the non-ragdoll target does properly attach; the ragdoll one doesn't.
Both scenarios show the target attached in the Outliner though...
Setting the custom movement mode to flying instead of none makes the capsule attach, but the mesh doesn't move.
This is starting to feel like it belongs as a custom movement mode, not using attachment at all.
Hello. I have problem with the head bone in my FPS. I have try to set hide bone by name only on client but not work on server. I have also try to use 2 skeletal mesh 1 for the client and 1 that run on server but I don't like the fact I need to call in c++ two similar anim istance to get the right result. So, anyone have a better idea? Why I have that problem with the head and I always replicate?
Or maybe I should look into physics handles? That doesn't look like it is replicated by default though
I have Seamless travel working in standalone application, but I am experiencing crashes in getting the seamless travel to work in editor.
What are the bare minimum requirements to make net.AllowPIESeamlessTravel true work? I am seeing multiple crashes in the below functions consistently, but it's not really clear as the crash keeps on changing places.
It is mostly Read Access Violation/nullptr exceptions.
Please let me know if any other information is required for resolving the above issue
That boolean is experimental. If it crashes then probably cause it's not fully supported yet.
Following up on my previous question about seamless travel, I read from the online resources that all the UserWidgets would be carried to the next level, but I am not seeing any user widgets being carried to the destination map, is this the new expected behavior or I have done something different which might be causing it? I am currently using UE 5.2.1
Hey i have a question where should i implement my multiplayer rpc that changes the ready status from my player? Currently i implemented this inside PlayerState
okay so its fine if i do it in there right?
As it's a state of the player itself and not of hte character they control.
okay nice
Not 100% sure about that. There was a time, back in 4.x where Widgets caused a lot of crashes due to not being cleaned up and referencing World stuff (aka an Actor).
I think they forced the Cleanup eventually, but it might be that some stuff survives if create in the PlayerController and the PC survives the travel
So is my understanding correct that the player controllers in the source and destination levels are different and the widgets are owned by the source PC, they are destroyed along with it?
They are different if the SeamlessTravel is done from a GM to another GM that have different PC Classes
The rest is probably a correct assumption
This is the case
Not sure what happens if you don't add the owner pin
Maybe it falls back to GI yeah
I seem to remember there being an option, world, pc or gi. Any other parent throws an error.
But I don't recall if using world/pc then fetches the gi.
This seems to be the requirement for an owner, so I won't be surprised if UE tries to fallback to either of those when one is not available
BPs only accept PC
But they work without supplying one
That's what I meant
The actor has continious updates happening, the dormancy is set to Awake but somehow unreliable RPCs don't work unless I set them to be reliable. Would have thought multicast RPCs would work being unreliable as we're sending a stream of updates
Wouldnt want all the updates to be reliable to clog up the network
The actor has continuous updates happening
If by this you mean that you are constantly sending replicated properties, then yeah that might be a problem for unreliables since unreliables take the same path of replication as replicated properties, and the latter might have higher prio than the former, but I'm not 100% on this... needs debugging
I also hope that your net update frequency is not set to anything less than 1
Currently it is set to the default value of 100 (Net update frequency) since we're capping the whole server to run at 32 ticks. I'm using replicated events to send the data as such
Everything works if it's set to reliable (Event from client to server works unreliable, but not multicasts from the server)
Yeah it should be pretty straightforward since you passed the previously mentioned criterias... nothing wrong from what I can tell
Could be an engine bug? I'm currently using 5.2
I don't think so if you're using the defaul replication system and not Iris
Default yeah
Also scratching my head why it doesn't work, thought of creating a new project and making the same example from there to see if it's still present
Would be a pain in the arse if the project is at a mature stage
Wouldn't be a big deal if you're just starting out
But in any case if I had cpp access I would have debugged this down futher and found out what unreal shenanigan is causing this
Yeah unfortunately I won't be able to migrate the project over if it works in the new example project, too many things to move over. I'll see what I can do, thank you for the hellp
class BACKROOMS_API ALobbyPlayerState : public APlayerState
{
GENERATED_BODY()
public:
ALobbyPlayerState();
UPROPERTY(Replicated, BlueprintReadOnly, Category="LobbyPlayerState")
bool IsReady;
UFUNCTION(NetMulticast, Reliable, WithValidation)
void ServerUpdateReadyStatus(bool NewStatus);
UFUNCTION(Server, Reliable, WithValidation)
void ClientUpdateReadyStatus(bool NewStatus);
UFUNCTION(BlueprintCallable, Category="LobbyPlayerState")
void UpdateReadyStatus(bool NewStatus);
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty> & OutLifetimeProps) const override;
};
ALobbyPlayerState::ALobbyPlayerState()
{
bReplicates = true;
IsReady = false;
}
void ALobbyPlayerState::ServerUpdateReadyStatus_Implementation(bool NewStatus)
{
IsReady = NewStatus;
}
bool ALobbyPlayerState::ServerUpdateReadyStatus_Validate(bool NewStatus)
{
return true;
}
void ALobbyPlayerState::ClientUpdateReadyStatus_Implementation(bool NewStatus)
{
IsReady = NewStatus;
ServerUpdateReadyStatus(NewStatus);
}
bool ALobbyPlayerState::ClientUpdateReadyStatus_Validate(bool NewStatus)
{
return true;
}
void ALobbyPlayerState::UpdateReadyStatus(bool NewStatus)
{
if(HasAuthority())
{
ServerUpdateReadyStatus(NewStatus);
} else
{
ClientUpdateReadyStatus(NewStatus);
}
}
void ALobbyPlayerState::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ALobbyPlayerState, IsReady);
}```
hey i have the problem that if the client calls UpdateReadyStatus that nothing happens
@wheat niche Why are you using a Multicast RPC to update a Replicated Property?
IsReady will be set on Clients when ClientUpdateReadyStatus is called and replicated, you dont need to also call ServerUpdateReadyStatus as well.
Because I want to change the value on the client and the server should see the updated value
Basically I have a player list with the ready status
And if a player pressed a button the status changes
Is there another way? Or a better way to solve it as I described
Just stop ServerUpdateReadyStatus from being an RPC
Remove NetMulticast
And remove its call from ClientUpdateReadyStatus
So I just need the UpdateReadyStatus function and inside there I change the bool?
Why is multiplayer so hard to set up for blueprints
eos doesnt play ball
all i want is peer to peer via epic games or even port forwarded ip address
Sure If you want to do that
@manic trail EOS doesnt make UE P2P in terms of its Server-Client architecture.
EOS uses P2P for its network traffic negotiation.
UE is still Server authoritative
Can you make p2p without eos?
You wont make UE P2P at all.
Its just not how its designed
There is no "Host Migration" in UE
It is not P2P in any sense
And never will be
yea it didnt work as i said i have a player list and right nerxt to the player names is the ready status lets say a client tries to change the sttaus the status next to the player name should update for all players
I understand what your trying to do, but if a Widget isnt changing, thats likely not an issue with your network code, more an issue with how you are trying to change the Widget
i dont change the widget i just call the UpdateReadyStatus inside the user widegt (Ready up button)
"the status next to the player name should update for all players"
Bump
Can you explain your question a little more? Im not sure exactly what you are asking?
Actors are never replicated every frame, they are replicated according to their NetFrequency.
Which is unlikely to ever be every frame.
I am not sure if it's only a replication graph thing but I imagine it isn't. Every replicating actor is accounted for and goes through a process to decide whether or not they need to be replicated. If I remove a specific actor from that list for too long they get destroyed on clients but not the server
I think it's the replicationgraph equivalent to net update frequency?
Maybe I should gather more accurate information and ask again with more details. I only understand half of what I'm talking about
If an Actor isnt contained in any relevant bucket of the rep graph to a particular connection its not considered relevant and will be removed on the client until a time that it becomes relevant to them again
RepGraph is just a different way to handle relevancy.
Is there a way to turn that off?
What do you mean?
You can make Actor always relevent
There is a flag for that
The PlayerState is a good example
They are Always Relevant for obvious reasons
I mean I want some actors to not be destroyed on clients when they are not relevant
Or would that be why dormancy exists?
Dormancy seems to work much different for the replication graoh
Dormancy is a separate thing
Dormancy is essentially deciding if the Actor should replicate at all
Regardless of its relevancy
Its a server side optimization
Right that doesn't doesn't to work for replication graph. I have thousands of actors that I need to avoid being checked for replication
So set them dormant?
But using spatialize_dormancy is destroying them on clients unless it's a listen server 🤔
The Host is the Server
So they will always have all Actors
Regardless of the situation
I mean if I do a dedicated server, those soatialize_dormancy actors are destroyed.
Yes because non relevant actors are removed on clients
Thats literally its purpose
Why do you need to keep them around?
On the Client?
What are they doing?
The issue here is even the ones that should be relevant aren't. Like they are within the cull distance
Maybe it's possible my replicationgraph settings for the grid is just not good
So the NetCullDistance on the Actor itself has nothing to do with RepGraph.
Your RepGraph settings and more specifically the bucket settings will determine which Actors are relevant
So if your grid is smaller than you think
Its likely culling those Actors when you dont want them culled.
You also didnt answer my questions above.
Ah, so I am using a pool method for about 5k+ plant fiber
And they're all being checked for replication when they aren't even active
"plant fiber" means nothing to me?
In this case, there are 5k plant fibers that likely aren't relevant to anyone, but a few that are relevant to some. After reading what you said I realize that I wasn't making any sense
I dont want actors relevant that shouldn't be relevant. The problem is the opposite
There are some actors that aren't relevant that should be
It probably is just an issue with the buckets and the grids
Sounds like it.
Also, no idea why you would ever want 5k replicating Actors
Sounds more like a system you want to create a persistent manager for.
Instead of the individual Actors all replicating, they would be associated with a single "manager" actor which handles the replication and rpcs for them.
RepGraph doesnt just magically solve "I want to have thousands of replicated Actors" issue.
It still has its limitations.
RepGraph is more of a Server Side CPU optimization
Its reducing the number of Actors it needs to consider for replication.
Thus reducing CPU overhead.
As soon as you start to get into the hundreds of Replicated Actors, you are looking at a problem that needs a novel solution.
Thanks Cedric, thats pretty interesting alternative! Do you have any links / tutorials about this ? Would this approach work if my camera is using a SpringArm?
Our game is an open world with thousands of actors and a hundred players similar to fortnite
We initially thought replication graph meant that we could have 50,000 actors replicating without an issue. We sort of done have a choice either because we use a building system similar to rust
Well sort of. The idea is to make some rules to stop them from actually replicating using the replication graph haha
The problem is when I do stop them from replicatingm.. they get destroyed
Fortnite boasts over 50k replicating actors, unless they're sort of lying and those actors aren't independent actors
They probably arent lying, but dude. Fortnite has a billion dollar AAA company making it.
You need to be realistic here.
I mean yeah 😂 but I imagined that's what the replication graph was for. I'm sure we'll be able to figure something out. Even if it's not actually 50k
Maybe I will have to be realistic and not go for individual actors
RepGraph is one part of many parts that make it possible
As i said earlier, it isnt a magic solution
Its one part of the solution.
So what would be the alternative? A manager with a struct containing buildpart information, and have the client build that information on their own?
What on earth do you mean by "buildpart information". When asking questions, its really helpful to either explain in very specific detail what you are asking, or abstract details of your game out of your question so it can be answered generically.
I have no idea what you mean by that
A manager like I explained earlier would be a good place to start
Especially for Actors which are all essentially the same
If your map needed 2000 doors that open and close
No point making those all 2000 individual replicated doors
Just make one "door manager" which understands and keeps track of the state of all doors
Yes its more messing about, but its more efficient.
But that could leave to a massive struct array which is what I'm sort of worried about, does unreal deal with this in an efficient way?
What do you mean a massive struct?
Yes, UE has a solution for that
Look into FastArrays
Fast Array Serialization
Let's continue using the doors as an example, players will be able to create their own anytime they like. If the manager is keeping track of all those doors in an array. It'd get pretty good.
I see
I will look into that then, thanks for the advice. I appreciate it a lot
You also dont need to have just 1 manager
You could create a manager for every 1000 doors
For example
That would load balance
You could even move doors between managers that have different update rates
If a manager has only doors in it which have never been touched, that manager itself could go Dormant
So if there were 2 door managers
each with 1000 doors
And one of the managers contains all door states which have never changed
It can go dormant
There goes 50% of the replicated state
Not needing to be checked
This is very similar to how RepGraph works
Or at least, can work.
Oh I seeee
Also, its been foreshadowed that RepGraph will become obsolete in UE5
This a great idea
With the Iris networking model
So if you are on UE5 you may want to consider looking into that
I heard about that aswell but who knows when unreal engine will follow through with what they say. They tend to take their time
But honestly, your issue isnt that you are using RepGraph
Its more your misunderstanding of RepGraphs usage
Yeah that makes sense, I'm only on day 4 with the system and it's quite complicated
If you have hundreds of the same types of Actors that need to replicate, create a manager for them instead.
Using Fast Arrays to hold and update their state data.
The Manager would also deal with RPCs for those Actors to if necessary.
And so these managers would need to be always relevant right?
Yes
So essentially these doors would never be culled then right? Only through gpu?
I guess no more delays and looped code
Well the doors would not even be replication enabled
Sounds worth it though
Only through gpu? rendering culls is nothing the same as network culls.
A Rendering Cull only removes the geometry, it does not affect the Actor in any other way.
Right, it wouldn't be a hit to clients performance because they'd still be rendered out
So I'd just need to be careful how I program these doors
The doors are only a visual representation and interaction interface for the state data on the Manager.
The tricky part, is associating an individual door, with its correct data on the manager.
Which isnt really tricky, you just need to have an appropriate ID system
{
FGuid DoorID;
bool bDoorOpen;
}
This is likely all you need for the door managers struct
An ID to associate to a Door Actor
and then its actual state
They are, but im just using it as an easy example
Just use a ptr tbh
But I completely understand the fundamentals hrre
Or, assign ID's to doors deterministically, replicate a packed array of bitmasks
Here*. I spent a lot of time with UNetDriver. I just thought ReplicationGraph would be a much safer process
I guess I was wrong
Did that for something non-door related but, works well.
There is certainly more efficient means to manage this
I was only being obtuse for clarity
on the fundamentals
Ah I see, yeah I think I could get away with using Pointers for my game
I really appreciate all the insight
Hard to find this kind of information and ideas
You would only use a Ptr if the door is statically placed in the level.
If you have Players creating doors
Oh right
Then you need a system where you can deterministically create the IDs
Like Jambax mentioned
You literally find such clients, and send them the said RPC
You would route it through their PlayerControllers.
for VPS Server which one would be good AWS Vps or OVH or Azure VPS < I want a vps for my shooting game
as chep rate
🥲
any suggestion
Hi, I've programmed my character controller to pick up an actor and carry it on his back. He does this by attaching the actor to a socket on his back.
Unfortunately the socketed actor stops replicating its position across the server, only magically voiping over to its correct position when detached.
How do I make a socketed object continue replicating its position? Or do I need to replicate the fact that it's been attached?
Hi. The position of the attached actor depends on another actor - the character in your case. How do you imagine its replication? Actor cannot have two different positions at the same time.
So how do I let every client know that the object is now socketed, so it follows the parent objects motion?
As far as I remember, the attachment is replicated. Just check the status of the actor.
Or I may be wrong, then an RPC can be sent to notify clients.
I think you would need to Mimic the spring arm logic. But it might also be that you can use your setup and only drive Z through the camera manager
Thanks definitely will try it !
Yes, attachment is replicated
That's good, then why does it just sit there on the client screen?
You mean the attached actor doesn't move with the character?
yep
I tested it in my project and it works fine. Maybe you have a mistake somewhere.
AttachActor() was executed only on the server, but on clients the actor moved with the character.
Crap, I guess I'll try it again in a fresh project to see if there's something else breaking it along the way. Very strange, I initially was using a physics constraint to drag the object around and that replicated fine, I just swapped that out for an AttachActorToComponent node.
By the way, I checked on version 5.1. If yours is different, it may work differently, although unlikely.
Is this the right chat for animation replication?
And we never heard of them again
Hey i have a question after reading some articles and watching videos i only got examples on how to replicate variables from the server to the client but i want to have a ariable that the server and the client can modify is there a way?
variable replication always goes from Server to Client. There is no way to invert that.
Clients can modify the variable but it will only change on their end.
okay and how can i change a variable as a client?
You mean so that it replicates to everyone?
yes
You would need to use a Client Owned Actor (such as PlayerController, Possessed Pawn/Character, PlayerState or a properly setup Actor that has any of those as Owner) to perform a Server RPC and then change the value on the Server side.
#include "Net/UnrealNetwork.h"
ALobbyPlayerState::ALobbyPlayerState()
{
bReplicates = true;
IsReady = false;
}
void ALobbyPlayerState::ServerUpdateReadyStatus_Implementation(bool NewStatus)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Called ServerUpdateReadyStatus_Implementation"));
IsReady = NewStatus;
}
bool ALobbyPlayerState::ServerUpdateReadyStatus_Validate(bool NewStatus)
{
return true;
}
void ALobbyPlayerState::ClientUpdateReadyStatus_Implementation(bool NewStatus)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Called ClientUpdateReadyStatus_Implementation"));
IsReady = NewStatus;
ServerUpdateReadyStatus_Implementation(NewStatus);
}
bool ALobbyPlayerState::ClientUpdateReadyStatus_Validate(bool NewStatus)
{
return true;
}
void ALobbyPlayerState::UpdateReadyStatus(bool NewStatus)
{
if(HasAuthority())
{
ServerUpdateReadyStatus(NewStatus);
} else
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("No authority"));
ClientUpdateReadyStatus_Implementation(NewStatus);
}
}
void ALobbyPlayerState::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ALobbyPlayerState, IsReady);
}
Like this?
The Client RPC seems redundant
Since the Variable is already marked to replicate
That can just be a normal function
That sets the variable locally like you already do
And then ServerRPCs for the change to be applied by the server
So yeah it's okay just the client RPC isn't needed
And in theory the server doesn't need to call the RPC either
okay the problem is that ServerUpdateReadyStatus_Implementation gets called from the client but nothing happens (value does not change)
UPROPERTY(Replicated, BlueprintReadOnly, Category="LobbyPlayerState")
bool IsReady;
UFUNCTION(NetMulticast, Reliable, WithValidation)
void ServerUpdateReadyStatus(bool NewStatus);
UFUNCTION(BlueprintCallable, Category="LobbyPlayerState")
void UpdateReadyStatus(bool NewStatus);
Multicast is also not needed
I'm at my phone so can't easily type code.
But the idea is:
- SetReadyStatus(NewReadyStatus) sets ReadyStatus and if Client also calls the ServerRPC
- ServerRPC sets ReadyStatus
- ReadyStatus being replicated
Optionally ReadyStatus can he RepNotify (ReplicatedUsing) to notify clients about the change. Would need to manually call the OnRep function on server though if you need that to call for them too (e g. Listen server)
As you can see i have two players in my list left is the server and right the client the first player in the list is the server and the second the client if i try to change the ready status it tries to change the tsatus from the server as you can see i printed the name from the player and in the server and client i have the same name why is that i started the game standalone netmode listen server and i tried netmode standalone
No clue. That part of your code is fine
But I just told you the setup
Adjust it first
small question btw sry that im asking so much but im new to multiplayer ^^ should i chnage this:
UFUNCTION(NetMulticast, Reliable, WithValidation)
void ServerUpdateReadyStatus(bool NewStatus);
to this:
UFUNCTION(Server, Reliable)
oid ServerUpdateReadyStatus(bool NewStatus);
Eh yes
hm okay yea this did not worked
Yeah I am at school now, will come back later
Finally got it working, just had to move the AttachActorToComponent node to a custom event and replicate the event Multicast.
Now to spend some more time learning how Unreal handles multiplayer. Thanks for the help
So I have some problems with animation replication, the advanced locomotion plugin to be exact, and I made everything work for multiplayer for my needs. Now in ALS there are two things that somehow work for my clients' client side and the server's all-seeing side of things but everyone should see them.
So my first problem is the aimoffset, which i got to work vertically but somehow not horizontallly
It is handled through the control rotation variable passed to the animBP and then mixed with other variables to output the aimopffset rotation
Or the base aim rotation but they lead to the same result
For the animation transitions I use these gates:
With states like this:
what is the typical good average size of both incoming/outgoing packet for 4 players coop game for listen server? i mean are there any golden standards budget saying that "if your coop game host sends more than 6k bits a packet it's going to throttle" and such?
@faint eagle 6k bits should fit into udp's MTU limit which is a good number for online gameplay indeed. For local network you can ofc stretch the bounds here quite a bit because the low latency / high bandwidth available. The inis provide ways to setup these limits many ways. I think throttling is a false statement in that context.. You may sometimes get throttled / trimmed on the internet for a short moment (by a random intermediate provider in the link between you and target), but it really is not your problem to be fair, that's just how internet works.
hm, ok, and what about 8k-10k packet size? I remember reading something about MTU half a year ago but I've already forgot what are the current limits (if there are any) for unreal and how can it be configured (and should it be at all). I also remember there are these Rates and Speeds to configure in DefaultEngine.ini, but again, I can't remember what's the rule of thumb to set the correct values
MTU limit is more like the limitation of the internet, and it's often 1500 bytes. These limits may vary depending on the network, but it's always best to stay on the safe side :) Again, local net is relatively unbound.
An unreal 10k packet may be split into 6-7 udp packets, depending on your network card's settings.
well currently I'm much more concerned about global net
Afaik 1500 MTU (about 12kbits) should work in most countries/provider - for a single packet that is, but the less is always the better. :)
I just checked all my network interfaces are currently set to 1500 by default (on win10).
nvm got it myself
ALS have community made cpp based variants on github which claim to be having advanced networking and all that. The marketplace als is just outdated, and it may fail quickly in many cases.
if i have a multicast event that adds chat results into a scrollbox any time a client sends a message, how do i make it so only pawns overlapping a trigger volume see messages sent by pawns overlapping that same trigger volume
@whole pine AActor::IsNetRelevantFor is virtual you can override and try implement your custom filter logic there. But i think there are other ways around this too, even a purely blueprint solution can work if you manually specify each owning client and send the data via events only where it belongs to. Altho the former are considered clean, yet the easy (and dirty) solution is just not displaying the message on the receiving end when the client do not qualify. I wouldnt recommend this last one but it seems another way to solve this i guess.
I need to use the BPs as I am fairly new to coding in general and started my whole project with BPs
But got it to work for me perfectly
Thank you anyways though
Aye but networking is very limited in bp and many things can only be done in cpp, so you need to catch up sooner or later. FYI you can always extend your blueprint only project to contain cpp which would allow you to go deeper in the replication-rabbithole (when needed ofc).
what is the correct way to inform the client that they need to update their UI?
I can't for the life of me figure this out. Right now I have the server calling a "Run on Owning Client" event in the PC, which then calls an Event Dispatcher. This does not work for some reason and I have no clue why not...
I made multiplayer door, if server open door everything ok but if client cant
ofc ofc, already experienced some of that stuff but got BP ways around them for now. It is my first real project so I am still figuring things out. Are you free to playtest sometime?
Can you replication pitch (camera or other) with an animation blueprint? I put a cube on the screen, 2 players and other player can see all the server rotations (pitch, roll), but server can other player rotate, no pitch. I know when I have an animation blueprint, and replicate a pitch var and use it in the animation, it works.
Guys how it is possible I get different looks and output when I test multiplayer in Editor by adding more clients and different when I deploy dedicated server and join there?
Why would this 'run on owning client' run on the server and not the client 'sometimes'
Anyone know where I can find an example of Fast TArray Replication usage? I just spent about 5 hours figuring out FFastArraySerializer structs only to find out that it doesn't support replicated variables 🤦 So I guess I'm missing something...
The Fast Array itself is a replicated variable
There is a clear example of its usage in the NetSerialization header
If you are using UE5
Its in FastArraySerializer.h
hey, FFastArraySerializer structs can't be replicated, I tried setting this up and received errors about it.
UPROPERTY(Replicated)
FExampleArray MyArray;
This would not compile
FExampleArray is the struct from the example you mentioned
Why would you use that?
You realize its called that because its only an example
Not actual usable code
Because its not even compiled
It is wrapped in #if 0
Right, I copied the entire thing and put it in my header
🤦
Follow the steps in the example with your own type.
Dont copy paste the entire thing
FastArrays are used all over the engine, they work, they do replicate (they are literally built for it).
If you want a "simple" working example
Look at the GameplayPrediction.h where the Prediction Keys are handled
Right at the bottom
FReplicatedPredictionKeyItem
FReplicatedPredictionKeyMap
UPROPERTY(Replicated)
FReplicatedPredictionKeyMap ReplicatedPredictionKeyMap;
Is in the AbilitySystemComponent.h
Alright got it, really appreciate it!
qq, I think I did this before but i can't remember how, I have an actor i'm spawning on the server, and it has an expose on spawn parameter, that I pass to it. But obviously the replicated copy of the actor doesn't receive that property that is set on the server, how should I handle this ?
(im using this property inside OnConstruction, to do some stuff)
should I just use a repnotify and move that logic from onconstruction to the rep ?
No, it's not, the engine was not designed to support that... as simple as that. Usually people in here want that for rollback, and it's unnecssary as you could use a non-destructive synced network clock
Yeah it's new twitter rules I guess, you have to login
devtricks goes over synced network clocks fyi
rollback is what cs and valorant use.
That or PostNetInit if it's a POD. Replicated properties are read in client inside PostNetInit at the earliest
Assuming we are talking about a dynamic actor
CMC also has limited rollback, but that's for resolving mispredictions on the client rather than lag compensation on the server.
then that's all the more reason to not do anything related to rollback aside from what you get out of the box with CMC
Then forget about rollback
Rollback isnt an "afterthought"
You either know you want/need it from the get go, or you just dont do it at all.
See why I love my current job, I don't have to care about rollback
Not to an afterthought PVP mode
The point of rollback is not making things feel smooth or responsive - you can do that much more easily by simply having (limited) trust in the client.
The point of rollback is letting clients predict inputs while still being entirely server-authoritative.
I mean we already have PVP, but we either didn't really need it, or something something was done that I didn't knew about 😛
I was responding to V about the yeilded results comment
And that is incorrect, in terms of server rollback.
In terms of client rollback CMC already does so.
The point of the server performing rollback is verifying that what a client said actually happened.
The point of client rollback is resimulating on top of confirmed movements from the server to reconcile inputs that haven't been confirmed by the server yet, which CMC does out of the box.
Unless you have purely client authoritative movement it'd be impossible to make a usable networked movement system without it.
would that work for a primary data asset ptr ?
I'm not really keen on their replication, but I would imagine not
That's really not necessary in anything except a 1-on-1 fighting game
My theory: They are UObjects at the end of the day, which I would OnRep as any other
It will actively make things feel worse everywhere else
ok, onrep it is then
Actually, I think we're both misinterpreting what you think you just said. Fighting games do not delay inputs, they delay corrections from the server.
Which is what just about every game involving any kind of rollback does.
You cannot apply server state immediately, you interp to it over a short period of time.
Applying server state with no interp would cause jitteryness at best and choppyness/teleporting at worst.
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking is the standard article to link to about this stuff. This is for both full server and client rollback.
Ignore the stuff about tickrates, it's not relevant.
That is specific to fighting games.
And is only possible because you're not using a camera that is completely tethered to your character.
Because you can outright feel that kind of latency in a first person game.
any type of correction/jerkiness on a camera is way more noticeable
It's also completely unnecessary in anything except fighting games where frame accuracy is valued.
Still would feel bad.
I am trying to compile with SteamAPI_Init() but I get an error. Probably something I'm not #including. I can see on the internet many people have the problem but no solution. I made sure steamworks is intergrated into my project. Is there something I forgot to add in the module? Please let me know.
And no one cares if your client needs to move 0.1 units to the left in anything but a fighting game where pixel-perfect hitboxes matter.
It's beyond unnecessary to care about in pretty much any other genre.
Yes?
It's not a good concept.
It's required for fighting games to feel right. It's not a good thing to have.
Introducing purposeful latency is a bad thing. You do it if absolutely necessary, not because it's "neat".
ok I'm missing something, doesn't seem like the property passed in as an exposeonspawn is even replicated at all
Well you have to internally replicate it if you're missing that
you mean have 2 properties ?
Nah, I mean to mark it to replicate
ah yeah i did
UPROPERTY(BlueprintReadWrite, meta = (ExposeOnSpawn = "true"), SaveGame, ReplicatedUsing = OnRep_ConstructableData)
UConstructableRecipeData* ConstructableData;
It should replicate just fine then
I mean I'm not sure what that UObject is, but if it's a regular UObject then you need to replicate it the old way via ReplicateSubobjects or the new way
it's a UPrimaryAsset
well, a ptr to one
I'm replicating them in other places just fine
Hi!
I'm trying to make it so that the server is always in spectator mode. I dont want the server to have a pawn.
So, I'm trying to override the gamemode's Handle Starting New Player function.
But I don't know what it does by default. Is there any place where I can view its default implementation?
so im assuming that part works
I assume you still need to add IsSupportedForNetworking and return true for it to work?
But yeah they should be net referencable out of the box
Unreal's source?
nope! not using source. i am trying to make a poor man's headless build, for quick testing.
I don't mean building from source if that's what you're thinking of. Literally an IDE that has your project solution open
Oh, yeah! Yeah, i've got Rider open
however, everytime I try looking at HandleStartingNewPlayer from GameModeBase.cpp, i'm just sent to GameModeBase.gen.cpp's implementation
which....isn't very helpful:
void AGameModeBase::HandleStartingNewPlayer(APlayerController* NewPlayer)
{
GameModeBase_eventHandleStartingNewPlayer_Parms Parms;
Parms.NewPlayer=NewPlayer;
ProcessEvent(FindFunctionChecked(NAME_AGameModeBase_HandleStartingNewPlayer),&Parms);
}
That's the reason since sadly Rider can't handle jumping to BlueprintNativeEvent functions
You need to look for the function suffixed with _Implementation in the .cpp
To be honest I think this should be an easy fix, but it's just that they didn't get bothered to do
It normally works fine.
I believe rider has an issue specifically when the _Implementation isn't declared in the header.
Ah makes sense. I can't recall how RPCs behaved in this regard
But yeah they work on a good day
Yeah, looking for the Impl one works great! I can now replicate that
thank you so much for the help!
if a property is marked as RepNotify from C++, and set from BPs... should the BP node say "Set" or "Set w/Notify" ?
I didn't remember you need to change the option. But it was in 4. Not sure about 5
what do you mean change the option ?
I didn't check that box, im just pointing out that the property IS tagged repnotify
Like you need to make it "Set w/Notify"
but the BP node doesn't seem to show that it's w/nofity
Just "set" it simiply
oh it's just set
It should call back in the code
but BPs show w/Notify if you do that on a repnotify property
Yeah, if it is a C++ declared variable, it is fine just using "Set"
with BP variables you also use set... but the node just shows a different title
it doesn't seem to do that with C++ vars
im just wondering if im missing something or it has always been like that
i dont recall 🙂
Yes, that is BP special thing.
How did you test it? IIRC, C++ won't call the function if you are a server.
i have both server and client
i put a breakpoint and a print to screen in the notify, it's not called
Did you change the value? If not, it won't call either.
Yeah, this is often get missed while adding a new variable. And it won't give you an compilation error
yeah silly me, i was just doing a quick comparison between bp and c++ forgot that
heh
also it's quite misleading how that GetLifetimeReplicatedProps doesnt need a header declaration...
Hey so i am making a local multiplayer game, I have this weird thing where its seemingly random if gamepads are detected and working in the engine. Sometimes I get 2 to work, sometimes only 1 ever works, sometimes neither work. I just keep trying random things like restarting the editor or re-plugging in the gamepads. one time I added a print string to the blueprint and both gamepads starting working? super confused if anyone knows a good way to go about debugging this please let me know.
Hi, Does anyone has issue when teleport character and CharacterMovementComponent does some net correction, that cause player lag.
Hello everyone, I recently started learning networking and replication in UE, why doesn't this code work? (I call TryGrapple from Ability which is on the server and client) the idea was that I take the client version of AttachPoint and assign the client version to the server version of AttachPoint
So when Grapple phys function starts, server uses its own verision(which i sync with client before)
Is your character movement Component replicated?
Cause by default it's not
The RPCs go through the Character
Yes, I set it to be eligible to replication, but it still doesn't work
I don’t quite understand how this affects, without this flag there will be no CMC on the server
Or what?
Can you tell me more details pls?
I EnableInput of a actor. To execute server RPC, I need to change the owner right? My character or his controller need to be the owner?
can someone clarify why this is not working :/
when im chaning the input mode to UI only that works but it never goes back
that dosent work
Is it possible in any scenario for a server rpc event not to be.. .well.. on the server? Feels a little redundant to check if it is the server ..
I guess some reason if because of listen server? Like you actually has both roles as server and client.
right but in that case the client is the server, so it's just always on the server and never called as an RPC ?
IIRC, if you don't check if server, it could be called twice...for multicast RPC. If you mean run on server, and yeah, you don't need to check if it is server or not.
No it just means you can't replicate data through the CMC directly. Which is the default.
The stuff you are doing there is also mildly wrong
You wouldn't send additional rpcs
You'd send a flag that the player is pressing the grapple key via the already existing ServerMove rpc similar to jumping and crouching
And then perform the grapple logic on both sides via e.g. PeformMovement or similar.
How do I replicate a UNiagaraComponent It's showing on my server but not on my client
Hey Cedric, I somehow got to your blog and from it to this suggested video:
https://youtu.be/RtQRMcupJs0?feature=shared
Support the channel through donations. Crypto accepted!
PayPal: https://paypal.me/reidschannel?locale.x=en_US
Patreon: https://www.patreon.com/reidschannel
Bitcoin: 1JFwWHr4X6uAeoZadukzqKjzFBj3Qjy7Sk
Ethereum: 0x2B2Bc108F1Cc0fF899959dEF3226637787d8C3dE
Dogecoin: DNQ33YnhpWoTBokBNVkZP5ub8KTLkpyjpv
Join our community discord!
Discord: https://dis...
I wondered if you could explain why using the compressed flags instead of making the RPC got rid of the stuttering because it isn't explained in the video
IIUC in both methods there's client prediction, which should cause stuttering in high latency
And in both methods there's high latency so why 🤔
I guess that's related, but is it the additional RPC that causes the stuttering? If so, why
Because the CMC moves via the ServerMove. It performs the full movement via that RPC and any other don't play nicely into the prediction and correction system
Hello, I need to do a server RPC using Game State Component, however it doesn't allow me to as LogNet: Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor MyGameState_0. Function MyRPCFunction will not be processed.. Does anyone know what the error actually mean? I've tried to add an on rep property, and it's being replicated to the clients
It means that either 1) the game state component is spawned client side and the server doesn't know anything about it or 2) it is from the server, but not owned by the client.
Generally, you need to send server rpcs from the player controller, player state or player pawn/character owned by the client or any components therein.
I add it using game features. Everything added so far has been working fine network wise, but that's the first time I'm adding a component to the GS that has to be replicated 🤔
The game state isn't owned by the player.
You can't send rpcs via the game state or any of its components.
(to the server)
So I have to go some other way? 😔
👍
All right, thank you
Put a second component on your PlayerController to do it for you if you're doing features.
Or Pawn. Whichever makes sense.
Yeah, seems like a solution. However what I need is to notify the client about one property only on component spawn. Is it possible to do an onrep that will be fired only on initialization?
Previously I wanted to make a server RPC to ask for it, and server would make a client RPC with the value
Seems to do the trick DOREPLIFETIME_CONDITION(ThisClass, Test, COND_InitialOnly);
the random value is different on client and server
BeginPlayServer NetMulticast? Perhaps first server changes the value, and then client overrides it as it's running the function as well
Though it depends when the bunch containing server value will arrive
so what should i do?
Let only the server write the value you want the client to know
okay but then the client doesn't know the random value
The SelectedBurgerName (which I assume is the property that should store the random value) is marked as set w/Notify, hence the client will receive the value server has randomized
yea but it doesn't, like it's 'None'
When it's set to notify the value?
no, like on the server it's normal but on client it says it's 'None'
I get it, so you have to find out why it's none client-side, hence I'm asking what's the notify set to? When is the value notified to the client?
like what's in the function OnRep ?
Which one is selected?
Uh, how is it going to work when it's set to none? 🤔
what should it be set to?
It depends on your needs, however I assume it's something you want to be always replicated
yea
I've tested, and it seems to mean "always replicate"
there's no always replicate
ohh
i know what you mean
but why does it say 'None' in the client while something else on the server?
even with rep notify
Is the rep notify even called client-side?
no :(
i added print
and it only prints the server one
What is the property residing in?
I mean, is it a component, character, controller?
it's an actor in a world
Is it replicated?
it doesn't replicate to client, but it's set to rep notify
If actor is not replicated, it's not going to replicate its properties to others
oh, the replicates checkbox wasn't checked, it seems to work now, thanks
👍
Do you know why? Is it because of the update rate?
RPC queue on server? Something in the client code?
Because the CMC is setup that way 😅
Movement goes through the ServerMove call
Not sure what else to tell you.
That's how it's meant to be used
Ok thanks
how do i detect if i click a nav modifier volume
I have discovered the problem with my pickup character / ragdoll logic. I wasn't aware that the mesh actually detached from the capsule component when ragdolled. That would explain the headache that I have been having with this. I am guessing a studio then would just pay an animator to make it look like the character was picking up the mesh via animation and then the capsule would get attached. Then they would simulate a ragdoll appearance through the anim BP as the carrier moves around, similar to processing leans.
Is it necessary to use the EOS Subsystem to connect to someone's Port Forwarded IP address, or is there a way to only use the join ip command
Trying to get a peer to peer multiplayer set up, and can only do it locally or with hamachi (5 player max)
is there a channel for testing packaged games?
No
I don't believe there's anywhere on the server for getting together testers. Maybe the WIP forum might do? But traffic may be low.
I'm wondering the best practice for projectiles in MP. I have an ability that spawns a projectile, that will live at most 2 seconds.
When testing the game, the connected clients, often don't visually see the projectile, as it seems like it spawns and moves too quickly that it doesn't sync to the client, so they just see the impact effect, but not the projectile itself.
If I spawn the projectile on all clients, then it shows double projectiles occasionally, as the server still is spawning the "real" one.
What is the proper way to do this, so the projectile itself will render for all clients properly? I have been searching and not finding anything, just tons of tutorials on projectiles themselves, but nothing for this specific issue
If you get double projectiles, simply don't replicate the projectiles.
They're effectively just a visual effect for clients.
You could send an unreliable multicast RPC for quick firing projectiles?
If you send the fire time as well as the start position and projectile type, you can even fast forward it to account for lag.
Or maybe simply the time and the player that fired it and work it out locally.
I would do local projectiles and clientside hit detection with server validation
I wasn't using them just a visual effect, they were handling collision information, but I could swap that out so they are just the VFX portion and have them not replicated.
@dark edge I am still pretty new at the multiplayer aspect of unreal, for the server validation, would I just simply take a line trace at the time the projectile fired, and then match that with what the server said it should have hit, and if they match apply damage/impact events etc?
What I'm saying is you have the firing client say that it hit something, and the server can check, whatever that means. It can either mean do nothing and trust the client, or do some sort of sanity check to make sure they're not hitting things on the other side of the map, or do some sort of roll back to check if the hit could have happened.
If your max flight time is like 2 seconds, anything relying on a replicated actor is going to be in a weird state for like one quarter of its lifetime at least.
Unless you want to wait ping milliseconds to fire your gun, which I'm guessing you don't
There's various ways to do it, but I prefer to just have fairly deterministic projectiles that are not replicated, but their initial conditions are.
Yeah that makes sense, thank you. And yeah I don't want to wait before the projectile actually fires.
I honestly wouldn't care if this happened for other players, but it happens for your player, where if you fire at something close to you, you never see the projectile, just the impact. But I think changing to not be replicated, spawn unreliable for each client, and then do that server check to apply the actual hit makes sense. Thanks!
The stuff I was mentioning was more for visual effects of other clients.
Yeah, I mean it also impacts other clients, but that is less annoying to me (though still want to fix it). And I think doing that unreliable multicast you suggested will fix that issue
Would it be appropriate to use a gameplay cue for the projectile effect itself?
I currently only use it for the impact
You don't need a special subsystem to connect directly via IP if ports are opened manually
Subsystem NULL supports that just fine
Or just no subsystem and use the console.
What does that have to do with #multiplayer ?
The Mover plugin (aka Character Mover 2.0) effort has the goal of massively improving the existing character movement functionality in UE. This is going to be a very large endeavor that has numerous touchpoints in the codebase, ranging from physics to animation to networking.
The main goals of this effort are to:
Support all actor types, not only characters
Allow gameplay programmers to focus on movement, less on the complexities of networking.
Improve extensibility and customization through modularity, while empowering non-engineers to craft their own movement.
Expand gameplay possibilities by discarding rigid requirements and improving interactions with physics-simulated objects.
Support a generalized rollback networking model that other systems can also use.
Probably might interest a lot of you
How many millions of lines of code will this be?
As long as it's an improvement I frankly don't mind
This will probably also entail the NPP
And it has good documentation and examples!
Yeah I actually took the time to mark this whole thing critical
Not sure that does much
But heyyy
Maybe it motivates the devs working on it! 🙂
I'm interested in how they're going to make the networking work without much dev interaction.
Anybody have experience with Custom NetworkMoveData in the CMC?
I am trying to connect GAS with the CMC by incorporating a "MoveSpeed" variable into the network data but I am having some trouble
I have a float, I've followed the steps listed in the UE docs in regards to subclassing NetworkMoveData and NetworkMoveDataContainer. I have serialized the data correctly and done all the other steps. The part I'm struggling with is where do I actually call "GetMaxWalkSpeed" (like where do I connect my MoveSpeed float to the actual value) and what should I do with SetMoveFor and PrepMoveFor functions?
is there anyone that managed to have active ragdoll working in multiplayer?
is such a thing even possible to implement reliably in unreal?
That's a lot of data to replicate. Do you absolutely need ragdolls to be replicated or does it make more sense just to replicate a boolean so that client's know when ragdoll should happen?
Do arrays replicate the whole thing when an index changes or are they smart about the data that is replicated?
they're smart aren't they?
I think FastArrays are smart, regular arrays are not
It's possibly. But you'll find it both rare, and even when it's done it isn't exactly identical. Most times a single or only a few bone locations are replicated and interpolated on the client. Enough to more or less keep a corpse in the same general area on two different clients in the case that they need to access the body for like looting, etc.
I have some unresolved symbol errors, but can't figure out what the deal is. Its related to multiplayer code, and I'm pretty sure it has somethign to do with serialization so I'm putting it here. Can someone try and take a stab at it? I don't know how to go about problem-solving in a situation like this:
unresolved external symbol "__declspec(dllimport) bool __cdecl UE::Net::WriteQuantizedVector(int,struct UE::Math::TVector<double> const &,class FArchive &)" (__imp_?WriteQuantizedVector@Net@UE@@YA_NHAEBU?$TVector@N@Math@2@AEAVFArchive@@@Z) referenced in function "bool __cdecl SerializePackedVector<10,24>(struct UE::Math::TVector<double> &,class FArchive &)" (??$SerializePackedVector@$09$0BI@@@YA_NAEAU?$TVector@N@Math@UE@@AEAVFArchive@@@Z)
Note that its in the "SerializePackedVector" section, I'm not sure what is wrong
you need to add “NetCore” to your projects Build.cs
thank you!!!
hey all , what is the correct way to check if a controller is the local playing player? im trying to run some logic specifically for the local player, and logic for connected clients .
@shy gust Do you mean you want to separate logic for the Host from Clients?
IsLocallyControlled will let you run code for just the local player
Whether its a Client or Host
no, sorry, im trying to separate logic from the local player , and everyone connected to their PC . for context, I have a racing game , im trying to disable physics and other things for the vehicles being controlled by other players
Is this a Split Screen scenario?
Your question is confusing, thats exactly what IsLocallyControlled does
"Is this Pawn controlled by a Player Controller which is owned by the literal machine controlling it"
Thats what its saying.
This would be false for remote Clients
True for the local Player
If its Split Screen then thats a whole different can of worms.
okay thanks , i just wanted to make sure , as its firing true for both players on the server and on the client , the client is false and the hosting player is true
but that tells me the issue is probably somewhere else. and not in the Islocallycontrolled
It depends on what kind of server you are using. For DS, it won't trigger at all.
im doing Listen Server
okay okay okay
Yeah, that's the reason because the host is server and client. You need to do extra check for the host.
u got to umm call replicated for them yes?
the full call u made
if u want i can show u a quick way to do it
ah i see , that makes sense , and sure if you dont mind, tho it sounds like i need to check for local , and then check authority , in some form
no no no u need all u need is add custom nodes
Yeah, you need sorta extra checks.
i couldve sworn there was a 1 node answer to this , I must be getting my engines mixed up, eitherway much appreciated guys.
do what you guys said but do add custom nodes for run on server to client and back
it'll work
I think the problem is triggered twice?
@lusty kelp Stop providing unconstructive comments thanks.
do once
i did
i am just telling you that do what the mod said
but do add custom nodes to replicate
no worries I appreciate it smoke
Not sure what you mean?
@shy gust BeginPlay could be to early, the RemoteRole may not have updated.
Giving you a false positive
Add a delay
See what happens
ahh i didnt know a delay might be needed , ill give that a try aswell
Im not saying to use a delay to solve it
Only to test it
Adding delays like that should never be a solution lol
Like the host triggered twice because it has server and client1 from the screenshots (it is right because of listen server). It might have some problem that this logic just wanted to be triggered once?
nvm, my mistake. You tried 1 host + 1 client.
Listen server always confusing me honestly
right I understand , adding a delay did fix it on the hosting machine. however the clients machine local player gets false, and the connected host on the clients machine gets True
wow, we need to talk
big time my mod man
trying to help
and u time me out
forget this
you should trying collecting all your thoughts into one message my guy, I appeciate the effort tho
@lusty kelp Stop derailing the conversation.
You are not being constructive, hence the timeout.
In which class you called begin play?
the players pawn
Thats a really unhelpful screenshot lol
Oh sorry, I didnt see the Auth in the top left
Then the screen shot is right, I think? You have a local player and a remote player...
For both sides.
right . my wording for the flag is probably bad tho,
on the client there , when he joins . it triggers the client connect , which really means "non local" and the host is triggering the "local connect"
right , but it isnt for some reason. thats what really confuses me
What do you mean?
The print strings shows that it is
The message that says "CLIENT CONNECTED" on the Client, will be the Hosts Pawn.
Because its not locally controlled for that Client
Yeah, the word itself is confusing. It should be remote connected I think
Player controller will always be local for the current controlling side (client, or host in listen server)
The wording is confusing yes
https://i.gyazo.com/43a767198d68b2ec55086136e139c71c.mp4 hopefully this makes a bit more sense
when the host boots up its correct, but when the client does , see he connects as a client to his own instance , and the hosting player is tagged as remote , by the "islocally controlled"
It is better to have Local Connected and Remote Connected 🙃
☝️

You will have clearer idea if you spawn 3 windows, 1 host and 2 clients.
To take a look
You would have 1 local connected and 2 remote connected for each
thats a pretty good point , ill give that a try
So i think i fixed it ,the delay currently does make it work, im aware thats not the best practice tho. i was doing some trouble shooting and only had the sphere render for the local player and that proved to be much more accurate then depending on the timing of the print string. really strange
So I think the reason is the pawn spawned doesn't mean it is possessed.
You may try not calling it BeginPlay but onpossesed
ahh that makes sense , i always forget about the time it takes for things to process, so many hours of troubleshooting;;; thanks a million guys , really appreciated.
okay so my question is this, why am the other person thru steam getting a Frender error?
across the ocean per unit to my home
Is there an overhead of calling server RPC from server? I mean I know is server calls server RPC it's just going to execute it locally but should I bother refactoring RPC method content into separate method and call it directly?
The overhead is negligible.
Its not worth it.
k, thanks
So the OnPosses event is still too early, so im not really sure what the proper way to wait without using the delay node would be
alternatively i could just exten the loading screen a bit and wait for all players to load in, and assume everything should be properly bound by 3-5 seconds. but I imagine thats pretty bad practice.
Hmmm, can you post the blueprint graph or code?
@shy gust You will usually want some sort of UI Interface for when Players load into the level.
i just realized the event possessed only fires on the server? so im not sure what to do for connecting players
Ah, yes. It only fires on server. My bad. You could replicate it to client
Like set a variable in Pawn such as Possesed and make it rep_notify. Then the client should get the call back.
ah that seemed to do the trick! thanks a ton, I have alot to study with networking, I appreciate the help again.
Hope it works.
@shy gust IIRC there is an Event called something like Restart that is called on Pawns after they are recreated for the PlayerController
Cant remember its Blueprint exposed name
Its called on the Client
ah gotcha , ill see what i can find
Its actually the ideal alternative to BeginPlay for Pawns
For intialization
As its called after all of the nuanced replicated ownership and roles are sorted out.
think I found it , "Receive Restarted" sounds like what your refering too , ill give it a try
Sounds like it
that seemed to get rid of all the inconsistency, works like a charm now, the other method was still leaving some room for error but that seemed to do it , man the amount of times ive spent a day troubleshooting and researching around to be told about a weird nifty node here in this server lol. thanks once again.
You still stuck on this?
can anyone help me with this? i followed this tutorial but i cannot seem to "host" sessions or join them. but the map starts when i click on "host"
Unreal Engine 5 Epic Online Services - Set Up EOS for Your Multiplayer Game
Set up Epic Online Services for your multiplayer game!
Epic Online Services Dev Portal:
https://dev.epicgames.com
EOS Documentation:
https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/Online/EOS/
Multiplayer Plugin:
https://github.com/DruidMech/Multipla...
When I play as a listen server should it be counting as a client as well when replicating things?
What makes you think it is?
Listen server has a local player if that's what you're asking
Yeah that's what I meant, thanks
Yeah, listen server is server + client basically
void UHealthComponent::OnHealthUpdate()
{
AActor* owner = GetOwner();
//Client-specific functionality
if (owner->GetLocalRole() == ROLE_AutonomousProxy)
{
FString healthMessage = FString::Printf(TEXT("CLIENT: You now have %f health remaining."), CurrentHealth);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, healthMessage);
if (CurrentHealth <= 0)
{
GetOwner()->Destroy();
FString deathMessage = FString::Printf(TEXT("You have been killed."));
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, deathMessage);
}
}
//Server-specific functionality
if (owner->GetLocalRole() == ROLE_Authority)
{
FString healthMessage = FString::Printf(
TEXT("SERVER: %s now has %f health remaining."), *GetFName().ToString(), CurrentHealth);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, healthMessage);
if (CurrentHealth <= 0)
{
GetOwner()->Destroy();
}
}
//Functions that occur on all machines.
/*
Any special functionality that should occur as a result of damage or death should be placed here.
*/
}
I have this on health update. When my client takes damage it prints out both the server message and the client message.
But if I'm playing as the listen server it's only printing the server message on the listen server + the client
Feel like I'm doing something wrong but I'm scratching my head a little bit..
The ListenServer does not "count" as a Client in that regard
ah excellent
It's a bit hard to put into words
A traditional DedicatedServer and Clients would strictly split this of course.
A ListenServer is a weird mixture. In almost all Code-Paths it counts as Server/Authority
Yet it's a Player that still needs to get the Events that you do for Clients
Run on owning client would work tho right?
E.g. show UI, Effects, play Sounds etc.
That just a normal event then
So if I wanted to code for a game that could either use listen-server or dedicated then I would need to account for all this
There is no second instance on a "Client" for the Listen Server's Actors
If you do it right, it should work just fine for both. You just have to very carefully consider your conditional stuff.
So the Client or Server RPCs if called by the Server on the Server's Actors are just events
You usually have to keep that in mind for stuff
E.g. OnRep calls only for Clients in C++
Yes but they would both still fire, correct? What are the actual conditions for run on owning client, locally controlled?
If you do something in there that affects the Player, like adding a Widget, then you'd need to also do that for the Server
By either doing that by hand or callign OnRep by hand when setting the Variable
Or owner = local player
And at that point you'd need to know if Listen or Dedicated
Cause e.g. a WIdget isn't needed for the Dedicated one
So you do have to somewhat code your stuff with that in mind
It would still fire, yes
LocallyControlled is a Pawn concept
The condition is more "somewhere in the chain of owners has to be the PlayerController", which is ultimately a UNetConnection
LocallyControlled just asks the Controller for IsLocalController
Which in return just spits out a bool based on the Local and the RemoteRole
So not really related to Ownership
It just goes hand in hand for PlayerController etc.
@sharp vigil Here is an example where the difference would theoretically matter. This is one of many things. The exact usecases are based on your game. Also this is pseudo code that probably doesn't actually run.
// Header File
UPROPERTY(ReplicatedUsing=OnRep_MatchState)
EMatchState MatchState;
UFUNCTION()
void OnRep_MatchState();
// CPP File
void ASomeActor::SetMatchState(EMatchState NewMatchState)
{
MatchState = NewMatchState;
if (GetNetMode() == ENetMode::ListenServer)
{
OnRep_MatchState();
}
}
void ASomeActor::OnRep_MatchState()
{
if (MatchState == EMatchState::PostGame)
{
ShowPostGameUI();
}
}
Can also place the NetMode check or similar into the OnRep in case there is code that the Server has to execute in addition to the Player related stuff.
But that could then just be placed into the SetMatchState function or similar.
Ahhh I see
So you're saying I can use netmode to have more control when I'd need to account for whether my client is the listen server
In BPs that's yet another story, cause OnRep works differently there. It's a PropertyChanged notifier more than anything and will also call for the Server, due to the variable changing. (as well as for Clients if they locally predict the change..)
bool UKismetSystemLibrary::IsDedicatedServer(const UObject* WorldContextObject)
{
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (World)
{
return (World->GetNetMode() == NM_DedicatedServer);
}
return IsRunningDedicatedServer();
}
Yeah it's really annoying that they did it that way.
Yeha I mean there is a sh*t ton of different ways but yes
Can also just use the Kismet functions
const bool bIsDedicated = UKismetSystemLibrary::IsDedicatedServer(this);
const bool bIsListen = UKismetSystemLibrary::IsServer(this) && !bIsDedicated;
(this being an Actor or a UObject with a valid GetWorld)
I gotcha. Thanks for all the info. Super helpful. Really appreciate it
It's like you executed this node. If you want some callback, it is a good timing for binding.
Or you can do some print string or whatever.
so the result might be either success or fail?
The top execute fires immediately after that node, the other two fire when it returns a result.
It doesn't relate to the result
hey guys question
im trying to show player name/portrait but it only works on the 2nd client 1 sec ill show
Show your code
as you can se the "main window(listen server)" is not getting the 2nd clients info but the client window is getting the first ones info
so the way ive set it up
on the main menu im setting the "portrait texture" & Name and saving it to the GameInstance
then im just updating the UI based on a cast to player and getting the info from Gameinstance
Show your code
The only way the server can know about anything from the client is through a run in server event. Do you ever pass the name through one?
Thank you, this really helped! 🙏
hmm well the vriables are replicated but u might be right im not running it thru the server
-.-'
mb
one sec ill se if i can fix it
@dark edgey so that fixed it obviously i was just being dumb 😛
Another issue, im "destroying" an actor in game GameMode
but it only being destroyed for the "listenServer" not the clients :/?
anyone:/?
Is it a replicated Actor? Otherwise it won't do anything
yeah it is
hello, i have an array (that replicates with a repnotify) of a struct which has a few variables. i've tried seeing if changing the values of one of the struct instances in the array would trigger the repnotify, but apparently it doesn't. so what is the best way to enforce a replication when a value inside the instances are changed? using the push model?
Hey. I have a problem that I cant find a solution for. I have a function to spawn player. I want to do some kind of among ug logic. Lets say when there is less than 5 players connected, I want to spawn 1 impostor (character blueprint) and 4 normal players (another character blueprint). I tried it like shown in the image, but when for example 2 players connect, each one of them is "impostor" and then it spawns 2 "normals". Does anyone have any suggestions?
hi
im having problem with the multiplayer menu
where it says host or refresh list
everytime when i press host, im still stuck in the menu. I want to make like this when i press it that the widget menu will be dissappear
I just finished making a dedicated server. What are best practices that I can use to have the host change levels, player slots, password and other server settings when launching the dedicated server .exe?
In a previous engine I worked with, there as a variable type called "PlayerFlags" that created a bitflag for each player in the game, and would handle things like player IDs changing. Is there anything in unreal that is equivalent to this, or is this player ID changing not something I need to account for? I assume worst case scenario I just need a map of these flags per player controller, but I'm not sure if there is a better way to handle this.
Lobby -> start game (spawn players etc) -> shuffle array of players (or player indexes) -> foreachloop -> branch(index % 5 ==1 ) -> true => imposter
False => regular
Okay so I tried something, dont know if its right but I guess its not, because it only spawned 12 normals and 3 impostors even though I connected with 3 players
Tried it like this aswell, same thing
Hello, newbie here. I'm using the UI Widget from the Car Game Template.
On the server no problems whatsoever, but on the clients, the value seems to be uncertain of the speed, it vary a lot.
For reference those are the vanilla functions i'm referring. The function is declared in the UI Widget and is called in the VehiclePlayerController. The smooth gif is the server and the jittery one is client.
I'm feeling my lack of results researching for the matter might indicate that i'm missing a pretty obvious notion could you maybe point it to me ? Thanks a lot
Yeah, though the problem has evolved a bit.
After debugging, I'm finding that I am successfully passing floats and such, but the actual replicated float isn't being set anywhere.
I thought it would get set in the "SetMoveFor" function within the SavedMove struct, but it doesn't seem like it is ever called (I tried placing a break point here and it never came up). This is the only place where i actually try to set my float value
My goal is to connect a GAS MoveSpeed attribute into my CMC. I am trying to accomplish this by just passing along the MoveSpeed as part of the networked data, that way it should sync with locally applied GEs and such (my MoveSpeed is changed via some effect, and my CMC should grab that MoveSpeed float, pass it along, and use it in CalcVelocity). So I think its all working, except for where to actually set the float...
In the debugger it shows the float value being passed around as zero, so
@gritty warren not sure I follow
The SavedMove does not pass anything to the Server
Ah, sorry, that was a disjointed explanation. To clarify, I'm following this: https://docs.google.com/document/d/1UO6Ww6Lfpti3YElVdo9uioTUtQJQ9CoSLvd9kF8hvJo/edit
Custom CMC Network Data Discord Permalink This document will cover how to use and send custom network data between the server and client through the Character Movement Component, beyond just custom flags. This could include sending additional compressed flags, additional input vectors, etc. No...
The process for sending info is very extensive, but its something like:
SavedMove -> NetworkMoveData -> Server stuff
Sure
The NetworkMoveData obtains whatever values from the SavedMove and sends it along
Correct
So I have done this in the past with flags, and it worked great! I can add in flags for like sprinting and stuff and it worked very well
But I am having trouble figuring out this float business.
The float I'm trying to send is my own version of "MaxWalkSpeed"
I don't have the Engine at hand but I'm sure I recently talked about this here already
It's a GAS based Attribute for movespeed, because I'm doing a GAS game. This is against the convention - GAS does not typically play well with the CMC because they have separate replication / prediction systems. To solve this, I'm just going to package up the MoveSpeed attribute and send it along too
You need to override the method that "unpacks" the NetworkMoveData on the Server
and set the value tehre
Is the value already 0 when you fill the NetworkMoveData?
Aka already in the SavedMove?
I do not know why it is zero. I am not sure where I should be setting it every frame.
With flags, I only ever changed them in SavedMove
Yes!
and i only ever changed the flags in the "SetMoveFor" function
if i recall correctly
I can't recall the function names atm
np np
yeah, i think that is SetMoveFor
It's the one that also calls something with initial position or so
Yes! That's the one
Yeah, then there you'd need to get the CMC value
Okay, so if that is where I should be setting the float, I just got to figure out why it isn't being set there
I am trying to set it by calling "GetMaxSpeed()"
which I have overwritten
to obtain the appropriate attribute value
Well, did you override it so Server and Client do two different things?
and that all works locally, but for some reason the net stuff doesn't
hmm, i did not
I assume your Client should get the Attribute
And your Server should use the Variable itself
just one thing, and then in the CalcVelocity i do two different things depending on autonomous proxy or local authority
I would have just done that in the GetMaxSpeed function
Client returns Attribute value, Server uses the CMC Variable you added
Why
Only the Server needs that you are setting that with the data you send to the Server
well, if my attribute gets changed based on some gameplay effect (like a slow), i want that to be sent over in the appropriate time
Yeah?
- CMC gets a MyCustomWalkSpeed variable
- GetMaxSpeed override with GetAttribute for Client and MyCustomWalkSpeed for Server
- Client fills NetworkData with GetMaxSpeed
- Server sets MyCustomWalkSpeed with NetworkData
ohhhh
I also don't see the need for the SavedMove to have the MaxSpeed, unless I misremember and the NetworkData has no direct access to the CMC
Interesting
NetworkData doesn't transmit anythign but acceleration and direction i think
NetworkMoveData :: Serialize has acceleration, location, control rotation
and like a time stamp
You'd need it in the SavedMove if you want reconcialiation to have the correct speed
Which means PrefMoveFor would need to set something for the Client too
Hm
Okay so
Letm e see
My prep move for just sets the attribute value, which in hindsight is very bad
I like your approach
I didnt even have a custom walkspeed variable in my CMC, which is super silly in hindsight
- CMC with CustomMaxSpeed
- GetMaxSpeed returning CustomMaxSpeed
- SavedMove SetFor using GetMaxSpeed
- SavedMove PrepFor setting CustomMaxSpeed
- Client setting NetworkMoveData MaxSpeed from SavedMove (I assume)
- Server setting CustomMaxSpeed from NetworkMoveData
You are then lacking a point where the Client initially sets CustomMaxSpeed with the AttributeValue
I don't remember the name
But there is a function that is something called with Before or Pre Movement Update or something like that
Oh interesting
Okay I'll take a look
And we wouldn't just skip the middle ground of having a CustomMaxSpeed by directly adjusting what GetMaxSpeed() returns?
because if it just returns custom max speed, but we are trying to set custom max speed elsewhere every time get max speed is called
couldn't we just skip the local value or?
(this was my initial thought)
I mean you could just set the MaxSpeed variable that already exists
MaxWalkSpeed or whatever it is called
But the rest stays the same
Just that CustomMaxSpeed becomes MaxWalkSpeed
Or what do you mean?
Also don't forget super call, cause this handles Crouching/Jumping iirc
In CalcVelocity, a value called "MaxSpeed" is a stand alone float that is filled by "GetMaxSpeed()"
