#multiplayer
1 messages · Page 236 of 1
yeah, but i'm asking about this binding, inside widget
it works even without rep notfiy xdd
The get text function is on tick yes
uhh, i dont want that for sure xd
Yes if a variable set as replicated it will update. But you want RepNotify to tell any listener to perform something
E.g updating UI
That way you don't have to use event tick -> get damsgeable struct -> get hp
Most cases is peanut, but if you are doing RTS and a lot of actors
A wise man says widget tick can be costly
@normal viper unnecessary depdency to widgey
Your on call should work if it doesn't it just mean the binding didn't take place in that specific machine
Besides you can make this cleaner with just 1 event dispatcher. Many things can listen to it
Imagine if you have to perform 20 actions for the variable change
You don't want to do all that on your OnRep function
As you can see it was dispatcher before, so I'm aware of it, it just wasn't working so im trying more simplier temporary solution to find the mistake in the flow
I would debug and check if the binding take place
im gonna try it right now
so this is current state, the delay is ofc temporary so I can figure out where is mistake,
W_WIdget (binding to event dispatcher)
AC_Damageable ( Dispatcher on Ac_Damageable getting called)
Anyone sees any mistake?
Print the onreps
omw
yeah it only prints it for client
that's good find
there are 4 units in the game btw
there should be 8 rep in total, right?
hmm
im not sure what you mean
btw. i added 2 extra players and they get updated and server still doesn't
black magic
Onreps firing for the server is generally unique to blueprint replication
This one?
Yeah, I'm not sure that would trigger an OnRep
So this is inside Bp_Unit when it get's ''initialized'' with data from Data Asset
You are setting it on Server and Client that way. And depending on the way that Actor is spawned (is it placed into the Level?) that might cause the Client to not call the OnRep cause the data it receives is the same it already has.
You can't set the "AlwaysCall" flag on OnReps in BPs.
If you need that, limit that specific part to IsServer
so either make a setter that calls it manually
or actually react to the property you set and not some other thing
show the details of damegeable data
inside Unit or in Damageable COmponent?
that seems to be the issue
I am asking to see how it is replicated
wait, which one of these is the value we are changing?
I changed it since it was pointless to set it here
there is a local dameagable and one on a replicated... data asset?
i removed it and just moved it to take from Data Asset
and feed to Damageable component
ofc then Update Health Bar at the end is not needed here or I have to change it to takee directly from Data Asset as well
so the initialization was fine, like both clients had the same value
imho, you shouldn't need to set locally as client
just receive replicated value from server
it's just dealing damage doesn't update it
it works for client currently
it just doesnt update for the ''host''
the damages are going trough
what is this rpc on
Server Take Damage?
is ACDamageable sets to replicate btw? (Component replicate)
does the client own this actor to be able to call this rpc from client to server?
clients can't just call rpcs on random objects afaik
okay so the part with setting, binding and other should probably be fine, it's more about how i call to take damage of the unit?
yes, and debugging should reveal this imo
i tried to cheat it, making it multicast, server rpc after clicking G ..
the rpc not ever getting called on server at least should be the main concern imo (read the docs on rpcs)
Try changing this to Server RPC
ormake the result of the end of this sent as a server rpc
send the data to the server from a client->server server rpc that has the info about what you damaged and how much
replace the X with a new server rpc that accepts the damage amount or whatever
or just use the damage amount they have on the server
to keep it authoratative
not sure if this is what you wanted
btw this is not how they gonna take damage but i just want to see it working i guess? its a good way to test right? then i can just take it and make the same logic in the unit dealing damage to unit
so i can now call it from each client (before I could only click G on host) and it deals damage
still doesn't update the host health bar
not sure if visible
host is 100/100 (default of widget) and clients are updating
host sees all as 100/100
a forum post on the UE forums when i was trying to figure out why it wasnt working lol
so the issue is the RepNotify never runs on Client0 or Server
omg i think i found it
inside function Take Damage, that takes the damage and updates current health
I need to Set with notify Damageable Data as a whole
this was missing
it works now. Do you guys think it was it?
now it works even without calling rpc just press G and Server | Take Damage on all units
someday maybe ill understand it, gonna read some documents about multiplayer again now 😄 im satisfied, moved like 5 things so far to multiplayer haha
anyone tried replication with mutable instances?
hello how can i use level streaming in multiplayer load and unload only effets who trigers the collision
That's kind of how you do it, each player should handle them locally
There isn't any out of box multiplayer support as to my knowledge
okay i knew it but how can i do it i tryied run on owning client and run on server - run on ownin client, multicast but nothing changed
Well what do you try to do with the RPCs?
If everyone should have the same levels, I'd keep a replicated array of desired levels and load/unload or set visible/invisible inside the OnRep function according to the changes to the array
I want everyone to be at the level they want and I want it not to affect each other.
hi guys , I want to make a pawn controlled by AddForces and replicated. I'm currently looking into mover 2.0 as a solution but would that mean creating my own MovementMode similar to what walking does ?
Then loading and unloading effecting the collision triggerer shouldn't be a problem here. But you would need your server to have the levels that any players are in to be loaded as well, otherwise they would be considered as in empty space and fall
If it's a listen server, you can load them but keep invisible to not let them see anything they shouldn't see
I add Run on owning client again its works well but if server triger unload its effects everyone
As I stated on the above message, server shouldn't unload levels that players are in. You're basically unloading your ground on server, which makes your player to go falling state, even if the client sees they're standing on something
I need server can unload levels with no body effects beacuse Im using listen server
You can set them invisible in server.
Just replicated or predicted? There's a big difference
Hmm, what I noticed that it's just good to create Widgets of objects that are in the world (that I want for each player to have acces to) on Begin Play of the object. Btw I ''avoid'' generaly running things on Begin Play because we know sometimes things are not loaded, not set etc. so I just try to make sequence and Initialize things when exactly I want it. But back to widgets, just asking about widgets I noticed when I create them on begin play it kind of works (each player can access it etc.) is this generally speaking good approach for the widgets? Ofc, there are probably different types of widgets that I create just for the player, like inside HUD or whole ''Main UI'' but that is different approach as each player has it's own HUD so it's more obvious. Here I talk about objects in the game, they create widgets on their own and put their own data there so player can see and begin play seems like it creates the widget for everyone (each client), I will need to see how it works then with feeding data to it, but I guess it's the same as with health bar, with some kind of rep notify update.
**i'm having an issue attaching a weapon to an NPCs hand on spawn without a delay.
**
i spawn the weapon, then i use OnRep to ensure the weaponRef is available to attach it (in the screenshot, on rep has teh attach code).
despite this, in multiplayer the weapon attaches with a big offset on some AI. i think these AIs are often have scaled meshes (not ideal i know).
strangely, if i include a small delay after spawning the actor, i have no issues. its just, feels like landmines having delays in these kinds of spots and kinda jank.
any ideas?
holy, is multiplayer really like I need to send so many requests from the ''objects'' to the player controller so player controller beeing client can ask something to server, and then server will decide to run it on client or actually on server and then because it was run and server and it's replicated it's gonna replicate to other clients? is it clicking right for me? Like Actors spawned in the level don't have any power, unless I first call from them to Player Controller (if i have reference to it as it was beeing spawned starting from player controller), there I call to Server, then server Call either back to Run It On Server or Run It On Client. Can anyone tell me if more or less its like that?
no, if an object is spawned by the server most the time you do not need to route rpc calls through the player to control it. there are situations where you do need to do that though.
in general when you do stuff on the server you should find ways for it to replicate down without having to multicast etc (not always possible).
there is some of this back and forth though sometimes.
but it still has to be done by the player controller at least (something that is owned by client), and it cannot be just a random actor
nah like, if you spawn an NPC on the server, the npc will be owned by the server. if you want to attach weapons to the npc, or make it do a dash, or whatever, you can do it at the server level and it will automatically replicate down.
however, if you want to trigger an animation montage, you need to do a multicast for the client to see it. but you don't need to run it through the player/client
some stuff is legitimately complciated though, especially once you want to avoid the appearance of latency.
but can I do things inside NPC ? like events that will call to server
or make changes to player controller
if you spawnt he NPC on the server, the server owns it, you dont need to do RPC calls.
Not from the client, no
but as duroxxigar says, you can't just run 'destroy npc' from the player, you need to RPC call.
You can only do a Server RPC from things that has network ownership
So if the client does not have network ownership over the NPC, while you can call functions on that AI - if at any point it tries to do a Server RPC inside of that function, it won't work.
And doing a server rpc on the server is pointless
yea sometimes it is nice to have a server only function as a RPC though, there is no cost.
then you can call it from the client or server.
if i spawn things that are only on server it means players may dont see it?
if the thing is replicated, you will see it everyhere.
If it isn't set to replicate - then, no. Others won't see it.
okay, and it practice it means i will see 2 instances of it (Server, Spawned) (Client, Spawned) ?
you definitely dont want to think about it as two instances.
Has anyone has experience with Replication Graph?
Traying to implement it on a Game in which the camera and the Pawn are not in the same location and the calculations seem to use the camera always as the reference point, but I haven't been able to change it, even by overriding the GatherActorListsForConnection in the UReplicationGraphNode_GridSpatialization2D
it is easy to start thinking about it like two instances but it is a flawed way of thinking and will mess u up
Haven't had to use it - but Iris is supposed to largely replace replication graph.
As of 5.5, Fortnite is finally using Iris as well
is there any easy way to see if something actually was spawned by server or client? i guess if everyone can see it, it would be correct to say it was spawned by server and it's replicated?
Haven't heard about it, I'll read into it. Thanks!
It is still experimental, but some people have already switched to it
And it'll eventually replace the default stuff
Pretty sure it is also super important for the server meshing stuff they're working on as well
here is a to do list:
- figure out how to play as a local client.
you see i am in standalone mode, the server is on the left and the clietn on the right.
-figure out how to log client/server locations of stsuff. you see how i have a debug thing i'm looking at (this is VR). its showing teh client and server position of various objects so i can ensure they are in the same spot.
you should try to figure out how to get to this stage, logging the location of an object on client and server that was spanwed by server and is replicating.
once u can do that, u will have much better knowledge to ask questions, but it helps to start from this base, always ensuring you know whats going on on both the client and the server.
also i can't stress enough, dont add a bunch of code then try to figure it all out at once, just go slowly ensuring that things are where they should be in both the client and the server as you go, and that you have ways to check these things.
Thanks a lot, any sources that you recomend to read on it?
Alright, I'll look it up. Thanks!
Hey everyone,
I'm trying to get more detailed insights into the contents of packets in Unreal Network Insights, similar to how CPU_TRACE_SCOPE works for CPU profiling. As far as I can tell, it doesn't seem possible to achieve the same level of granularity since Network Insights relies on NETStat and is built at runtime.
For example, when analyzing Lyra's Ability System Component, I can't see which specific ability or part of the system is causing network issues. Has anyone found a good workaround or workflow to get better insights into what’s happening inside packets?
Show your startup args
Your verbosity appears low
Guys, why there is difference in the variable between Client and Server version? The server version has correct version of variable, if my client could use it, logic would be fine.
PlayerControllers don't replicate to everyone, they only exist on the owning client if the client owns them, and the server.
Which playercontroller you may be referencing in there depends on where you're running this and how you set the value.
Sure they replicate, as you say from the server to owning client
UI/HUD sure won't tho
Hmm, when I spawn these actors (Caravans) from Player Controller (and it goes trough gamemode, since it's how game starts for each player), i plug PlayerController (self) to them, so to my logic they should have these set as static Caravan0 PC0 and Caravan1 PC1 (as on the server version) and then client version don't have correct variable? It's kind of like I set it to number 01 and client shows 00 out of nowhere?
I even pass these Player Controllers as Get Owners
i guess it's doesn't matter, im just using this wrongly
how many players are involved?
It was 2 players (host and client)
the client playercontroller will be 0 on THEIR MACHINE, but the hosts might be 0 on host and clients serverside controller is 1
IDK if that'd be reflected in the name of the object but it certainly is if you Get Player 0 for example
There are 2 playercontroller actors on the server but only 1 on the client, their own.
yeah, but shouldn't that variable be replicated down to client from server?
or just because its player controller it's like exception
because it (im probably wrong), but it's like server had variable with Player01 and client sudenlly has Player00
the server player's playercontroller doesn't get to the client
like the client can't even see? it would be null in case if we wanted to display it properly?
it doesn't even exist
i mean yeah..
If I have event sequence started in GameMode, and almost on the start I put Authority Check, I spawn some things, on the same sequence after spawning I call event inside spawned thing to Initialize that thing, is it still running like it's server even inside that spawned actor? Or Do I have to bump authority or run on server somewhere along the line because it breaks?
Hey! Real quick I have the advanced session plug-in, I have it setup and someone can join my session but Noone else can join. This person is in the same state as me however and the other people are not in the same state. I checked if it was a player cap but they can't join even if it's just me can anyone recommend something?
It isn't a firewall thing also
Show the setup of create/join sessions and also did you try printing anything in success and fail?
he cant help sadly so i need help
Epic's doc is pretty lackluster, but in case of Iris, It's even worse
Lol, didn't scroll enough xD
Hey, my server is struggling with a bunch of NPCs. Does anyone know a good way to optimize them on the server side or maybe a plugin that helps with that? I’ve looked around but most optimization plugins seem to focus on the client side
Having a weird problem 👀 . I want to play montage on begin overlap, nothing networked
I just want to play a montage when an NPC is hit
On Begin Overlap -> Find Direction -> Play montage
so again, no intention to network this.
However, when playing as listen server the anim isn't playing
but as client it does
this is soo weird 0o, any suggestion?
where do you playing your anim
Character -> Capsule Begin Overlap -> Play montage
multicast?
try multicast
I don't want to network it
the montage should be played locally whenever an overlap happend
and it's weird because it does go through the play montage code
but it's just not playing the anim
i didn't fully understand the issue. if you're not playing on a listen server and it's triggered on the client side, then overlap won't work on the listen server anyway
it's triggered locally
0 networking
it's triggered on server machine when the overlap happend on his machine
it's triggered on client machine when the overlap happend on client's machine
and I can see that it's triggered on server
but the montage is not being played
🤔
Very strange....
Hey, sorry for the ping! was looking through history here for information on steam sockets. Your name came up a lot from your time looking into them. I was wondering if you ever found a way to get it working with advanced sessions on 5.1?
Hey sorry, I am not using them at all
just using advance steam session
why do you need steam socket? for pings?
Yeah
I can't be much of help, putting that feature on hold / entirely dropping it as I am looking into dedicated server
and ping should work with dedicated server with just advance session
Fair enough, Ty anyway! best of luck in your dedicated server endeavors! I haven't made it quite that far yet lol.
you can look into implementing ping your self, someone has done it and share the code online @teal frost
sending packets and calculating the time
but there is a few caveat like waiting for handshake
I'll see if I can find anything on that. My next option right now is to try beacons.
If I was understanding the documentation right that is.
Guys, does this make sense? I'm just wondering if Server RPC actually comes first trough server and then to Server Spawned version of unit or it goes straight there?
multicast on player controller doesn't make sense to me
only client's player controller exist on their machine.
hmm, yah fair
Server has everyone player controller
So if you tell server to multicast player 3's controller
only player 3 and the server will run the function
and since there is no copy of player's 3 controller in other player's computer. They obviously don't end up running any function.
ClientRPC == RunOnOwningClient
okay so it's the same, it's just different based on where we call it from
like if u call it from server rpc it's gonna be like ''replication'' from server to client
and if u run it from client it's gonna only make changes for client
@normal viper does this make sense?
RPC is just a way to run function
Server RPC = Client telling Server to run the function
Client RPC = Server telling client that own the actor to run the function
Multicast RPC = Server telling everyone with a copy of the actor to run the function.
so the node Run On Owning Client is already running on server? Or usually you first have to call Run on Server and then Call On Owning Client? What is the difference?
It's mean to be used by the server to communicate to the client that owns that actor.
RunOnOwningClient is Client RPC
Run On Owning Client = Client RPC
Dunno if this will be helpful but https://dev.epicgames.com/documentation/en-us/unreal-engine/remote-procedure-calls-in-unreal-engine?application_version=5.4
damn, im just confused because I have the same output in logic no matter if I Run On Owning Client or just run normal event without anything
Haha I'm sorry for idiotic questions. I read these 3 times and probably will more from different sources... I'm just trying to organize it in my brain
Are you running 1 client or 2? Also what setting (listen server, client, stand alone)
It's 2 standalone clients, but the session is set to Listen
btw. the output is good
like its what I want
i just look for what is the difference
so what I'm doing. I spawn Caravan. In Begin Play of Caravan I call to PlayerController, and there I call to Camera Pawn to lock the Camera:
now this event, doesn't matter if I put it on Run On Owning Client or just without anything
it works
and i wonder if it was so stupidly easy and didn't require anything, why it took me so long
So you're just handling cameras as the pawn basically, right?
void AAGNpcCharacter::OnCapsuleCollisionBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
Super::OnCapsuleCollisionBeginOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep,
SweepResult);
// Make sure not colliding with self.
if (OtherActor == this)
return;
// Check the velocity of incoming character.
if (Cast<ACharacter>(OtherActor))
{
if (Cast<ACharacter>(OtherActor)->GetVelocity().Length() > 250.f)
{
EAGDirection Direction = UAGLibrary::GetDirectionFromImpact(this, OtherActor);
UAnimMontage* L_Montage = nullptr;
// Play impact montage based on direction.
switch (Direction)
{
case EAGDirection::Front:
{
L_Montage = *CollisionMontage.Find(EAGDirection::Front);
break;
}
case EAGDirection::Left:
{
L_Montage = *CollisionMontage.Find(EAGDirection::Left);
break;
}
case EAGDirection::Right:
{
L_Montage = *CollisionMontage.Find(EAGDirection::Right);
break;
}
case EAGDirection::Rear:
{
L_Montage = *CollisionMontage.Find(EAGDirection::Rear);
break;
}
default:
L_Montage = *CollisionMontage.Find(EAGDirection::Front);
}
if (L_Montage)
{
PlayAnimMontage(L_Montage);
UKismetSystemLibrary::PrintString(this, FString::Printf(TEXT("%s"), *L_Montage->GetName()));
}
}
}
}
So it's rts type of game and for the time when caravan is alive, i want to keep the player camera locked on it. After it deploys camera will be free.
Before I move on i just want to understand why it works.
@sinful tree sorry for the ping, do you have any idea at all why PlayAnimMontage doesn't play on listen server?
I am not even looking into networking this but play montage work when play as client but on listen server it print string but doesn't play the montage.
I would probably just replicate the focused actor.
When FocusedActor is valid, your targeting component will follow the FocusedActor
I mean, funny thing is, it works 😄 just trying to understand
The function will run on the client that owns the actor (Controller in this case)
The camera is handled locally. So controlling that itself should be fine to run without replication.
Animation stuff usually isn't my forte.... If you're reaching the correct logic there with the print still executing on the server, I'm not really sure why the PlayAnimMontage() wouldn't also trigger. Is PlayAnimMontage() a custom function you have? Maybe there's something else within it that's causing the problem?
The function is the one from epic =(, this is soooo weird
Yeah. So if you can guys imagine. I was getting mostly confused with the Actors that are placed in the world and are not possesed and controlled. And it turns out that I cannot just do shit on them, i have to call to the pc and handle it there and then call back to that actor.. im starting to get it,thanks for help guys! just adoesn't help that most tutorials think you own 1 character and everything already happens in character/controller which is owned, not like actors that on top of it are owned by aicontoler for example
I'm not so savvy with c++ yet but where are you calling that montage? (server, MC)?
OnBeginOverlap -> Play montage
I don't want to network this
fixed it with Enabling root motion and force root lock
but whyyyyyy?
makes no sense
is there a way or paid solution which would improve sync for physics driven actors?
we have lot of troubles with objects being desync between listen server / client
What's your current replication setup?
I think problem comes down to that each client is simulating physics on their side
smoothsync plugin might be worth investigating
but I'm not sure what you are trying to say with "sort of default" and then just simulating physics on the client
like yes... if the client can move the object how exactly is the server going to know when to correct it? do you have some ack step where it sends info to the server to ask for a correction?
Actor positional onreps are mostly just "go here with this velocity" by default
depending on game network settings and quantization etc cvars
AActor::OnRep_ReplicatedMovement
Hmm... let's say after I click on actor, I want to add Input Context Mapping of Actor Selected (which adds inputs like Actor Movement, Actor Attack etc. to my ''right click''). Actor is owned by AIController (not possesed, not owned by player).
Since I'm doing the Selection ''Click'' Run On Owning Client inside PlayerController, after I select the Actor, I can tell him to Add Mapping Context and GetPlayerController[0] to access the Enhanced Input Local Player Subsystem.
Would it make sense? I was trying to plug Player Controller variable (not [0]) but obviously it was trying to Get PC3 etc. which doesn't exists on this client, since he has only his own. So if the Client requests to Add Mapping, and it's all on client... I think it would be safe to use GetPlayerController 0 in this case? Does it make sense?
The alternative I see is after actor is clicked, I call to PlayerController (the variable one) and Player Controller then adds the input mapping that was provided by actor.
Is first approach ok? or I should use 2nd one whenever it's possible.
Why do you need to network this at all?
is the data not readily available?
if the data is already embeeded in the A.I actor then when a player click the actor, simply bind the input.
0 networking needed imo
to the player that select it?
aka the local player
why do you need that info from the server?
unless you need to hide the info away from the client, which I don't see the point.
yea so before my selection wasnt working on the 2nd client, but i think i had component for selection replicated, then i changed to not replicate and also set to run on owning client and it started working, now i skipped client rpc and it still works
so i had made wrong assumptions
a bit 😄
you should established the general design first imo
like what info should be passed to the server from client
in general, don't trust the client
and when you are working on something
ask your self, do you have to network this?
Lets say the Units have a series of commands when they are clicked
Move, Attack, Guard, etc. And you want that info when you select the actor
those info could be stored inside the A.I using data assets imo
so that's already available at the time the actor is spawned
you don't need to communicate to the server, hey server, what's the command the unit has? Give those to me.
Instead you just run the code in your machine, not talking to anyone. Select the actor -> Get the array of commands
in practice it means i click on something, i get info from it and I just process it on the player controller because that is what player own
before I think I was trying to somehow do it on actor ... get playercontroler[0] and do something there and thinking its gonna be for THIS player controller onlky
haha xD
doesn't matter about ownership or anything
you don't need to do a single networking or RPC
the data is readily available in your unit
unless it's mutable then it's in your best scenario to have that data in server only
but if it's a static data like a series of commands.
E.g a dog can only move, and patrol. No Attack command
Then just get the data with 0 networking
yes, i'm just saying that if i do something on actor itself, doesnt mean someone will even see it on network, i have to run it trough player controller, unless it's something on begin play, unless i multicast it from this actor?
One thing you need to understand is
we all running different instances of the game
the server run their application
You the client run your own application
so is every each of the player
And each of those application run their own code
your job is to design communication between instances in a way that the world stay synced
Take input for example
V Keyboard -> Print string V
If Player 2 pressed V, that code will only execute on his application
no one else knows about it
people are not sharing the same world/instance
Takes a while but it will click
once it click... everything make sense
but then you will relaised that's the least of your worry in multiplayer
there are a lot of can of worms
yeah.. i just want it to work coop at best so yeah
but yeah still need to be playable
This might not be multiplayer specific, but if two clients call an RPC at the same time, can multiple RPCs run on the server simultaneously or are they queued?
I just want to know if I can set and get variables on the server using an RPC without messing up other RPCs that are running at the same time (if RPCs do run simultaneously)
What would it mean to run simultaneously given the entire network read is single threaded
like would it switch between the two events
alternating
or do they run one after another
What exactly would the client to server RPC be fighting over?
They would already be distinct objects
Getting and setting variables
What is "they"?
The order of rpcs from distinct clients in mind can be considered completely random
Okay so they do run in order
no?
What
how can you rely on the order, there is lag
You said "the order of RPCs". I just mean "in sequence" not "in order"
I don't care about the order
Just whether they run in sequence
Or alternate
What would this actually look like in practice to have them alternate
Am rpc is part of a packet that has some bits saying execute function on X network id with a payload
Unreal has 'reliable' RPCs that do sort themselves and try to guarantee being re-sent if missed but they don't give a shit about other connections
Afaik
The question reads like Single Thread vs Multi Thread.
2 RPCs send to the Server from 2 different Clients will run after each other.
There is no Multi Threading for that.
I already asked if that's what they meant
the one that arrive first will get proccessed first
And the order in which they arrive, as others said, is not guaranteed.
So yes, you can do stuff in RPCs without worrying about other RPCs. Just keep in mind the order stuff.
The simple thing is to just use unreal insights to see the shape of a network read and broadcast in context
You don't need to guess
Okay but when another a RPC arrives while one is getting processed, does the one getting processed finish first before starting the other one?
They are all single threaded
Okay thanks
There is not some magic async network read
I guess some people do have like an async http thread thing?
UE is generally single threaded in most things.
There is the Render Thread.
And there is the option to run stuff on background threads.
But gameplay relevant stuff usually stays on the GAME Thread.
I think if you know what you are doing you could do a lot of onrep work in task threads but unreal is just heavily single threaded
have you ever done break point in bp and goes step by step? It will be just like that
Probably, but there is also a lot of stuff where UE slaps you if you do it on a different thread.
I think Context Switching is what I meant by "alternating". Dunno if that is the same as multithreading
What does that mean? Like a coroutine?
I think one example of something that can split into sections over multiple frames would be massive large data rpcs that require multiple packets to fill out due to MTU size limits but from the user perspective it is effectively identical as the end result is it being deserialised at once iirc in the latest version
Yeah we did that for bigger Client-Auth SaveGames on the Ascent iirc.
But that was still singlethreaded fwiw
I noticed that if I very gently inch my character forward on a higher latency client, I can end up in situations where a collision happens on the client, but the same collision doesn't happen on the server. The two seem to disagree on the microscopic details of the position of the player. Is it fair to say that this is entirely possible depending on things like quantization and whatever optimizations the CMC is running internally to potentially avoid spamming the server with position updates it might not need to know about?
You can definitely expect difference between Server and Client in terms of position.
The threshold for that is small, but not 0.
This event doesn't run (not owning client?) I confirmed that the actor (bullet) replicates, the RPC runs on the server, and I'm setting the actor's owner to the player controller on BeginPlay. Any help would be huge.
Check on event tick Get Owner of the actor.
So I've confirmed all the references are the same... the prints are from just before the RPC, the local actor BeginPlay, and inside the player controller. Strangely, it works in Standalone mode.
Roger, that's helpful to know 🙏
Would the "correct" thing to do be call an rpc through the player controller instead of the projectile?
I would question the immediate destroy call after the RPC.
Yeah check this first, and I'm not best with advices yet for multiplayer, still trying to figure out and dont want to give you bad info.
In general though, as long as something is owned directly or indirectly by the local player's controller, and it is net addressable(server spawned and replicated or client predicted and name stable) it should be allowed to RPC
This was one my my first suspicions. Unfortunately removing it doesn't help
btw it's like nothing literally happens or what?
try to put more prints before and between each node
if anything even fires
Right, this is where the break is. the RPC just doesn't work
@thin stratus have you encountered desync issues with GAS/CMC when you have a gameplay ability that goes Montage -> Root Motion Source Task -> Montage?
If I do Montage -> Montage -> Montage there's no desync
None of them run at the same time, they wait for events such as montage completing, or something triggering a Wait Gameplay Event (and killing the root motion task) to transition to montage
Have tried various root motion source types but all have the same de-sync
The de-sync occurs at the end of the final montage
I can't really test this but if it was just Source -> Montage I imagine it would still de-sync
And we are making appropriate use of wait net sync to open new prediction windows, as well as flush server moves
RMS that are called after a delay of sorts will have desyncs
You'll need to:
- FlushServerMoves once more
- Recreate the prediction window iirc
- Ensure that Start and End values of the RMS are identical
We're doing the first 2
Not really sure how to do the third, are RMS not already doing this out of the box?
The RMS itself doesn't de-sync but it introduces de-sync for the montage that plays after it
After the RMS completes we flush server moves and recreate prediction window, then trigger the montage that de-syncs
I tested with a 1 second delay after the RMS ends and it still de-synced
That's super weird because if it was out of position it should have completed any corrections before initiating the montage
But the montage itself is de-syncing somehow as a result of previously having had an RMS despite considerable time (1s at least) passing
After the RMS ends we do a flush server moves -> wait delay 1s -> flush server moves -> wait net sync server only -> play montage and it de-syncs if the RMS was used, replacing the RMS with a root motion montage doesn't have an issue
Turns out actors that aren’t visible to the server can’t fire RPCs. Makes sense, but i wish I’d been able to find that in documentation.
Can't tell server to run function (server rpc) from actor the calling client doesn't own.
Also yeah vissibility shuts off replication all together
Yeah, and that was the issue. I ended up sending it through the player controller
You can just tick hidden in game
Yup in general you don't want to give ownership too as that leads to vulnerability
Routing through pc is probably the go to way as well
@mild sonnet you are essentially design the game in a way that client can tell the server who they hit
Doesn't matter for a chill game but just be aware of doing that for competitive game
Client can just hack and kill everyone in the world from anywhere
Yeah, totally aware of that. It was a difficult decision but I wanted total responsiveness. There will be server-side checks in place
There's an article about rewinding brb
@mild sonnet https://vorixo.github.io/devtricks/simple-rewinding/
Is your projectile instant? Or does it travel?
I think that's a sane way to go about it. I'm doing the same with some checks.
It’s a physics-based projectile with ray casts in between each frame to make sure it doesn’t skip through targets
Hmm I'm using projectile movement component
Afaik it can bounce but deffinitly not gonna behave the same way as if it's physical driven I suppose
True
Though that leaves the issue of how to delete projectiles once they’ve hit… anyway thanks for the advice and sanity check
I just blow them up whenever they impact something locally. The one on the client is just proxy for visual.
the real one that get spawned by the server comes later and I have that hidden in client
only the real projectile is accounted for damage
but I don't even know if this is the correct way. Surely there are times when positions are different between server and client. and what if in the client world, the proxy hit something and in the server it doesn't?
Im gonna find out once I can do test
Yeah, I was thinking of keeping a list of projectiles somehow and telling the server to delete them when they hit on client side
It would help fix this issue, or at least indicate if the projectile hit
Out of curiosity, is this true for all Actors, or is this something specific to the CMC? And do you happen to have a sense of what might be inducing this? I'm guessing the engine makes no promises about each instance have perfectly synchronized state at all times, but I'm also curious what exactly introduces that drift. Is it quantization? Maybe some minor changes in state that the client doesn't bother notifying the server about for the sake of network optimization?
integration error from variable timestep
and from float precision
and from timing differences if you're predicting
is there some bug with world compositining right now? I can connect to my dedicated server but whenever I need to use load level instance I get this error
How do you network profile a dedicated server?
I see this in the server [2025.02.02-03.15.05:010][398]LogNet: - Result=MissingLevelPackage, ErrorContext="/Memory/5ZRZPN0MXF9YASXYGH02TE14O_LevelInstance_1,/Memory/UEDPIE_0_5ZRZPN0MXF9YASXYGH02TE14O_LevelInstance_1"
im 100% sure load level instance is broken with dedicated servers because if I use the level instance actor it will work
I have a quick question. What if i want the player to imput a custom name in the menu and then join a lobby. How do i get the server to get the name from the client.
Server politely asks the client for their name.
Client politely sends it back. (From something they can call an RPC from)
Server has name 🙂
Only works if they’re both polite
The threshold is CMC specific, but in theory it's a concept of Prediction in general. NPP/Mover also has it (or should at least).
Other stuff might be more in sync, but there is also no other prediction like this in UE after all.
And yeah, all kinds of PC related differences. Floating Point Precision, Ping differences. It's more or less impossible to get it 100% sync.
Sort of the same reason you shouldn't do == checks on float/double :P
Is GetPlayerController(0) reliable or should I pass reference to my player controller to any class where its essential that it gets the correct player?
In a multiplayer context that'll only really work clientside, as long as there's no splitscreen
ListenServer, fwiw, is also fine.
But DedicatedServer not really.
I just recently pinned some explanation about that
Okay so as long as only client calls it its fine then
yes, should be good
obviously because if it's on client it's always gonna be his player controller, in case if u call it from server, server player controller [0] might be PC3 in reality and it's gonna call it on 3rd player instead of the 2nd one that you wanted
Hi, im having a problem getting a widget that's displaying the players name to be removed when the player leaves, its working on clients fine, but the server player doesn't remove them.. I've tried calling the dispatcher directly on End Play, I've tried calling the dispatcher inside an onrep which is set on End Play and I've tried making it a server RPC called on End Play that sets the repnotify that calls the dispatcher but nothing worked so far, the server player is still seeing the widgets.. any ideas?
Only true on DedicatedServer
It will be the ListenServer's PC otherwise.
Node uses the LocalPlayer array on the GameInstance. That does not contain Client LPs.
I'm creating an inventory system and having trouble adding items to the inventory component
My items are UObject instances.
I've built them so they can be modular, and have additional subobjects inside them to extend their functionality
Some of those "modules" also have properties. Such as heath, durability, etc that need to be replicated
The item objects are being replicated with the new AddReplicatedSubobject system unreal introduced
The problem I'm facing is that when adding the instances to the inventory I need to duplicate them in order to keep their properties. If i try to just create a new object from the instance ref class, none of the properties follow.
Duplicating the objects however is not working as expected.
I recieve this error
LogNet: Warning: UActorChannel::ProcessBunch: ReadContentBlockPayload failed to find/create object. RepObj: NULL, Channel: 6
The server does seem to get the changes, but they're dropped on the client
I've tried clearing flags, renaming and resetting owner but I haven't been able to get it to work.
Any insight here would be helpful
void UInventoryComponent::AddItemInSlot(class UItemData* Item, int32 Quantity, int32 Slot) {
// Two options I've tried:
// Produces error outlined above
UItemData* NewItem = DuplicateObject(Item, GetOwner());
// Does properly replicate, but no properties are transfered
UItemData* NewItem = NewObject<UItemData>(GetOwner(), Item->GetClass());
NewItem->Quantity = Quantity;
NewItem->OwningInventory = this;
AddReplicatedSubObject(NewItem);
FItemStack IS(this, NewItem, Quantity);
Items[Slot] = IS;
}
Found a workaround that seems to be okay for the time being:
Instead of making the original item objects instances in the editor, just make them regular UObjects
This has the unfortunate side effect that I won't be able to access them in the asset registry
Unfortunately it means that every object is also technically a class rather than a data container
Why don't you just destroy it on EndPlay? Why do you need to make any network call for widget?
Just remove the nametag when the actor is destroyed
I'm not sure what you mean? I tried calling the dispatcher directly but it only works for clients, server still see's the player card
When a player logged out, their character get destroyed no?
Wether it's on server or client
sure but its a pre lobby there is no actual character class if thats what you mean
Well does your game mode actually spawn a character or not in the lobby?
Do a print string on end play, make sure it's being run by the server
And make sure you never made duplicates of the widget due to bad code
@blazing spruce try doing switch has authority on end play and call player leave on authority pin
Might be dealing with race condition. E.g the player state gets destroyed before the on rep is called, hard to tell
Testing it now will see, thought it might not be because even the run on server event i tried did nothing
Run on server means client telling server to run the function
You won't be able to do that in player state or game state
As client doesn't own them
2 actors client own by default is the controller and the pawn they possess
Okay so the End Play event does fire on the server, I tried having the switch has authority -> authority -> rep notify and also tried switch has authority -> authority -> call OnPlayerLeave directly but neither work, it doesn't even remove the player card from the clients screen when i run it on the authority pin lol
This is how im creating the widget btw
Thats called on my pre lobby widget, with the OnPlayerJoined dispatcher being called from the begin play of the player state
Forgot to include the function too
Check if the player leave is called if not work your way from there
It's just mean the event is never binded
Player Left is being called, it goes True for one player which'll be the leaving player and it goes False for everyone else.. however something weird thats happening is its being called one more time than it should be, if there is 2 players in the lobby it'll get called 3 times when one player leaves, if there is 3 players in the lobby it'll get called 4 times when a player leaves
If i stop doing the switch has authority before calling the repnotify and just call the repnotify directly its even worse.. PlayerLeft gets called like double the amount of times it should
No idea wtf is going on 😂
Show screen shoot of the print string, need to know who's printing on leave
Unreadable from mobile 😦
This is with switch has authority -> authority -> repnotify
fuck lmao
2 secs
That doesn't sound right
Btw maybe you can just update this with the player array?
OnRep player array -> broadcast Player changed.
Widget construct -> get game state -> bind player changed
Assuming player array gets updated as player leave and join
Still can't read but I think it's just saying server. Would be more helpful if I can read the text.
dunno if that'll be blurry or not
That looks right. You bind it on every name widget
Only one name widget should say true and remove them self since you do the player state == check
Although it is def calling one more time than it should be which is odd
Did the on rep called the player leave?
Because on Rep in blueprint gets triggered on server too
yeah it is, what should i be calling on end play to trigger it? just directly?
although if i do call it directly it calls PlayerLeft waaaay more lmao
This is with End Play -> Cast to GameState -> Call OnPlayerLeave
Because you also call it directly on top of the on rep for server
Also you may be overcomplicated this
I would just check if the player array gets updated
Do a test first see if the player array updates after the player leaves or join
If it does then just OnRep_PlayerArray -> playerArrayUpdated delegate
Widget construct -> get game state -> bind player Array Updated -> Update UI
Hi, I'm trying to setup a simple listen server but I'm having issues getting my friends into my level. In fact I'm having issues to get the correct level on startup at all. Whenever I set the option on the "Open Level" as "listen", the logic breaks somewhere and I can't figure it out. My game is supposed to load on an empty level, which calls a custom event to create a session and load the "LobbyLevel", but whenever I run it it stays in the first empty level (sometimes I get like a single frame of the LobbyLevel popping up but that's it, it's like it's loading the Lobbylevel and instantly reverting back to the previous empty one). If I remove the "listen" option it works fine, but then what's the point cause friends can't join.
I don't know if I'm making any sense lol (it's basically the first 6 minutes of this tut https://www.youtube.com/watch?v=Eg81FgtWbBc)
The start looks ok, but what are you doing next exactly? Show code
also are you using the same ''Base'' for both GameMode and GameState?
as a Parent of yours equivalents
let me check on that
Are there any users also experience network issues with the Mover plugin and character rotation? Rotation doesnt seem to replicate when the player is not moving.
When i join session this node dosent fire. Any idea why? It is supposed to spawn a camera and possess it but its not firing at all.
PostLogin is in the GameMode. GameMode doesn't exist on clients. You should study the basics again, cause not knowing something like this will lead to a lot of headache and bugs.
Unless you are aware and don't understand the IsServer node, which will return true in the Server and since GameMode is always Server, it will always be true in your screenshot
I thought that was the whole reason for onpost login. How would i trigger the server to spawn a player upon joining then
You can do that with PostLogin, you just need to remove the IsServer Branch.
There are also functions in the GameMode you can override.
One of them should allow you to return a pawn class for the passed in Controller
Using PostLogin is not the only way to manually determine the class.
If you use those overrides you can later also just call Restart on the Controller you wish to respawn the pawn for.
so the player spawns as a camera with the main menu (booting up the game.) he starts hosting the game. When a player joins wouldent they just be at the main menu. I would like the Server to spawn with menu and client to spawn in lobby.
Does anyone here have experience making grenades in a multiplayer game? Should using any physics simulation be avoided?
this is regarding actually spawning in the object and synching it land at a location
Clients always join the level of the Server.
If a Player decides to Host (ListenServer), they would need to open a Map/Level with ?listen.
That Map/Level, or rather the current one the Server is on, will be loaded when joining.
If you want to do different things for Server vs Client, then you need to branch in PostLogin or one of the overridden methods to do something different for the Clients.
It's also adviced to have different GameModes and other GameFramework classes with proper inheritance chain for your GameMode, Lobby and Gameplay maps!
Physics Simulation, at least in the past, should always be avoided for gameplay critical stuff.
Chaos might improve this by now, but I'm not sure how far that is. LEGO Fortnite got some improvements, but most of that was Server Auth with Smoothing for Clients.
For something like a Grenade you should just use the ProjectileMovementComponent.
That doesn't have prediction but it has smoothing by using a Collision as RootComponent and the Mesh as a Child of that and then setting the "InterpolatedComponent" to be the Mesh on BeginPlay or similar.
Ok awesome, thank you
Sanity check to be sure, reliable RPCs are guaranteed to be ordered right?
Trying to figure out some shooting netcode
Using one shot per RPC because of accuracy reason
But for simulated proxies, I'd like to use a burst counter (the one you have a guide about)
Using that with one shot per rpc sounds counter-intuitive
So I wonder if I could do both start/stop RPCs & one shot per RPC
one shot per RPC for accuracy between AP & Server, with start/stop for "accuracy" in SPs
That's the goal right now
but wouldn't that lead to jitter in SPs simulating the shots
Should be all you need then yeah, then just increment the counter on the Server each time it's received
Yeah it will
But RPC's would have the same problem so wouldn't matter. My solution was for "automatic" weapons, use the burst counter as a start/stop counter - and just spawn looping FX
Using looping sounds/particles hides it
and for semi auto, just treat it as shot per shot?
yeah
so I'd need to have both start/stop & shot per shot rpcs somewhat right
or maybe a way to put the start/stop in the shot rpc
Although if someone tap fired an automatic weapon you'd basically get the same issue hah
IIRC I had start/stop RPCs for weapon state and per-shot RPCs
Wasn't too heavy?
nah
100 players, no probs. Obviously took up a large amount of the available bandwidth but it was a shooter so.. seems reasonable to spend most of it on shooting
You probably could pack it into the shot RPC though, i.e. "bLastShot" or something
Yeah I remember talking with you in the past about HLL's stuff
My current implementation is somewhat inspired by it, but I also incorporate hitscan for the close range shots
Well we were ShooterGame-based so a lot of the fluff came from that
that way I can have a per shot RPC + hitreg in one instead of two rpcs for close quarters
wouldn't be able to know if you release your attack button after the shot
which would probably be the case most of the time
The per Shot RPCs can't possibly be reliable though or?
Mainly asking, cause the bLastShot being dropped randomly would be problematic :<
per shot is reliable yeah
explains why the budget is mostly taken by shooting
i'm tempted to make extremely high rpm guns only use start/stop
but it would cause desync in magazine bullet count
yeah they were reliable 😄
couldn't not be really.. don't wanna be missing shots
Start/Stop only works if you can somehow guarantee that character movement is up-to-date server side when you fire the shot, and that the server is moving you in lockstep with those shots
Hence UT had a really tight coupling between weapons and CMC
Otherwise it just falls apart really quick, and your shots go nowhere near where you're aiming
I've got an actor component that's added to a character and on said component, there's a var for a data asset. Now, when a new player joins, this var is null, is anyone able to point in the direction of what's wrong?
Is that a replicated variable that you set after character gets created and expect to be able to read from any present and future clients or something you set from the editor?
Something set via the editor.
Do you add your component on runtime?
If so, is it a replicated component and added from server or all clients add them locally to each player?
No, added via the editor as part of the character BP.
Hmm then there shouldn't be any multiplayer related problems with that from what I understand
Is it possible your defaults for component itself and the component's instance on character different?
Or somehow modifying it after character is being created?
Not that i'm aware of.
This is how I define the var on the component.
UPROPERTY(EditDefaultsOnly, Category = "Input") TObjectPtr<UGASInputConfig> InputConfig;
Not sure if that's correct or not.
I can't see any problem as long as you set it to something in BPs as well, sorry
Oh wait... I had my validation checks the wrong way round for my logs. 😅 Turns out it's not finding the input component on the owning pawn.
What does LogOnlineSession: Warning: STEAM: Failed to respond IP:<XXX.XXX.XXX.XXX> upon calling FindSessions trying to tell me?
The given IP is also mine so I don't get what's the problem
I feel like I need to re-learn steam OSS from scratch every time when I'm trying to set it up on a fresh project
guys, is it correct spot to catch players who's clients get disconnected unexpectedly? Due to network problem or forceful client close?
virtual void Logout(AController* Exiting) override;
I'm trying to prevent player pawn to get destroyed, just after player closes client. Want to keep it alive for some time
If I call GetPawn on controller here, seems like it's already NULL. so a lil bit too late
Hey all, I'm looking for a sanity check in regards to a function I've made that's supposed to toggle the player's state between their default state ("mech mode") and their alternate state ("ball mode"). I seem to be running into a snag where the client and server have opposing values for a boolean on pressing the button for the first time (in other words, it seems like the default value of the boolean is different between client and server). After that first press, on subsequent presses the client and server "sync" to the correct boolean value, but in actuality the other properties between client and server (such as floor angle, breaking friction, etc.) are mismatched between client and server and cause the client to constantly stutter when updating movement/location due to that mismatch.
(In the first two images, Orange is client, Blue is Server. In the second pair of images, the boolean values printed are opposite (client says true, server says false) on initial press, while on the second press, the values match up)
And here's a object debug showing this interaction.
Any clue why this would be happening? The boolean property being read/set is replicated btw.
Maybe I'm missing something obvious/critical such as "don't use branch nodes with booleans set on the client" or something like that, in which case an alternative would be appreciated.
(Disregard the fact that true and false are flipped in the branches compared to the prints, I tested various ways of hooking these up and came up with the same result.)
What’s the point of replicating the value if you’re just gonna multicast and having everyone set the value themselves? That’s why you’re getting out of sync
The whole pattern you have looks super weird.
It more or less should look relatively similar to this:
Client flips switch -> Tells server they flipped switch -> Server sets variable that’s probably a repnotify -> everyone gets the update in sync.
I see. I was following this method but it does indeed seem quite obtuse: https://forums.unrealengine.com/t/help-replicating-set-capsule-half-height/1720992/6. The apparent reasoning is that character movement component doesn't normally replicate capsule half height/radius property changes (which I found to be the case in my own testing) apart from when changing the movement state of the character (ie. beginning or ending a crouch action).
toggle the player's state
State -> RepNotify
Under what circumstances does the "Reliable" checkbox of an RPC start to matter? Most of the time most of the RPCs go through without you checking the box.
I understand the general advice of when you want to use it and when it's not needed, but what are the circumstances of an RPC being dropped, and Reliable saving the day? Is it about packet loss? Is it about there being too much information to be transmitted in one packet that the RPC doesn't fit into the packet, and gets effectively dropped unless Reliable is enabled?
Reliable is when it HAS to happen
Even if it happens later, like setting your name
VS info that'll be stale if dropped like setting your aim direction
My challenge is some folks on the team believe it's entirely optional because RPCs never get dropped in practice, and this is just people being sticklers and being dogmatic about something that doesn't make a difference. I don't think I've personally seen instances of RPCs being dropped, so it's hard for me to show them a repro of why this is essential.
So I'm trying to get to the bottom of the underlying issue that makes this checkbox worth checking.
Do you guys not test with some amount of packet loss etc?
Just leave 'em all unchecked. Then, when you inevitably get a dropped RPC, go back and redo the work that could've been entirely avoided.
Sure do, but I suppose that one particular packet being dropped doesn't always happen
Yeah, figuring out why the client is suddenly out of sync is going to be rather unpleasant due to this
If you're the network lead, then tell them these are your guidelines and you won't approve any PRs/code that doesn't follow it. If you're not the network lead, then bring this up to your network lead. If it is your network lead's guidance, then just do it, but document that you informed them of your concerns.
Honestly I make more things reliable than unreliable these days. With the obvious exceptions. But I generally only like to have one central RPC for most things, I really try to minimize the amount of RPCs in a project
RPCs never get dropped, until they do
Like generally something similar to a transaction that can mean multiple things. The good part is you can pack the bits of that struct then just throwing a bunch of properties in the RPC
and if it does when you expect it to not happen, your game will break
The less RPCs you have the happier you’ll be
a client getting out of sync sounds more like replicated properties arrent getting used though...
Pretty sure I plug Reliable on every one time RPC
Just not on the ones that are called so often that them dropping doesn't matter.
The point here is though: There are very little amounts of RPCs in the projects I work on :P
Most of the RPCs come down to:
- Inputs -> Reliable
- Movement -> Unreliable (on tick)
And sometimes something the Server tells the Client, which is often important, so reliable
The majority of replication is usually state, which isn't done via RPCs anyway
Am I correctly understanding that an Actor Component with "Component Replicates" set to false will still have that component execute BeginPlay (and the rest of the lifecycle) on the client? The replication part is saying that we allow its replicated properties to replicate, not that the component doesn't actually exist on simulated and autonomous proxies?
Yop
The Components are usually Subobjects, created when the Actor gets created.
If the Actor gets created on the Client, e.g. by replication or by being placed into the level, so will its Components.
An Actor placed into the level also doesn't need to be replicated to run those events
BeginPlay/EndPlay/Tick are inherently not Multiplayer related fwiw
Cedric I’m still waiting for your blank UE program ;P
Oh
The door bell went, gotta go
Honestly, it's 9PM and I'm still working. I just don't have the time
Honestly I wanna see how much work it would take to write a simple Slate UDP messenger app
Like, ICQ? :D
Probably way harder then it would be with the windows socket API and ImGui 
How about you use UE
But then with an ImGUI integration
Just for the sake of it
And to spit on Epic's internal one
How about we don’t, but we say we did
I need to get valve’s socket API integrated in my engine but there’s a thousand other things I need to refactor first
You know, if I have to figure out a Slate UDP messenger app, how about you figure out a UE ImGUI (not THE ImGUI, but whatever Epic created now) UDP messenger app?
I think that's totally fair
I wonder who quits first
Wdym whatever epic created now
Me. I have already quit before y'all began
Ah, you don't know yet
😮
Epic has their own immediate mode for Slate now
We shall act like this doesn't exist. Cause I like our internal ImGui implementation
This is just supposed to be an API you can use in other projects?
Intended for creating tools. Available in the editor, in cooked builds, and for programs without the engine.
The last part is why I suggested you figure the app out with that
And I use slate
I will, of course, only find time for this in 2027 or so
How about we alternate writing lines of code?
haha
I write one line, send over, you write one
Well finish in 10 years
But we’ll have gained half the knowledge of a real dev
We can also have 2 more lines be generated by ChatGPT and its chinese clone.
Wonder how far that gets
We would be down to 1/4 of the knowledge and 1/4 stolen crap from the internet.
Considering how much games these days are pumped out with “write me UE multiplayer game pls”, I’d say a pretty good chance
Can someone please post a proper multiplayer question before I get reported for derailing again
Ok I digress
ARE YOU SHITTING ME
Not that
Well now our messages look weird.
How do I make a multiplayer game?
I see
Okay I’m done memeing before I get in trouble
We don't even know if this is an honest question.
Let’s circle this conversation back to a good topic.
Less RPCs in a project = happier dev
One off single responsibility RPCs bad (in most cases)
most cases I found myself using RPCs when starting should have just been replicated properties
I learned a valuable lesson the other day about replicated properties vs RPCs. Late player joins have a way of reminding you when you should be using the correct one
any time you change something stateful you have to use a replicated property
What gets a little frustrating is having to wire up reactions to replication once you have multiple independent properties being replicated, things seem to spaghettify pretty quickly there.
I have been doing more atomic replication of the entire set of properties for each actor more recently, and that seems to reduce the spaghettification a bit
that sounds really inefficient ngl
Not only late player joins.
Relevancy has entered the chat
Imagine your map is a bit bigger and someone destroys a barrel that explosed and changes its state to now be broken and burning.
Players on the other side of the map won't get the explosion part (That should be an RPC or something long those lines), but they want to get the update of the mesh and the particle turning on when they get closer.
Just make everything always relevant
(pls don’t)
Make sure you make the whole thing, then just add multiplayer at the end.
Why doesn't rep notify just have a built in time mechanic so you can play explosion if recent or just show burned barrel if not recent?
You could wrap all your props in a timestamp struct but it seems like that'd be useful.
Is there a ReplicationReason?
I feel like that’s way outside of the scope of what the system that handles rep notifies should do
Something the user should implement
Hm, I get the idea, but I wonder if you wouldn't run into the problem of multiple changes to the same property not being visible to the user.
Maybe a ReplicationReason on the client side. Just a way to differentiate between "this data actually recently changed" and "you just now found out about this old change"
Then you could switch on that to choose whether to play the transient effect or just the persistent one
Then you can just add a float to your replicated property and set that with the Server timestamp
Then you can locally compare if you want.
But yeah, it could be useful
Who was talking about a better network clock a while ago?
Not sure, better network clock is pinned for a while now
I experimented with repnotify but must not have tweaked the function sufficiently to make use of it. I'll take another crack at it and report back
MLA format please
I've been reading alot about unreal networking. But there is still one question open.
If I'm using the SubsystemNULL the docs state I can create a session which will work in LAN only.
I dont actually care about sessions and matchmaking. I just want to host (play as listen server) and have a friend (not in LAN, but over the internet) join the host. Probably using ipaddress + port, and perhaps port forwarding if neccessary. Is this possible, or do I really have to use a online subsystem, like the one for steam or epic games?
Totally possible
open IPADDRESS
Also just to be clear, by state, I don't mean an actual enum or movement state or anything.
Port forwarding will be necessary like the good old days
thanks, i guess OpenLevelByName + "listen" in the opens and open IPADDRESS as console command will suffice for this. Will I need port forwarding?
aight, thanks buddy
But you can even do it from the editor.
State isn't only that
ohh, would like to know more about that. Any docs for this?
Haven't reached the point yet where you google something and find your own answer on the forums?
Just press tilde and type, also you can run console commands from BP as a hacky way to put it in a UI
Oh yeah many times.
You will need port forwarding, yes
7777 by default
Otherwise the connection will be blocked :P
That's why people opt for Steam etc. as that goes around the problem
For tightly-timed operations that require a player press a key on time, what do people typically use on the server to validate that the player did the operation correctly with respect to their local timeline?
E.g. the client player needed to press F within 200ms of the server telling them they need to react. But then say the player has a latency of 300ms. By the time the server hears back from the client that window of key pressing has long ended. Is the solution here for the server to look at the average ping of the player (I think the engine tracks that for you on PlayerState) and then do the math of "is Now - That Specific Client's Latency within the acceptable time window?"
In this scenario there seems to be no way for the server to be ignorant of each client's latencies and still make the experience feel correct. You could also have a generous grace period for late updates from the client, but that doesn't adjust to each client's latency. Of course at some point the latency is so high that other players start to feel like you're breaking their experience to accommodate the one high latency client among them. So perhaps having a fixed grace period of some reasonable latency such as 150ms is "GOOD ENOUGH (tm)" for most intents?
You would generally use timestamps to subtract out the latency from the Player actions.
IMO, high latency Players should always be at a disadvantage in this case.
If its a race to see which Player performs the press first, it should always be first come first serve, in that, if a lower latency Player returns a result to the Server first, but has a slightly slower time than the higher latency Player, thats to bad for the higher latency Player.
Players with high latency should come to expect a somewhat degraded experience, within reason.
Since there is only so much you can do to get around the laws of physics
Before you destroy the experience for others
When you say timestamps, is this clients sending the timestamp to servers, and servers sending timestamps to clients, when notifying each other of that operation?
And if yes, is this them sending that synchronized server timestamp value, or their local timestamp?
You would use a synced clock. Yes. Server timestamps saying this is when I sent the request, Client timestamps back to the server with when they ackked the reciept and when they sent the response.
From there the Server can work out if the Client pressed within a threshold value
Synced clock == GetServerWorldTimeSeconds()? Or is there something else I should look into?
Was reading https://vorixo.github.io/devtricks/non-destructive-synced-net-clock/ just now.
Use the one from the link
Is the idea here that, yes, we could achieve a similar result by looking at the latency of the client, but latency can spike, packets can be dropped and reordered, so we could be off by quite a bit, and timestamps will give you more accuracy here, assuming that you are doing the synchronization correctly?
Yeah, its exactly accurate. Just using the latency is effectively making an assumption about what might happen and when
If thats good enough for your needs, then use that. But if it has to be accurate, you need a more appropriate solution.
Keep in mind that Latency is an average. It cannot predict the future.
siliex informed me recently (by recently, I mean like some time last year) that the built in clock that UE has has gotten a lot more accurate since that article. To the point where that article isn't needed for most scenarios anymore. (Could be misremembering a detail though)
Fair enough, I could imagine that to be true, Im behind on a lot of stuff like that since Im not in UE5 yet 😦
Oh yeah - you're still a dinosaur
Maybe it wasn't siliex. Maybe someone else. But I do recall it being brought up.
So, I would test first before writing all that extra code @vapid gazelle
THat's a great detail, thanks so much!! I would have had no idea.
im trying to understand why on client im getting SetMovementMode called with MOVE_Walking right after i set it to Flying, on listen server CMC i dont have this issue
could it be because it did a ground check ?
@thin stratus @pallid mesa lmao... did you guys know that wait net syncs are called in reverse order?
I was using them with a psuedo anim notify system that uses timers
And the end would get called before the begin each time
Just thought that was something worth putting into the general pool of knowledge if you guys didn't already know, in case it catches someone here out lol
i just happened to read today this task 🤣
Absolutely bizarre right?
Couldn't just do a copy...
We're probably putting this on UDN
Gotta yell at those clouds again
I just yelled at them for putting checks in AnimNode_FootPlacement
Game crashed coz it got a NaN for something as meaningless as IK 😄
Glorious
what does the client handles over the server regarding controller and pawn rotation ?
because using SetActorRotation on server wont do anything to the local client
If I recall character rotation might not be replicated by default
Less RPCs in a project = happier dev
Less RPC == More GAS == Me sad
:)
I'm a freaking numpty
When I linked my classes so I could have sprint + stamina for testing the obvious use-case , I missed a single reparent: FSavedMove_Character -> FSavedMove_Character_Stamina
So was getting weird de-syncs
(Finally getting back onto this)
Its weird tho, I've fixed it all up, should be back to original state
But now I get intermittent de-sync constantly while stamina isn't 100, and yeah local client is still receiving stamina that isn't 100 despite server sending 100, some net error or something
Maybe its another simple mistake but it doesn't look like it
Server sends 100.f and local client receives it as 0.97f or something similar
I was about to ask you if you got it working lol
Anyways i was thinking about PostUpdate, and i'm starting to wander why we set forceNoCombine there too.
Cause, as far as i understood, PostUpdate compares the start state with the end state of the same move, while CanCombineWith, compares the initial state of the old move and the new one, which effectively is the same as PostUpdate, no?
Is it to catch changes for variables that might get switched back before the next cmc tick?
Did you upload the changes on github or something? Today i should have time to take a look if you want
Did just now. Check the stam_dev branch
I haven't updated to your changes due to the de-sync, went back to the original which was working
Not sure why de-sync is there now, might make a new project for testing
Ah if you went back to the original the problem was that you were not sending the PostUpdate stamina value, so the server was comparing its end state with the clients start state of the same move
That shouldn't result in the client receiving 97.f when server sends 100.f should it
And it never had intermittent de-sync previously
I've always tested with high latency of ~150ms ping, so I would have seen it then too
Idk with the original i always had desync problems if the stamina change in a tick was greater than the correction threshold
How are you testing for this?
I'm printing the stamina to screen, the client keeps toggling between ~97 and 100
Looking at ClientReceive... something, I'm making a new project so IDE is closed down... it is receiving 97
And looking at ServerFillResponseData it's sending 100
Imma have to look at this further once I have new project setup, blank slate can help sometimes
@twin vessel
Server sends 100, client receives 98.5...
Wonder if I handled the serialize wrong
Actually yeah I must be
This is not ever getting called meanwhile it continues to send data
OK I see it, it just keeps sending the last serialized value when a correction last occurred
Corrections shouldn't be occurring but that's a different issue
Bloody hell ( @twin vessel ) I got it
@thin stratus do you remember way back in the past I noticed there is an earlier point prior to OnClientCorrectionReceived() called ClientHandleMoveResponse() where we don't need to use GetMoveResponseDataContainer() because it passes in a const FCharacterMoveResponseDataContainer& MoveResponse?
It's not the same. I thought it was. I wanted to use that function because it looked more correct even though as you said at the time, you can get it anywhere at a later point, but also because the FVector ServerGravityDirection was introduced which means I had to use some pretty ugly looking macros (not actually a big deal).
But it actually causes de-sync, there is something happening between those two points that causes it not to serialize corrections properly, not only because IsCorrection() is failing when it shouldn't be, but it's also causing false de-syncs as well.
So yeah. I'm going to update everything.
Wanted to avoid this ugliness but w/e
Might be cause ClientAdjustPosition_Implementation is called by ClientHandleMoveResponse only if the move is !MoveResponse.IsGoodMove()
While you are setting the stamina value regardless of if the move is good or not
Yeah that looks about right
@twin vessel I'm glad Epic cleaned up their versioning macros btw, can do this now instead of checking major/minor version
Oh that's cool
Thing is, my new movement modifier implementation uses ClientHandleMoveResponse and has no issues, no unnatural de-sync
I'll update it too just in case it has some sort of edge case 😄
Yeah I'm pretty sure I commented on the annoying need to redo the checks for corrections etc when using that function instead of a later one. Hm
Actually my modifiers specifically look for IsGoodMove()
And use it to apply client auth
So for modifiers it's fine to be there, or rather, kind of needs to be there
It might have gone over my head 😄
what does the client handles over the server regarding controller and pawn rotation ?
because using SetActorRotation on server wont do anything to the local client
im wondering if the best method would be a replicated var (i want to set a specific rotation value when player starts climbing)
@lament flax pawn rotation isn't replicated afaik
not every game people want to replicate rotation
as for the control rotation, that's replicated
take a look at getBaseAimRotation
if you want to replicate rotation then yes
might want to set the RepCondition to SkipOwner
for ProxiesCharacter just interpolate to incoming rotation every tick
but you probably don't want that for autonomousProxy (The character that you own)
@twin vessel I'm headed to bed but let me know if you can see the error with this, it gets corrections every frame 😄 Without the use of PostUpdate it works fine without any issue
https://github.com/Vaei/PredictedMovement/blob/stamina_issues/Source/PredictedMovement/Public/Stamina/StaminaMovement.h
https://github.com/Vaei/PredictedMovement/blob/stamina_issues/Source/PredictedMovement/Private/Stamina/StaminaMovement.cpp
Hey,
we have a working and fully functional Multiplayer game. We got the response from playtesting that the gunplay feels of/delayed. This is potentially how we handel the shooting logic via network.
We are doing it like this:
Client_PressFire -> Server_FireWeapon -> Server_CheckAmmo -> Server_GetAim -> Server_SpawnProjectile -> Server_ProjectileHit -> Server_SpawnHitEffects
This can cause a delay as everything runs on the server and the server then broadcasts the hit effect. We have done it this way to eliminate the risks of easy cheating. I know there is the different approach where everything runs on the client and the server needs to confirm it. I simply can't get my head to wrap around it. I'm so stuck in the way we currently have it that I don't know how such a post confirmation should work at all.
Any good tutorials or hints?
https://www.udemy.com/course/unreal-engine-5-cpp-multiplayer-shooter/?couponCode=JAN-10-25-MLTSHT
i would suggest this course. It really helped me wrapping my head around client prediction and server side rewind
Are replicated ustructs delta-compressed by field? e.g. if one field changes, will it replicated whole struct or just one field?
If you want the most comperhensive video tutorial addressing multiplayer FPS that involves Client prediction, server auth and rewinding.
Then check Stepehen Ulbardi multiplayer FPS tutorial in udemy.
No clue why, but apparently in this branch Super::ServerCheckClientError returns true directly before even reaching the stamina check, which is why you are getting corrections
one field
Keep in mind if you are changing individaul fields in different replication frames, you may get updates in the wrong order. The struct could be in a state it was never in server-side, so if you care about atomicity, you'll need to implement NetSerialize for it
But then, you lose per-property replication - but as a bonus, you might be able to pack things more tightly. You also skip the extra 16-bit property header per-property
Any advice on why my c++ First person character isn't replicated to the server/client?
Hello guys hope you are having a good day!
so I have this setup ```c++
void ABaseItem::AddNewItem(AActor* ItemOwner)
{
//Check if valid owner
if(!ItemOwner) return;
SERVER_AddItem(ItemOwner);
}
void ABaseItem::SERVER_AddItem_Implementation(AActor* ItemOwner)
{
if(HasAuthority())
{
MULTICAST_AddItem(ItemOwner);
}
}
void ABaseItem::MULTICAST_AddItem_Implementation(AActor* ItemOwner)
{
bIsMaster = true;
UE_LOG(LogTemp, Warning, TEXT("Test"));
AttachToActor(ItemOwner, FAttachmentTransformRules::SnapToTargetIncludingScale);
//Hide actor and remove its visibility when attached
SetActorHiddenInGame(true);
SetActorEnableCollision(false);
}```
The add NewItem is called from a widget from the local client. The function you see here is in an Item object placed in the game world. Why does the Server RPC work but not the multicast. I am checking authority as you can see, but still the multicast will only be exc once. (proven by the log). Am I getting sth. wrong here. Shouldn´t the Server RPC fail??? (I have no netowner set up, breplicates =true. Nothing else)
thx for any help ❤️
Have you actually verified the RPC gets called (as in the implementation)?
a general reminder you cannot call server RPCs on actors you do not own
thats what I thought
what do you mean by that? Sry can´t really follow you
"Why does the Server RPC work but not the multicast" from your message
how did you verify this when all it does is call the multicast
I call the server event in the first function and check for authority which it has
so you didn't actually verify, you just assumed
did you actually add a breakpoint to the MULTICAST_AddItem call?
no I tried it and put an LOg thingy there
and see if it gets hit?
does it make a diffrence if I am using log or breakpoints?
I mean both verify that it got exc no?
I prop misunderstand sth though
well you should generally be using debug tools so you can actually inspect variables and such
though I'm not sure this is the best thing to be using a multicast rather than a variable with an OnRep
since it's state
yes because if I was out of relevancy distance while someone added an item, and then got closer, I wouldn't see it in the correct state
So you would suggest switching a bool state and triggering the rep event?
well I'm making a lot of assumptions here, but generally for a drawn/holstered weapon, you'd be primarily relying on the state changing to properly display that on other clients
(or item, not strictly a weapon)
yeah totally get your point! is there some cleaner way then just switching a bool?
well if it's a binary state, what's wrong with a bool? if you want to deal with multiple state transitions then use an enum or something
alr. thx you very much! ^^
Returning true means a correction is required
It only returns true prior to the stamina check if Super::ServerCheckClientError returns true
Otherwise it performs the stamina check and also returns true if its outside of the NetworkStaminaCorrectionThreshold
Otherwise returns false
I don't think anything has changed there in a very long time, I can't see any problem with it
Have a question about replicating actor variables so here i add a reference to my ground base and its location on begin play in my supply drops ground base actor
GameState->AddSupplyDropLocation(FSupplyDropInfo(GetActorLocation(), this));
{
SupplyDropLocations.Add(DropInfo);
}```
into a struct thats gets stored in this array in the game state
```UPROPERTY(ReplicatedUsing = OnRep_SupplyDropLocations)
TArray<FSupplyDropInfo> SupplyDropLocations;```
Now when the on rep function is called the ptr is always null but if i add a delay before adding this array member in begin play eg 10 secs the ptr is valid is this because the ground base actor hasent been replicated and spawned on the client by the time that client receives the replicated array?
chatgpt says
When you call GameState->AddSupplyDropLocation(FSupplyDropInfo(GetActorLocation(), this)); on BeginPlay, the server is adding the supply drop info (including a reference to the this pointer) to the replicated SupplyDropLocations array. However, clients might not have spawned and replicated the referenced actor (this) by the time they receive the updated array, leading to a null pointer on the client.``` is this correct ive never ran into this issue ever
As above, I'm pretty sure that was correct
I missed super call in PostUpdate 
Should fire myself
is this because the ground base actor hasent been replicated and spawned on the client by the time that client receives the replicated array?
That is a very very common pattern, there's no guarantee for replication order, so probably yes
race condition!
Any ideas on how to work around this i don't really want to use a delay here it doesn't seam appropriate and this still won't work for join in progress as this same situation can arise
Ig I could just use begin play on the client add the array elem and call whatever the on rep was doing
That's probably smarter, yeah
That's what I'd do
The OnRep fwiw should call once the actual pointer becomes valid, but maybe that's broken for structs
Does mean it can call twice
Otherwise any kind of OnRep for actors would be a problem
Ahhh i did see it call twice 1st with null and 2nd with the valid ptr maybe I can make this work
Hello guys ! 👋
I am working with unreal engine 4 on a multiplayer project. I code via blueprint. The multiplayer uses a listener server. Each player controls a Pawn.
I would like to apply different colors:
- green or yellow color for the body if the Pawn is locally controlled or not
- red or blue color for the head if the Pawn's controller is the client who host the game
For the body color, I use the "IsLocallyControlled" node, no problem.
But for the head color, I can't find the right way to know if the Pawn's controller is the client who host the game
I tried with the "GetLocalRole" and "GetRemoteRole" nodes from the Pawn's BeginPlay, but withou succeed.
If Someone can throw me in the right direction pls 😉
Im not sure about UE4, but I think your looking for NetMode (not NetRole) and check for ENetMode::NM_ListenServer
NetMode being the important keyword for you, perhaps you find some blueprint nodes for that?
Thanks for answer Ribyn !
But nothing about this "NetMode" in UE 4.27 😢
Is there another way to check that ? like test if the controller has hauthority, but on client ? (client do not know about others PlayerControllers, right ?)
I lack experience to you give you proper guidance. But this is how I would do it in CPP UE5. I did notice however, that I was unable to find aynthing NetMode related in the blueprints, so it might not be exposed to you.
Perhabs you can make a cpp in UE4, write a function which checks that condition for you as "IsHost()" and expose it to you blueprint? (set the cpp as parent for that blueprint)
Pretty sure, that is what you are looking for, and it simply isnt exposed to blueprints
Do you want that head color to be in sync on everyone?
Yep !
Then you'll need to set a RepNotify variable on the server anyway
And IsLocallyControlled is exactly what you would use for this too
Given you need to call the set color stuff on the server, IsLocallyControlled will be true only for the ListenServer's own pawn
Not sure why you can use it for the body color but not for the head
Logic is the same
Are you retrieving PlayerController by index?
2nd section of the guide https://wizardcell.com/unreal/multiplayer-tips-and-tricks/#2-beware-of-getplayerxxx0-static-functions could help
Maybe I wasn't clear enough. Take a look at this screenshot :
The Pawn BeginPlay :
On client, I can't figure out to check wich one of others pawn is controlled by the server (in case of listen server, the client who host the game)
The RepNotify must be set on server side, but on BeginPlay Event or Possessed Event ?
if an actor is dormant and a component prop wants to replicate
it will fail right?
@teal flareserver will always be authority
so if it has local controller and authority its server (for listen server)
if its autonomous proxy then its controlled by a player locally (not server)
if its simulated proxy then its a simulation of the pawn on another client
as a non-host client, he wants to know, if one of the other client is the host
Can I Check that on client side ?
yes so check is local controlled and has authority == local client listen server
as a client you cant detect the host
client will see Simulated Proxies and its own autonmous
BUT
you can check RemoteRole
let me explain
LocalRole < role of the pawn as you see it
RemoteRole < role of the pawn as it comes from server
so if pawn local role is simulated and remoterole is authority == host
if pawn local role is simulated and remote role is autonmous proxy == other client
though i need to verify, been a few months since i did this stuff
normally if you want to set the skin, you would set a replicated property, and just do it there
Keep in mind BeginPlay of a pawn is too early to check locally controlled stuff on the client
UE4 doesn't have a proper callback for when the Pawn is possessed on the client though. UE5 should have OnControllerChanged which is a better place to do these checks
Ok, that was the problem. Does I have to continue my tests on Pawn's Possessed Event ?
OK guys, I got it !
It took me a while to understand, Thank you (so much !) @meager spade & @thin stratus to take time to explain 🙏 🙏
(SwitchHasAuthority is useless)
Is this some client spawned pawn that’s being possessed?
Nevermind I see you edited your message 🙂
If I understand what you mean, yes. OnPostLogin, the PlayerController ask the GM to spawn the Pawn
I was just curious why you had a switch has authority
But you answered it
Making sure you knew it was useless
Possess only calls on the server
In UE4 you are pretty much lost on that stuff
If you aren't very far in your project you should probably use UE5 nowadays
To have a complete answer about how I acheived this
Did someone said switch has authority useless?
In this context he was using it, it was
Not really, I justed start making separated modules. So I think I can "transfer" them into UE5.
The only problem is that UE5 is lagging so much on my computer (Intel i5-8400 2.8GHz, GTX 1060, ssd, 16Go RAM)
Turn off the more expensive features
You can read Laura's article to fall back to Ue4 settings in UE5
I think your system is pretty ancient
16gb ram and a 1060 is generally not up to date enough anymore. But I get it, hardware is expensive
My 3060 barely tanking UE5
With lumen it's like 40 fps with few character
Could be my fault though
I put my 2080 super at home to rest and grabbed one of the 4070 from the office
That sounds way off
I had a 3060 before upgrading to a 4080Super.
In UE4 it's constant 300 fps ++
I mean you can stay with UE4 too. But UE4 requires even more often to use c++
By modules you mean plugins, right? Not
modules specific to your project?