#multiplayer
1 messages · Page 249 of 1
I mean you can still join, in theory. If you have a session result that is old, it might still be able to connect via that, even if the session isn't actively joined, not sure.
You shouldn't destroy the session though.
Just deny people in PreLogin/Login
Hello guys!
So I am having this problem when spawning an Actor on the server
After spawning, I want to modify it, meaning, assign a ref from the object to a variable in a widget for the Client. When I call the RPC on the owning client, the "Item Ref" from the spawned actor is not valid though. This is because the actor hasn´t been spawned yet, but how can I ensure that the function "CLIENT_AddSplitBulletCreateWidget" has a valid reference to the item?
Thx for any help ^^ ❤️
Item input not valid
By using RepNotify/OnRep instead of an RPC
Woudn´t that also trigger for the other clients and not just for the owning (The blueprint is in an actor component)
You can limit the replication target of variables
replication condition owner only!
oh true
I forgot, one last question, should that be a soft ref that is getting replicated?
cause I heard somewhere that you shouldn´t replicate ref but only soft refs is that a thing?
im not sure that's true?
I replicate both. It depends on what you want to replicate.
For cosmetics, since i will have tons of them. I replicate the soft ref then the receiving end can load it at its own time.
thx guys ^^
seems like now without delay enhaced input is not init? 😄
now you see if you looked at the logs you would see mad spam about node == none.. because your simply not waiting for the object to be ready
just try it with any reference in any bp to any other bp ( how do you know when they loaded)
you simply do not unless it has a magic event
yes this is why interfaces can help
its stops all the question mark when various other events trigger the crucial event you are interested in and all other variables are satisfied then you can proceed
No, interface has nothing to do with hooking an event for init.
why do you keep thinking every single thing i say has nothing to do with anything?
If anything that just make it harder to debug
Its a interface
it just makes life 1 tinny little bit easier
events wont be solving shit
If you think that's an attack then just get a third opinion.
I don't use that event, nor I have editor atm to check.
If it's true that it's server only. You can try running client rpc on the function that get called on server.
Move the input binding to the client rpc function.
Yeah on possessed is called on server
So running client rpc there will do the trick
But hooking to proper event is better. OnAcknowledgePossesion for example is only called on client.
But it's not blueprint exposed for some reason
did you press the eye ball
Nahh no such thing
oh
It's in the engine code and not marked blueprintable
ah
But anyone with cpp knowledge can just override it.
yeah override it baby
time to add C++ to toolset 😄
when you got c++ you can create a sub class of any thing
it's just getting crowded in there 😄 😄
C# for Unity
Javascript, HTML, CSS for Photoshop
Python, QT for Blender and Maya and custom applications
andddd all other api's such as google, jenkins etc..
man 😄
I'll add one more 😄 hopefully my head won't explode 😄
when you got c++ also you can .. do like stuff such as Including a controller callled GravityController for world settings and such.. and custom movement compenent like planentrymovement component and so on
UPoopComponent
just read this with 0 context and almost choke from the laughter
Very specific question here. I have a racing game, it's already made and runs split-screen. Was wondering how to have the race timer UI widget span between the screen at the top?
very horrible quick drawing, but works
right now each player has their own timer on their own UI, but I wanted to change it to this style
You should be able to create a widget that uses a canvas, position the timer where you want it, and then use the node "Add to Viewport" rather than "Add to Player Screen" and doing so in something that is player independent like the GameState or GameMode.
a sequence
Hi,
I currently try to get my head around seamless travel in Multiplayer. It kind of works as the clients follow. but some parts are not working. As the title is Crossplay on different platforms, we are required to display a Platform Icon next to the name on the Scoreboard.
What we are doing for this is, the Player Controller pushes it’s Platform Name to the PlayerState. This all works on the first connect and is correctly displayed. But after a seamless travel, it seams like the PlayerController Begin Play is not triggered. As well as the Gamemode OnPost Login.
We found that OnPostLogin does actually only fire on the first connection of a client but not after a Seamless Travel.
Handle Starting new Player suposedly should do this. But it does not.
We even tried to Force a Begin Play on the Player Controller, but this seams to also not trigger.
We came up with a different solution to loop over the Player Array from Game State and Login al Players. Doesn’t correctly work.
The Begin Play on Player Controller is not correctly called.
And all our custom Login in the Login Player which are called from all vcariants above (Opening Team Select Menu, moving Player to an overhead perspective and so on) is also only correctly executed on the first connection.
So how do I get this working? How do I get PlayerController and the Gamemodes Login logic to correctly work after seamless travel?
Thanks!
I'll give it a shot, thank you!
But after a seamless travel, it seams like the PlayerController Begin Play is not triggered.
If it's the same PlayerController class, it will re-use the last one.
We found that OnPostLogin does actually only fire on the first connection of a client but not after a Seamless Travel.
Correct.
Handle Starting new Player suposedly should do this. But it does not.
That should indeed call.
We even tried to Force a Begin Play on the Player Controller, but this seams to also not trigger.
We came up with a different solution to loop over the Player Array from Game State and Login al Players. Doesn’t correctly work.
You shouldn't need to do that. Login is meant to only happen on first connection.
Your players aren't re-logging in after all.
The Begin Play on Player Controller is not correctly called.
Yus, expected if the PC Class doesn't change.
And all our custom Login in the Login Player which are called from all vcariants above (Opening Team Select Menu, moving Player to an overhead perspective and so on) is also only correctly executed on the first connection.
LoginPlayer should in theory only be called on PostLogin. If you need additional initialization that should happen after connection and seamless travel, you should put that, and only that, into HandleStartingNewPlayer.
Also, HandleStartingNewPlayer is a NativeEvent. Please call the Parent version of it!
So how do I get this working? How do I get PlayerController and the Gamemodes Login logic to correctly work after seamless travel?
You aren't, at least not like this. PostLogin in GameMode is not supposed to call after SeamlessTravel. Neither is PlayerController::BeginPlay.
Also your functions in the first screenshot that are using Delays are really bad. Don't ever use delays to solve network issues.
All of this sounds like https://xyproblem.info/ .
Instead of forcing whatever you are doing there, please explain what the intend is, so we can suggest you the proper solution.
@rich dune
so just wondering if you lot are still assertinting that the Heatrotation has no magical way to work?
tbh i am not being funny but i am just going to take this to the dev of unreal
this daft idea
that we have we have to manipulate the replicated variable in the bp
its fucking stupid
its already in the animation BP
I don't really follow. What "Heatrotation"?
He is struggling with replicating head rotation of his pawns.
Ahhh
Also bad tutorial on youtube by codelikeme is titled "how to replicate variable in anim blueprint"
I think that headline still stuck on him.
Hey, the Delay is just for debugging right now.
What I mean with Login is calling the startup code for the gamemode and initialize the player. For Example we want to set the default team this gamemode or map uses, force the player to open a specific menu the gamemode wants the user to have. The first setup after a map loads.
The Player Controller does not change but we need informations from the player controller. and need the Begin Play to be in some way or form be called. Especially the for the Platform Icons.
If you need the PC to call BeginPlay, then you will need to respawn it by overriding HandleSeamlessTravelPlayer in C++ in your own GameMode.
The Platform Icons i don't get.
If you received and set them already on the first map, why do you need to set them again?
because player state resets
I just made a "PostSeamlessTravel" method in my playercontroller personally. Then just call that.
SeamlessTravel allows you to move information between the levels better than any other travel.
Then... move the data over?
They are literally coded to have a function for that.
to where?
To the new PlayerState
I don't get it
Where do I access an old player state and write to a new player state for the same player
CopyProperties is the event
It calls on the old one and passes in the new one.
which event?
The Event in the PlayerState that allows you to move data from old to new one after a SeamlessTravel.
ah okay
If the PlayerController doesn't survive a SeamlessTravel (if!) it will also allow you to move data to the new one, but that happens in the GameMode via SwapPlayerControllers (or OnSwapPlayerControllers for BPs).
You usually don't re-initialize data between Seamless Travels. At least not all.
so basically like this
Well we more or less never did know or need this because it's a match based FPS and everything resets on map change
Sad days where BP peeps couldn't use that
Thanks, will give it a try tomorrow
There are pins in this channel that have some info on how to retain data between travels
There is even a way to restore data when a clietn disconencts
Cause the GameMode keeps a PlayerState of a disconnected player alive for a bit.
And then calls OverrideWith inside the PlayerState.
That one works the other way round though.
But that's only needed for data that can't be recreated through "login in" again.
Such as: "How many kills did the player have?"
Now I know a bit more what to search. Always tought everything resets and Player Controller 'reconnects'
Nope. Just, next time you got a problem, please also state what you are trying to achieve, not just the thing you are trying to "fix" on the way to it :D
For a listen server situation, can malicious hosts mess with session info? As in change join in progress to true or change the max num of players
So for a listen server game, having an open quickplay type of situation can easily be exploited, interesting!
Everything can be exploited if you use ListenServers.
That's why you don't use those for competitive games
That's why use DedicatedServers and host them away from the players.
That's why I will never develop one of those, even with all the knowledge I have, cause that shit is expensive.
Even for non competitive it can create a lot of hassle for users as they could be thrown into games that mess with their saves or just invalid sessions made on purpose for example
But the benefits of listen servers still outweigh those cons imo, infinitely scalable and free
Yop, that's why ListenServer games are usually meant to be for games with friends.
Or at least not coded in a way that the server can influence save games if clients.
Or I guess having some kind of server browser so you can avoid bad actors
Yop
What are you even going on about
quick question, i cant seem to get an up to date controller rotation in cmc to compare against input direction
Sounds like they want to replicate bone transforms directly, which doesn't make much sense. And is also of course not required to actually replicate the transform of a bone.
Why not? :P
i have a predicted heading for input, checking that heading against rotation and the rotation value is always behind
i just realized this happens in standalone
yeaaah this doesn't work in build
[2025.04.09-19.27.02:075][408]LogScript: Warning: Accessed None trying to read property Player
BP_Character
PC is not passed to client
gonna try this instead
maybe that will help
Yeah that's also wrong.
You don't need the ClientRPC. You just need to use the OnControlledChanged Event.
And then filter that for IsLocallyControlled.
That already calls on Server and owning Client when the Controller replicates after possession.
Kinda, you don't need the delegate binding. This should be a normal even you can find, similar to BeginPlay.
Ah it's called ReceiveControllerChanged by now
got it
Rest seems fine though, yeah
ok 😄 it's build time 😄
hi guys, I'm new to ue5, I come from Godot and have a good amount of experience. I switched beacause making a multiplayer fps in Godot is difficult and I heard it's supposed to be easier in Unreal Engine. So I downloaded a starter project from the marketplace to get me started, and I think it uses listen servers, but my question is what else do I need to test this out with friends over different networks ? Isn't port forwarding needed ? Do I need to integrate EOS ?
You shouldnt need to port forward if you are using sessions.
Your Listen Server can advertise a Session, that Clients can search for and use to connect with.
There are many tutorials on how to do this at a basic level.
Search around Youtube.
Worked like a charm, I was in a rush and this solved the issue, thank you!
Might want to add that Sessions alone don't help. Has to be with either Steam, EOS or whatever other OnlineSubsystem provides NAT punch through.
Fair call.
Yo guys so I have an issue on actor with simulated physics on when server moves the actor everything is smooth but when the client starts moving the actor it becomes a bit laggy
Now I read the physics based actors in multiplayer have issues and one of them is lagging but is there any solution, I read I could interpolate but how would I do that, other solutions welcome too/
When playing in Editor mode with two clients it works fine under one process or under separate process, both works fine
but connection in a packaged version: development win client and development Linux server doesn't work correctly.
My keyboard and mouse inputs just disabled when connecting to server.
but logs shows everything is fine.
What could be the reason for this behavior?
[2025.01.10-12.26.52:759][374]LogNet: Remote platform little endian=1
[2025.01.10-12.26.52:760][374]LogNet: This platform little endian=1
[2025.01.10-12.26.52:822][375]LogNet: Login request: ?Name=DESKTOP-1585D8N-B5918EF83A12FFD4C96C69E3711B50E9 userId: NULL:DESKTOP-1585D8N-B5918EF83A12FFD4C96C69E3711B50E9 platform: NULL
[2025.01.10-12.26.52:855][376]LogNet: Client netspeed is 100000
[2025.01.10-12.26.54:376][421]LogNet: Join request: /Game/Maps/TestLevel?Name=DESKTOP-1585D8N-B5918EF83A12FFD4C96C69E3711B50E9?SplitscreenCount=1
[2025.01.10-12.26.54:379][421]LogTemp: Warning: AARMACharacterBase::Constructor() Called
[2025.01.10-12.26.54:382][421]LogTemp: Warning: AARMACharacterBase::Restart()
[2025.01.10-12.26.54:382][421]LogNet: Join succeeded: DESKTOP-1585D8N-B591
using nullsubsystem
5.5 issue still exists!
what epic is actually doing? 😄
https://forums.unrealengine.com/t/unreal-5-4-problem-with-a-packaged-game-server-spawns-the-character-and-client-disconnecting-with-failed-to-load-package-error/1871962
Everything worked fine in 5.3 but in 5.4 I stuck with this problem. I connect to the server and everything is ok but when it spawns a player character the client got immediately disconnected with the “Error ‘Failed to load package ‘’’. Exiting.” So… here is the logs [2024.05.24-15.46.31:617][820]LogNetPackageMap: Warning: GetObj...
temporary fix
[ConsoleVariables]
net.IgnoreNetworkChecksumMismatch=1
in the past few days, I realized that i will never ever upgrade project to any new version of unreal engine...
every update fixes old bugs and introduce new bugs.
don't know if this is the idea to keep people upgrading to new versions or what
no real reason to update unless there are features and fixes you want
even then you might be better off cherry picking what you want
yeah totally agree... from now i will lock myself to upgrade unless there is a very big and serious issue that will force me to upgrade
I think it depends. I think if you were on UE4 and close to release it makes sense to stay in UE4. Even if I did a short term project that required much stability I would consider UE4.27 over UE5.
However if you are on UE5 I would say that it's generally worth to keep updating because none of the previous versions is particularly more stable than the current, so updating is probably worth until we find ourselves in a stable version compared to, let's say, 4.27.
If we're talking about a big big project with many developers then I would probably consider picking a single version and never update again, or update very infrequently in a way that nobody is impacted. Probably those projects use custom engine builds anyway and I can imagine the update process on those is way more painful
me too
I just can't bother with all that stress
Ownership is typically in relation to clients. Setting an owner to "self" would do nothing (assuming you're setting the owner of the actor to itself). You would have to set the owner of the actor to something that is owned by a client, such as their player controller, playerstate or possessed pawn/character, after which the "owner" would then be that particular client, and something like "Owner No See" would make it so that particular client would not see the object.
Owner no see in reality means view targets
It's a bit misleading
Possession generally sets the pawn to be the view target
Could use a sanity check, you all.
Is the state change of running Attach Component to Component actually replicated across the network? For some reason I was convinced that attaching was a purely local operation, but now that I'm looking at SceneComponent.h it looks like both the parent component and socket name are replicated. Did I get this wrong?
/** What we are currently attached to. If valid, RelativeLocation etc. are used relative to this object */
UPROPERTY(ReplicatedUsing = OnRep_AttachParent)
TObjectPtr<USceneComponent> AttachParent;
/** Optional socket name on AttachParent that we are attached to. */
UPROPERTY(ReplicatedUsing = OnRep_AttachSocketName)
FName AttachSocketName;
Would overriding OnRep_AttachmentReplication() be what you're looking for? Take a look at the FRepAttachment struct, all of what's inside is replicated, including sockets as you mentioned.
So yeah, I think I had this wrong the whole time and I didn't realize attaching scene components was replicated, wow. The only thing that saved this from blowing up was the fact that I hadn't marked those components as replicated. Looks like I then later enabled component replication and everything started behaving bizarrely. Now I know.
but yeah overriding the onrep should stop it from applying this
I see. So I can surgically disable this particular state replication, but still benefit of component replication for things I might want to do it for?
Anyone know why this might be happening? The pawn I'm looking at here is a client, and they're on a physics actor, the experience for them is super rubber-bandy when walking on these physics actors and this is probably one of the reasons why
I have max walk angle set to be pretty high so you can use these angled boxes as a platform, it looks like maybe there's something related to that?
Is the Physics Actor in the same location on Server and Client?
This looks like BasedMovement kicking in when you land and correcting the relative location.
Yeah in the gif there I'm actually detached from the server player and looking at it from the server level
I'm trying to get another test case just to confirm
Actually yeah it seems like the player on the server seems them at a constant location, so seems like there's some disconnect between the client and server. Apparently detaching from the server shows you the world as seen by the client
Seems like with physics objects the server and client really are having trouble lining up
Question about FFastArraySerializer is doing something like this makes using FFastArraySerializer more or less not relevant due to nesting ?
You cant have a FFastArraySerializer struct type within a FFastArraySerializerItem struct type.
You cant nest FastArrays.
Well, you probably could.,
But
Like.
Why.
thank you then i am going to need to do it like so
Your diagram is like super confusing.
Better to write it in psuedo code
Than how you have done it.
Physics in Multiplayer aren't really easy. You can set it to bReplicateMovement, but that will literally set the replicated Transform, which means it will look choppy on clients when moving.
Idk how far #chaos-physics is with replication of such things, given that LEGO Fortnite is a thing, but that would probably be the only thing you could try.
Epic is working on a Chaos-based Mover 2.0 implementation, but I would not touch that for a longer while.
If #chaos-physics has no solution for it at the moment, then you might need to enable bReplicateMovement and smooth the location by hand.
Or give up on physics and fake it via normal vector math. A good alternative is an Actor that you put a ProjectileMovementComponent on. Those are the only other Components that have some native Interpolation and are my go-to setup when needing something being thrown, bouncing, shot, etc. while looking relatively smooth on the Clients.
--
What you are seeing there is standard BasedMovement behavior if the Base is not aligned at all. The CharacterMovementComponent already expects this and has some logic to make it somewhat decent to jump on and off such a desynced Base, but if the difference is too large it will give up and just set the Client to where the Server is.
The important thing to understand with BasedMovement is how corrections work.
- If you aren't standing on a Base, UE will take the Character's WorldLocation and compare those.
- If you are standing on a Base, UE will communicate the Base between Server and Client (assuming it supports being referenced across the net) and will compare the RelativeLocation of the Character on the Base.
That means, as long as you are ON the Base, even if the Base is totally somewhere else, you can walk without corrections. You onyl get a correction up entering or leaving the Base.
Epic is working on a Chaos-based Mover 2.0 implementation, but I would not touch that for a longer while.
Snacks, why would you want to inflict even more pain onto yourself?
Fair.
In the end, that isn't actually too surprising. We were pretty much expecting that move.
This is actually super helpful! But also something really interesting I notices was that actually the client's location on the physics actor was improperly rotated compared to the server
See in the gif that the client starts walking towards the server player, but from the server player's perspective they walk away from them
This aligns with the previous gif that I sent where as soon as the client jumped they were moved to the other plane of the cube they were on.
This seems like it could be do to based movement like you said, maybe the client isn't properly getting the rotation of the base?
Yeah BasedMovement includes Rotation. I should have written Transform or at least mentioned that. If the Platform is 180° rotated and you land on it you will snap to the relative rotation.
very interesting, something's probably not replicating properly with that. Thanks for the info!!
And yeah I can confirm that physics and multiplayer is really choppy
When you suggest to smooth it manually, what do you mean by that? The first thing I can think of is to have the actors on the clients on-tick adjust their location based on their velocity/delta time manually until the server corrects them, but that sounds like it would probably not be as simple as it sounds and also not account for collision in stuff
Did you have any implementation in mind for that, or have any resources that go over it?
And also the actors which projectile movement components seem interesting as well, sounds like instead of the physics collisions I would just apply impulses / velocity to the actors and let the projectile movement components handle the 'arcs' of those movements then?
Yeah, you usually give those Actors a collision Root and then a second Component that is the visual Mesh (without collision), and then you can set the InterpolatedComponent property on the ProjectileMovementComponent to the Mesh, somewhere on BeginPlay for example, and it will smooth things a bit.
Eh, smoothing just means that you take the current Transform and the Replicated Transform and you interpolate towards it over time.
There are multiple ways to do that, you can probably find some simple math on the internet. You just need to be aware that you are very close to requiring C++.
Yeah I'd probably do that in C++ if I'm going as into detail as interpolating movement, BPs are kinda just for prototyping while I figure this stuff out, just meant to be a stupid project to mess around in
Alright I'll look into that tomorrow, thanks so much for the help!
It's def better to do it in C++, because there you can override methods that would usually apply the replicated movement to the Actors Transform
Which you don't want, you just want to store it and interpolate to it on Tick.
Yeah that makes sense, easier to access and intercept that stuff in those functions
Hey everyone! 👋
Could someone clarify if I’m doing this correctly?
I have a function that adds a skeletal mesh component to the player on the server—basically, the player equips a helmet.
The issue is, any late joiners don’t see it. To address this, I’m retrieving the player state for each player and running the "add skeletal mesh" function only on the client who just joined.
You'd need to replicate the component, but because Skeletal Mesh doesn't have any replicated properties, you'd also need to replicate the mesh independently.
There's obviously more efficient ways, but that's the "simple" way of replicating a component.
If it doesn't work for late-joiners, it won't work for irrelevant players either
maybe this is right answer
yeah but the problem is you're also creating a new skeletal mesh component
The alternative would be to always have a "helmet" component on the character, and just change the mesh this way.
The best way most likely, is to replicate the cosmetic items ID for your character and have local clients find + apply the mesh from that. If you want to spawn the component dynamically too, then make sure you spawn it with a stable network name so you don't need to replicate it, but can still send references to it over the network.
I see
If it has no gameplay relevancy at all (i.e no collision, never send references over network), you don't need to worry about the last bit.
yeah they have ID as integers so basically I can have components ready and just send ID value and each client will handle that
yeah, and that's probably the best way IMO
cool, cheers
Does anyone else experience VOIP talker only working intermittently. I've Noticed the VoiceChat For my game isnt very consistent and somtimes it works, sometimes it doesnt.
Hi, using Steam Sockets for my online subsystem which has the pings showing correctly instead of '9999' for listen servers however some servers are still displaying with 9999 ping, anyone know what that is?
I am not sure if it is some sort of compatibility issue where its showing 9999 ping for people hosting servers on different engine versions or something (all using 480 app ID) and if so, I assume this issue disappears when using a unique steam app ID
when is reliable multicast RPC of GameStateBase available for a connection/client ? I supposed after AGameModeBase::PostLogin ? buts seems one frame is droped 🤔
What is it you're actually trying to do? A multicast on gamestate wouldn't work for a client until gamestate is replicated to them which you won't know when that happens on the server.
@sinful tree its a king of custom-compressed-world-snapshot, i sent the initial data in PostLogin then use Multicast but seems GS muticast is not available at that time
Why would that need to be a multicast if it needs to go to a specific client, and why couldn't you use an OnRep replicated variable?
Do clients require every individual frame of data?
No, they don't get it anyway
just though multicast is better since im sending same data to all connected clients, switched to Client RPC instead. (muticast never worked my whole life)
By the sounds of it, you're wanting to send to a specific client when they join the game. By making it a multicast, you'd basically be sending it to all clients whenever anyone joins.
Ideally, you woudln't be using an RPC at all... If you want some "initial" chunk of data to be sent to the client only once when they join the game, you can use a structure that is set up as an OnRep variable with a replication condition of "initial Only" which would make it so it only replicates the data the first time the actor that contains the data is replicated to a client.
You can then use the generated OnRep function to perfrom whatever actions you want when the data ends up on the client.
Hello, 👋
I'm seeking general advice on replication practices for anyone that knows. I've built my game to be server-authoritative using lots of OnReps and only allowing damage and death to be dealt on the server.
Lately, I've been testing my game with bad ping and the results are unsatisfying. Since my game is a four-player cooperative and not at all competitive, I'm considering switching to a client-authoritative set-up. To do this, I observe that I will need to implement many reliable RunOnServer RPCs to tell the server that the client has taken damage, been stunned, etc.
Is this a wise path to follow? I just want to change from server-authoritative to client-authoritative so that the client doesn't feel ripped off when they visually see they dodged while on the server, they collided.
Any advice would be appreciated. 🙂
Cheers.
OnRep for damage? interesting design
Right now I handle the overlap locally and immediately apply the flashing and effects locally. But yes, the damage is only really taken on the server before it replicates that to the clients.
But more importantly, death is only dealt on the server. And now that feels lackluster on the client as they have to wait for the enemy to explode after they can see they've hit it enough.
if you want it to be client authoritative you can basically do whatever
imo with high ping accept that things will look and feel awful
Thanks. Since I've never needed to use Reliable much before, I'm concerned about the implications. A player character might collide with an enemy two or three times in a second at the most. Would that be too many reliable RPCs?
why reliable?
Because running into an enemy causes character death and therefore, it has to occur.
handle death on the server
you could always just do some sort of form client prediction
That's what I'm doing now but it doesn't feel good because the player can see they dodged an enemy while on the server, they collided.
what kinda ping are you talking?
I'm simulating "bad ping" in the editor which is 100 - 200ms.
i would personally not design my game around people with 200 ping
it should be functional but it will feel bad no matter what you do
I think that by making it client-authoritative I can improve the experience for those with bad ping while keeping it the same for those with good connections. You don't think it's worth the effort?
if you think a meaingful amount of your playerbase will have 200+ ping and high packet loss, go for it
but they are going to have a severely degraded experience anyway by seeing every other interaction in the game rubberband
Thank you for the advice. I wonder what ping most devs consider when configuring replication.
If you make it so death is handled client side (ie the client has to tell the server they were hit), that also means you'd be allowing clients to not report to the server that they were hit.
Thanks, Datura. 🙂 I'm not concerned about cheating. Is that why you mention that?
yep 🙂
It's a four-player coop party game, so I'm not bothering to worry about cheating. I am worried about shooting myself in the foot with Reliable RPCs. Do you have any advice in that department?
Because I think in order to handle death on the client, I need to use Reliable RPCs.
If it's something that can happen every frame, then you probably don't want to make it reliable since you'd be sending another update the next frame anyway.
It won't be every frame, but it might be two or three times in a second.
Collisions are usually something that can be detected every frame, but usually you only know when the collision is triggered.... So, it's kind of in the air.
Yeah, I've got the collisions worked out, that part is functional. Right now, a collision can only kill a character on the server, but I'm considering reversing that to be client-authoritative. So far, the advice I've received here is that it's not worth facilitating high-ping (200ms) players.
I just want the client to feel like they smashed into something and immediately suffered the consequences while also ensuring they never die because they hit something on someone else's screen.
the issue with having client authority is that anything that involves another player influencing them is going to be utterly broken
Generally speaking, anything you want to communicate that is gameplay important, you'd want to use reliable on anyway, just so long as you're not doing so every single frame or anything else you may be sending rapid updates on.
Thanks to both of you for the advice. My game doesn't involve many player-player interactions, mostly player-computer.
Like, a collision like this would be fine to send as a reliable RPC, but you may also want to block the client from sending that "hit" RPC through your normal logic if they have been deemed defeated already, just so you're not sending reliable RPCs when they're not needed under normal gameplay.
i would worry over weird edge cases like the server replicating hp down to me, but as its being replicated, i tell the server my hp is 5 less than the original not server replicated value
keeping everything on the server also makes logic a lot less confusing
Okay, okay. Those are valid concerns. 🙂 I think I'll try a couple experiments and see how it feels. It's interesting to consider that at a certain ping, players accept poor experiences. It's also good to know that Reliable isn't a game-ender.
hey sorry for the ping but i tried this and i feel like im not understanding something, what im currrently doing is applying an impulse on the client that kicks the ball, then i apply the same impulse on the server? would this automatically handle prediction or am i missing something?
i wouldnt say high ping players "accept" a bad experience, but they basically have to or else their bad experience affects everyone elses experience
like imagine you're playing a coop puzzle game with a friend and they teleport through a wall and get stuck
or you split second decide to heal your friend but their hp gets reset to whatever the last value the client had 600ms ago and the potion gets wasted
high ping ruins the players game. dont let it ruin everyone elses
Okay, I understand what you're saying. Thanks again.
How do you set unique variable values of a level placed server owned BP on a per player basis? For example I have BP_Box and default color is red but for some players it should appear to them as blue and to others as green.
At first I tried looping through the players array from the gamestate on BP_Box and was changing the color that way but soon realized it would apply the same color for everyone depending on the last player in the array. Which isn't what I want.
Just change it on the client.
Its a replicated actor though
In the onrep, check on the client what color it should be based on w/e criteria
I need to replicate the component because it scales up and down based on certain events, but only the color should be different.
OnRep when there is a change. The OnRep can use a for each loop with break through the PlayerArray, the loop should check if GetOwner Cast To PlayerController Is Locally Controlled, if so, that's your local playerstate, your onrep can now modify whatever based on that local PlayerState's values and break the loop.
IE - just change it on the client.
There is some way that you are determining this already. Just do that same thing - except on the client, in the onrep.
ahh yes ** GetOwner Cast To PlayerController Is Locally Controlled** was the key part I was forgetting about
thanks
I would just do a getallactorsofclass player controller personally. On the client, it'll give you yours. Because clients will only have one PC typically speaking.
(I don't trust the index getplayercontroller stuff - even though that should work as well in this case)
If this is in the playerstate though - it should also already have a reference to its owning controller
If I am server logic on the PlayerController, and I need to trigger logic on the Client's PC. What are my options?
Right now I have a MultiCast - but that feels like it it might be overkill and I believe sometimes the message is failing. I've ticked it as 'reliable', but is there a better way to pass logic back to the client? Is this where I would use "Run on owning Client" -- does the Client "own" the PlayerController, or the Server?
Reproduction of this bug is ~2%; I think I've pinpointed it to the MC failing, but not sure.
Depends on what you need.
Stateful changes - use an onrep variable, and you can also set conditions to it.
Nonstateful changes - use an RPC
Client rpcs will send the rpc to the client who has network ownership for that PC
what other clients would the multicast go to?
the player controller is a handle to the connection that ONLY the local player and authority can see
the player controller DOES NOT EXIST on other clients for other players, each one has a local controller
the authority can see all controllers (and AI controllers if you have those too in the typical setup)
but yeah Onreps should be generally the first choice if it is stateful information
just because it is an "event" doesn't mean that an onrep won't work, onreps can indicate a change at a certain time
can I send pointer to UObject through client rpc?
I think it depends if it's net addressable. For example iirc DataAssets, and ofc replicated actors.
ok so if there are issues with replicating uobjects and sending them through rpc it ruined my inventory idea 🤡
I can't use structs too, cause I need per item programmable use action
depends on what your inventory design was like. You can send the required properties through RPCs or replicated variables and forward them to a UObject or whatever you need.
Also probably you want to replicate items, not RPC them
I don't think there is any restriction per se on using structs like that btw
yeah sure I can spawn on client-side it's own uobject instance but it would be hard to manage so I wanted the easy way of just sending the pointer to uobject 😄 if I tried to replicate the tarray of uobjects pointers on client they were still nullptrs. Tried to setup uobjs as subobjects but without any success
how would you do it?
what's your idea for it?
I never created an inventory system but first I would think what I need to represent an inventory item - a struct with base data, maybe a data asset, maybe even a whole actor?
Then depending on that I'll see how to replicate those from the server to client(s). Most likely an array of replicated items.
Finally you need to figure out how to pick items (add to the array) and see if it needs client side prediction or not
I think items as actors will be too expensive (even for max 8-16 players coop game) , but this would be the easiest way to do it - I made weapon inventory in that way
if the items are just static data I would likely go for data assets
you can have a base class for inventory items so that all of them have a common interface if needed
So how would you do the custom use actions per item when they will be struct, data asset? with uobject I can go with BlueprintNativeEvent or ImplementableEvent
which kind of custom actions?
Hello, I'm confused about something. On my client side I am setting the location of the player character to a different location, and if I print the location immediately afterward the location has successfully changed. But it seems that something, I'm assuming the server, is setting the character back to its original location right afterwards. But AFAIK I'm not actively replicating anything, including movement. So what is going on?
What is this thing, Character?
Show the parent class and the component layout.
Character is the pawn controlled by the player controller. IIRC it's Actor->Pawn->Character
Why do you need the components?
So it is a Character? That's already replicated with server authoritative movement out of the box. It's correcting you.
Yeas you cannot set location for character directly because CMC overrides it (and already handles movement replication)
I'm again getting a strange issue where in packaged builds the client disconnects form the server after a login request.
client have a join button in the UI, which calls the openlevel function and i am using the ip address of the host as a new level. it works in editor play mode, but not in the packaged game.
linux server
windows client
Login request: ?Name=DESKTOP-LOCALPC-001 userId: NULL:DESKTOP-LOCALPC-001 platform: NULL
Client netspeed is 100000
UChannel::ReceivedSequencedBunch: Bunch.bClose == true. ChIndex == 0. Calling ConditionalCleanUp.
UChannel::CleanUp: ChIndex == 0. Closing connection. [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr: 127.0.0.1:63421, Name: IpConnection_1, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_0, IsServer: YES, PC: NULL, Owner: NULL, UniqueId: NULL:DESKTOP-LOCALPC-001
UNetConnection::Close: [UNetConnection] RemoteAddr: 127.0.0.1:7777, Name: IpConnection_1, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_0, IsServer: YES, PC: NULL, Owner: NULL, UniqueId: NULL:DESKTOP-LOCALPC-001, Channels: 3, Time: 2025.04.12-15.34.43
UNetConnection::SendCloseReason:
- Result=ControlChannelClose, ErrorContext="ControlChannelClose"
UChannel::Close: Sending CloseBunch. ChIndex == 0. Name: [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr: 127.0.0.1:63421, Name: IpConnection_1, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_0, IsServer: YES, PC: NULL, Owner: NULL, UniqueId: NULL:DESKTOP-LOCALPC-001
UNetConnection::PendingConnectionLost. [UNetConnection] RemoteAddr: 127.0.0.1:63421, Name: IpConnection_1, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_0, IsServer: YES, PC: NULL, Owner: NULL, UniqueId: NULL:DESKTOP-LOCALPC-001 bPendingDestroy=0
launching a standalone dedicated server from the command line and joining it from the UI or form the command line also works perfectly
LAUNCH
TIMEOUT /T 1
"D:\Engine\Engine\Binaries\Win64/UnrealEditor.exe" "D:\Projects\ARMA\Arma.uproject" TestMap -server -log -nosteam
JOIN:
TIMEOUT /T 2
"D:\Engine\Engine\Binaries\Win64/UnrealEditor.exe" "D:\Projects\ARMA\Arma.uproject" 127.0.0.1 -game -ResX=640 -ResY=400 -WinX=800 -WinY=20 -log -nosteam
https://dev.epicgames.com/documentation/en-us/unreal-engine/replicating-uobjects-in-unreal-engine
tldr, yes, but they have to replicate through an actor at somepoint. so either owned by a component and forwarded through an actor or just owned by the actor
i used it for my inventory and i am happy with it
but this works for you for run-time created uobjects?
yes
hmm
I made everything what it needs and it do not work for me xD
still can't replicate uobjects in tarray or send pointer through rpc
Are you trying to RPC the reference immediately after spawning it?
yeah
That's probably the problem. The RPC may be getting received before the object gets replicated , if that object is replicated properly.
but as I said - replicating TArray and checking the values in OnRep also gives nullptrs
i remember having this issue. it wasn't related to subobject replication iirc
What I did is an actor component which handles registering subobjects for replication. I added this component to the gamestate actor (first what came to my mind where to put it), when spawning I am registering uobject via component
Uobjects have IsSupportedForNetworking override with return true, GetFunctionCallspace, callremotefunction etc
UBaseItem* Item = NewObject<UBaseItem>(GameState, Pickup->GetInventoryItemClass());
GameState->GetReplicatedObjectsReplicationManager()->RegisterReplicatedObject(Item);```
you set bReplicateUsingRegisteredSubObjectList to true in the component right?
Yes
Is there a way to turn off the networking part of the CMC? I don't need the server to know anything about how the character is moving. Will I need to reparent into a pawn to avoid the issue? Makes me wonder what other information is being sent to the server without my knowledge
You can check in CMC properties to accept the client side position
I don't know what excatly he want to do, but accepting client side position speaks for itself and he should be aware of consequences of it
I've been reading the descriptions of these two options and it sounds like the client is still sending movement info to the server, it's just that the server isn't going to correct it. So if there are no other options I guess I will reparent
if you dont want to use the cmc just use pawn and make your own movement component
that is non trivial tho
what is the issue with it sending movement info to server?
Is it not possible to move without a movement component?
i mean, you can
theres nothing stopping you from just rpcing the position to the server and having it accept it
You're saying these nodes need the character movement component?
no, but they wont do anything unless you make something ingest those inputs
I'll test it out and see if movement breaks. Thanks for your help
went and looked at my implementation. this is what i did.
// .h
UCLASS(meta=(BlueprintSpawnableComponent), Abstract)
class MALFUNCTIONALGAME_API UReplicatedSubObjectOwnerComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UReplicatedSubObjectOwnerComponent();
protected:
void AuthAddOwnedSubObject(UObject* ToAdd);
void AuthRemoveOwnedSubObject(UObject* ToRemove);
};
// .cpp
UReplicatedSubObjectOwnerComponent::UReplicatedSubObjectOwnerComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = false;
SetIsReplicatedByDefault(true);
bReplicateUsingRegisteredSubObjectList = true;
}
void UReplicatedSubObjectOwnerComponent::AuthAddOwnedSubObject(UObject* ToAdd)
{
AddReplicatedSubObject(ToAdd);
}
void UReplicatedSubObjectOwnerComponent::AuthRemoveOwnedSubObject(UObject* ToRemove)
{
RemoveReplicatedSubObject(ToRemove);
}
// DX STUDIO 2024
#include "Core/ObjectsReplicationManager.h"
#include "Engine/ActorChannel.h"
UObjectsReplicationManager::UObjectsReplicationManager()
{
SetIsReplicatedByDefault(true);
PrimaryComponentTick.bCanEverTick = false;
bReplicateUsingRegisteredSubObjectList = true;
}
bool UObjectsReplicationManager::RegisterReplicatedObject(UObject* ReplicatedObject)
{
if (IsValid(ReplicatedObject))
{
ReplicatedObjects.AddUnique(ReplicatedObject);
AddReplicatedSubObject(ReplicatedObject);
return true;
}
return false;
}
bool UObjectsReplicationManager::UnregisterReplicatedObject(UObject* ReplicatedObject, bool DestroyObject)
{
if (IsValid(ReplicatedObject))
{
ReplicatedObjects.Remove(ReplicatedObject);
RemoveReplicatedSubObject(ReplicatedObject);
if (DestroyObject)
ReplicatedObject->ConditionalBeginDestroy();
return true;
}
return false;
}
void UObjectsReplicationManager::BeginPlay()
{
Super::BeginPlay();
}
bool UObjectsReplicationManager::ReplicateSubobjects(class UActorChannel* Channel, class FOutBunch* Bunch,
FReplicationFlags* RepFlags)
{
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 1
return Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
#else
bool WroteSomething = true;
for (UObject* ReplicatedObject : ReplicatedObjects)
{
if (IsValid(ReplicatedObject))
{
WroteSomething |= Channel->ReplicateSubobject(ReplicatedObject, *Bunch, *RepFlags);
}
}
return WroteSomething;
#endif
}
``` here is mine 🤡
im assuming you probably did something identical for your component
void UInventoryComponent::AddItemAtIndex(const int32 Index, UInventoryItemInstance* ItemToAdd)
{
AuthAddOwnedSubObject(ItemToAdd);
ContainedItems[Index] = ItemToAdd;
BroadcastChangeAtIndex(Index);
}
UInventoryItemInstance* UInventoryComponent::RemoveItemAtIndex(const int32 Index)
{
UInventoryItemInstance* Temp = ContainedItems[Index];
ContainedItems[Index] = nullptr;
AuthRemoveOwnedSubObject(Temp);
BroadcastChangeAtIndex(Index);
return Temp;
}
ignore the broadcast, its a kludge for ui
where are you spawning the instance of inventory item?
is there a reason you are using the ReplicateSubobjects function?
no, I tried adding that to see if it will make it work xd
either in editor in a container or done at runtime from a loot spawner on the server
i wonder if its just the order in which you register it for replication?
i register it and then add it to my replicated array
// Create instance of item
UBaseItem* Item = NewObject<UBaseItem>(GameState, Pickup->GetInventoryItemClass());
GameState->GetReplicatedObjectsReplicationManager()->RegisterReplicatedObject(Item);
if (Item && InventoryComponent->CanPickupItem(Item))
{
InventoryComponent->AddItem(Item);
OnInventoryItemPickedup.Broadcast(Item);
BasePlayerController->ClientPickedUpItem(Item);
//BasePlayerController->ClientTest(T);
Pickup->Destroy();
}```
it's the same here
bool UFixedItemSpawnpointComponent::TrySpawnItem(AActor*& SpawnedItem)
{
// check that owner has authority and that this is being done on some sort of server
check(GetOwner()->HasAuthority() && GetWorld()->GetNetMode() < NM_Client);
// select random item class, create an instance of it, spawn its actor, and return success
SpawnedItem = NewObject<UInventoryItemInstance>(
GetWorld(),
SpawnList->GetRandomItemClass().LoadSynchronous()
)
->SpawnActorFromInstance(GetOwner(), GetComponentLocation(), GetComponentQuat());
return true;
}
the only other thing i can think of is that maybe using the gamestate to spawn is causing issues?
gonna check it now
nope, same
:/
@thin stratus @pallid mesa @gleaming vector
Guess what. Higher fps = lower jumps with CMC.
I rebuilt DoJump and PhysFalling into a struct so I could simulate a jump. My sim runs at 60hz. Its 1:1 with CMC when I use t.maxfps 60
When I have 120fps and the sim runs at 60hz, I lose considerable max jump height.
[Image 1] Blue = sim at 60hz, red = CMC at 120fps
[Image 2] Blue = sim at 60hz, red = CMC at 60fps
Full Disclosure: I'm using a custom jump implementation with multiple phases and base CMC might not be so sensitive. I would have to recreate my sim for the default implementation to say for sure.
200fps
Modifying these makes no diff
This is actually a really serious issue for platformers lol
Do you limit them to 60fps so they don't get punished when jumping while they review bomb you for not letting them play at 120fps? 😄
Imma build a sim that does default CMC jumps to see if its just my custom jumps being more sensitive
lol
That's MAX Sim Time Step. That should only clamp if you get low fps or not?
Sim Iterations are just sub steps. They wouldn't affect this either.
Not sure what the third variable does.
I also don't see how the CMC sim could be locked to 60 fps.
Given delta time has an impact on everything, having less tick rate for the sim would mean it has a higher delta time. And if that's still ticked 120 times per second, you would gain height, not lose it
But I'm curious what the reason will turn out to be
If you look at it the other way around
You gain jump height at lower fps
Why?
No idea 😄
I might try reducing to 30fps and see what happens, but first I gotta update my sim for regular CMC jumps
Logical wise, low fps shouldn't matter, as they tick less often with an adjusted delta time
It would only be a problem if it ticks more often than what the delta time suggests. 120 to 60 or 60 to 30 doesn't matter then. Both would be double the delta seconds than expected
I know you just document your findings but testing native code first is definitely a good idea
I can understand that a lower tick rate would cause a slightly higher/later apex, cause the sim might go a larger step too far before noticing the apex, but the line leading up to it should be the same
Actually, not true what I said. It will be similar but slightly different cause each individual step of the lower sim will move a bit further with the same values, while the higher sim will be more accurate. It shouldn't have a drastic impact though in theory
Interesting nonetheless
That seems to somewhat fall in line with what I wrote. They want to counter the fact that the apex could be overshot or cut early depending on frame rate changes.
Nothing really suggests atm that the trajectory would be hugely different
Anyone have experience with the UNetworkPhysicsComponent? ive managed to get the resimulation working on a client controlled actor (pawn) cos its netrole is autonomous proxy. But i cant see to find any info on making it work for a server controlled actor with a client role of simulated_proxy like a boulder everyone can push around for example
@pallid mesa didnt you write this article maybe you know
~~Do you have any suggestions on which functions to override for this btw? For context these boxes that I'm simulating physics with are actor components to reduce the amount of bandwidth I'm sending over the network
Basically all of the replications functions I'm seeing are related to the actor's rootcomponent, so I haven't yet been able to find where the other component's properties are set, and if I have to do this on the actor level and propagate the changes to the components I haven't found the actor function yet that has access to the component's replicated info~~ See message [here](#multiplayer message)
if you want a boulder that everyone wants to move around you just gotta set the physics ball as a replicated physics object with predictive physics on it, nothing else needed
if you want physics to also be able to affect your characters pushing the boulder around you gotta use physics mover, but thats another can of worms to open
thats weird, im setting that but it isnt working
whats not working?
the heck xD
when i press e theres no impulse, just stays completely still. works fine in standalone netmode though so its definitely something to do with the component or my implementation
ah wait so you want to apply an impulse on input on authority? or when you walk against the ball?
the first yes
you gotta apply the impulse on the server if you dont mind about predicting it
needs to be applied on client first so it can be smooth
doesnt need to
Ive basically just hijacked the jumping part of your ball character demonstration
applying it on the client first wont make the interpolation more smooth, it will simply be more reactive
Yes well thats what i mean
yes the problem is that my article is about controlled physics interactions, in this case you dont own the ball, its in the world... thus what you see in the article wont work in such case
that was the gist of my question basically, if there were any resources for objects not owned by the player
i really just want something like the ball pawn that all clients can apply impulses to
on their own clients then have it simulated and predicted/ resimulated/ whatever on the server
yes, that doesnt come out of the box unfortunately with none of the techs epic pushed lately... not sure if you could hack something around
would have to look around to see what your possibilities are in this case... but should be definitely possible
how do they do lego fortnites contraptions? like im assuming when you shoot a rocket launcher or whatever at a physics assembly it reacts instantly on the client right?
for context its actually a sport game, i want the players to move the ball around and not have it be delayed/choppy
so... here's the thing... accounting for predictive interpolation, you could apply a force predictively on the client AND on the server, meaning that the force application in the client will happen half a round trip time before the server... the server will apply the same force at a later time, and if everything is okay... the physics system will 🤝 the simulation and keep on going, otherwise ytou'll get corrected
Actually I think I may have found the place to do it
Unfortunately bNetUpdateTransform is private :/ and all of the functions that modify it are as well. Only way I can think to prevent this is to either 1. Prevent the transform from being replicated in the first place, or 2. Override PostRepNotifies() and don't call Super, but that would also prevent all of the attachment logic so not ideal
I think actually what I'm looking for is UPrimitiveComponent::MoveComponentImpl(), except even that doesn't fire during replication so idk
id still be using UNetworkPhysicsComponent though right
not necessarily, you can raw apply the impulse for starters
if your goal is just to apply an impulse without continued inputs
you can just do it
this is actually what i tried initially just client impulse, then send a server rpc for a server impulse. i tried both resimulation and prediction but it had this really weird "snapping"
its like the client would apply its impulse and then the server would override it instantly
irrespective of if the clients velocity is correct
the network physics components is when you have inputs to rewind them or decay them, but in your case its just an impulse applied at a time t.
in this specific case you'd want predictive mode, not resimulation
which ue version are you on @potent tundra ?
@thin stratus @pallid mesa
Interesting. Its only when I'm modifying gravity at a couple of points throughout the jump that FPS affects the arc
I'm modifying it based on a JumpTime that is incremented in CalcVelocity, which is part of the physics loop so it shouldn't be inaccurate
5.5
i tried both resim and predictive interpolation
had the same issue
and you have everything on on project settings, no warnings on the output log?
Oh maybe it is actually related to this, because my apex time will differ if gravity gets modified
yes, i think that might be the case
Ya it IS that lol
specially if you are modifying gravity mid time
I disabled the cvar and its 100%
pog
Unfortunately I have to override and copy/paste the entire damn PhysFalling to fix this 😄
I have precomputed min/max apex time and height that I can pull from my jump solver asset
And lerp it based on normalized 0-maxjumpholdtime
So it shouldn't be hard to fix
That was the last thing I had to solve for my psychonauts jump setup 😄
Just gotta build some editor/vis tools
should replicatemovement be off?
in this case? i think it should be on... but im not 100% certain, dont have the engine in front of me
yeah when its off other clients dont get any positional data
but when its on that weird jitters still there
like, it clearly runs on the client but then it gets snapped back to where it was before
maybe this is happenning?
apply impulse on client
correct to server velocity (0, 0,0)
apply impulse on server```
so in the actor itself are you setting predictive interpolation on physics replication mode?
How do people go about predictive launch character? In my game, anytime a character is hit, it's knockbacked a little bit. I use launch character for that, but I do that server-side only, which causes the characters to teleport along the launch path rather then interpolate along it. Should I also run it client-side, or there's something better?
i did some more tinkering and as far as i can tell it just works now, i set the replication mode to predictive interpolation and fixed a bug with my code. Pretty sure the original issue with the stuttering was just a red herring brought on by a discrepincy in the impulse on the client and server
ts pmo sb atp 🥀
Thanks anyways your article was goated
pog! o7 happy deving @potent tundra ! glad you got it figured
Hello, I am new to UnrealEngine but have a lot of experience working with and managing packets, along with developing server side anti-cheats. My question is there a way inside of UE 5 to customize the backend code? Is it possible to customize how the client sends packets and how the client reads them? If so can anyone give me a general idea on where to go to start this process because I need to be able to customize the servers code and the packets the client sends out.
wait with the error per linear diff, is higher more or less aggressive
error refers to how much error chaos net chaos allows between contexts
so higher means less aggresive
hm okay
UE abstracts you from the low level through the implementation of a netdriver. Replication goes through channels, each having its own net priority and net frequency. However! You can ignore all this and make your own stuff using FSocket directly... but goes a bit against UE environment.
cos whenever i interact with the ball theres now a slight rubberband, that autocorrects (im guessing) when the ball data reaches the server. its way too late now though o im gonna lookk at it tmrw
i might of just forgotten to turn off my high ping simulation
Ok so what do you think the best option would be? Because I assume if I did make my own FSocket then I would have to esentially rewrite everything server wise from the ground up. I mean I can write the code to interoloate, make predictions, etc but it is a lot of effort. How trouble some would doing this be? Would it be hard to change how the client sends their packets?
you could modify the engine to keep functionality :)
so i guess its time to dig the netdriver, and try to understand the code and intercept the calls you are interested to modify @pulsar abyss
but yeah it depends a lot on what you want to do
I am currently taking a course on GAS and multiplayer, and I'm learning a lot, especially about the specifics of what to do for a given situation.
However, it's a very lengthy course, and it is taking me months to complete, so over time, I forget and lose the overall flow of both the GAS system and multiplayer replication.
Does anyone know of good videos that show an overview of either or both systems? Not a video that teaches you how to program your own system, but a logical explanation of how the system works for a general completed game.
that alongside this is a really great introduction to GAS to do a hands on and to grasp onto concepts https://dev.epicgames.com/community/learning/tutorials/DPpd/unreal-engine-gameplay-ability-system-best-practices
beautiful, thanks
written by Zhi Kang Shao from Epic Games, they are amazing
your a lifesaver
Where can I go to actually view all this code? When inside a default C++ based FPS template where should I go to view the source code for all the multiplayer aspects?
Are there any docs that goes over their netcode? Probbaly note in which case I would have to read through it all after I can find it.
get an ide in which you can navigation comfortably through the ue5 solution and look for specific keywords and usages... Nowadays the engine is implementing a new netdriver for iris use, which is the new and optimized network layer of unreal, you might want to look there
Ok thank you I will read through that article also I am using VS rn. Lastly, how can I navigate through the UE5 solution? Are you just saying to read the code through GitHub then saying I will have to change that code instead of inside of UE5?
for such sensitive changes you'd have to grab the source of ue rather than download it from the launcher, and build yourself the engine.
Alright of course it has to be so much work lmao. So basically I have to clone the engine then edit what I need then build it and then somehow manually load it so it can work with the normal UI or something.
yes, if you want to modify engine plugins/engine code, it has to be done that way unfortunately
void AProjectRagdollGameMode::PostLogin(APlayerController* NewPlayer)
{
Super::PostLogin(NewPlayer);
if(GetNumPlayers() == 2)
{
OnAllPlayersConnected.Broadcast();
}
}
I call a MultiCast reliable function when OnAllPlayersConnected is broadcasted. However, multicast function wont called on clients. Which function should I listen to make sure clients are okay to recieve rpcs ?
Can this be done with custom plugins or is editing the source directly the best way? Cause the only issue with this is compatability.
You can kind of extend some of the surface level connection things I think... Like how USteamSocketsNetDriver works
I would say it's probably unlikely you will have enough control without having source access but I'm not sure what you are actually replacing
your best bet is to just follow the packet reading/writing flow and figure out which pieces can be modified along the way
your players have no game mode
as for when your clients are okay to receive rpcs... it depends
I would argue you should wait for the playerstate and possessed pawn to show up (not "on posses" but to have been set) and have begun play
but that might be later than necessary... I just personally do not find gameplay code works well inside of "in between" packet reading for gameplay objects
@pallid mesa This is a great way to be able to tune a jump arc
Component visualizer?
Nope
I have added begin play to count how many player connected. it worked. thank you
Hey guys quick question. Im making a 2d online game and I'm using repnotifys inside of my enemy bp to update the enemy's sprite flipbook, with the event ran by the server. Everything works fine in game, but i get this yellow error in my Output log "No owning connection for actor Monster_BP"
So my question is, is there anyway to run server events on an enemy bp without getting this error? For things like updating sprite flipbooks for all clients.
You probably do not need the event marked as Run On Server. Events marked like this are specifically meant to be used for clients to request the server to do something, but it won't work unless the actor is owned by a client.
ahhh interesting. Thanks that solved it for me
looks like its peeing
went to sleep, but yeah, what Megafunk said
@pallid mesa yo why cant i set the values for prediction?
like make it more/ less aggressive
i see no option for it
u can wdym its on project settings
unless they changed sm X'D that i dont know, havent had time to look much at this system on 5.5
That’s a huge resimulation threshold
wasn't it possible to run standalone build as dedicated server (with -server commandline) ?
or i need to build for dedicated server ?
you need to build for it and you need to do from engine source build, not from epic games launcher engine
that -server commandline only works for uncooked, so you can test client/server logic
You might wanna see a doctor if that's what it looks like to you 
x'D
So having multiple jumps you can assign as needed and modify in this manner is supremely useful esp. for platformers. This does work with CMC prediction 100% so long as you drive the data asset selection with something predicted (e.g. jump count for double jump). My editor tooling still isn't right, its actually good enough for most people esp. solo devs because its a reasonable indicator of what your adjustments are doing, but I'm a bit unhappy with that 😄 Probably just something simple I missed (its pretty considerable, since I fake simulate a CMC in PhysFalling)
Hello everyone,
I’m looking for help solving a frustrating issue I’ve been stuck on for a while. Despite trying several approaches, I can’t get it to work as expected.
TL;DR
Struct data in GameState is not replicating properly to clients — particularly keys that are themselves nested structs, even though the parent struct is marked as Replicated.
Context
I’m building a 2D backgammon game in Unreal Engine. I store the entire game state in a single custom struct, which includes:
Player sides
Dice results
Board pile positions
Whose turn it is
Other in-game metadata
This struct is stored in the GameState, and it’s marked as Replicated.
The logic to initialize the board (generate dice, set turn, and populate the board) happens inside the GameState and is run with Server authority.
The Problem
The listen server sees all the data correctly.
The client only sees partial data:
Dice values and current turn replicate correctly (✅).
But the board state (a nested struct or array of structs) is empty (❌).
Even though everything is in one struct and that struct is marked as replicated, some fields never get updated on the client.
As a test, I converted the entire game state struct to a JSON string on the server and fetched it on the client — and it showed the correct, up-to-date data!
But when I access the actual struct variable on the client, it shows only default values. This suggests Unreal isn’t recognizing the change to the struct for replication purposes — even though the data is technically valid and exists on the server.
@thin stratus Sorry for the ping but i have this same issue from 3 days and can't work around with it.
Can you please confirm the accepted answer is legit in this post?
to me it has no sense, why would AnimMontage_DEPRECATED property can be a reason for the client disconnect in a packaged build.
https://forums.unrealengine.com/t/unreal-5-4-problem-with-a-packaged-game-server-spawns-the-character-and-client-disconnecting-with-failed-to-load-package-error/1841350
Hello, guys. That problem killing my days so you are my last hope. I usually test my multiplayer project by running a local server with bat file with -server parameter and joining same way with -game. And sometimes for the group testing I package the game for my friends to join. Everything worked fine in 5.3 but in 5.4 I stuck with this proble...
i'm afraid applying this change could break the engine
One thing for sure that probably won't be replicated correctly is the players - that looks like you're replicating the PlayerControllers which are only replicated to the owning client, so those would be coming through as "None" on other clients. The other fields should be ok, but it depends on what your other structures contain as well. I imagine this structure is marked as Rep w/ Notify so you're using the OnRep of the variable to then drive logic client side?
Yes i know about the players, that was just for testing there, anyhow the issue happens mostly with struct within struct.
When marking it as Rep notify and call print on it it just print from server and not on client. See screenshot. If the variable is of different type like boolean for instance Repnotify will print from server and client
one more is confirming it as a fix, so not sure what to do... i really don't want to upgrade this project to 5.5 since it will have other issues and again distraction from development and finding fixes... 
How are you setting the value of the nested structure? As an example, here's what I did to test this functionality. As a side note, this only ends up printing the onrep on the client, not the server.
- First im creating a temp copy of a structure
- Values are changed using set member in Struct node
- At the end the struct value will be set from the temp variable.
(Note: i tried also to change the state directly without temp variable and same result. I read that just changing some property of struct might not be recognized as a change by Unreal so ended up creating temp var and assigning that to the original one in the end to trigger change)
What does the "Board" structure look like?
It has 3 vars of type map
Maps don't replicate.
The bigger take away is that you shouldn't connect with Editor Game to a Packaged Server, or with a Packaged Game to an Editor Server.
Either you start both, Server and Client via the Editor (incl Standalone), or you package both.
I packaged using project launcher and cook on the fly
Linux Server
Windows Client
Does your log on the Client talk about Checksum Mismatch?
yes, and then i added
[ConsoleVariables]
net.IgnoreNetworkChecksumMismatch=1
net.CurrentHandshakeVersion=2
net.MinHandshakeVersion=2
and that error gone, but still disconnecting with errors
The problem in that forum thread is specifically a thing because the user is only packaging the Game Client, while starting the Server with -Server.
Mine is linux dedicated server and windows client
If you aren't mixing Packaged and Editor then this is not the same problem.
The problem here specifically comes up cause the variable is marked as WITH_EDITORONLY_DATA.
yeah i am not mixing in 5.4
The variable won't exist in the packaged build, so when the replication produces a checksum, it'll be different between the Editor and the packaged Version
If you aren't doing that, then this is probably not the same issue
why would AnimMontage_DEPRECATED property can be a reason for the client disconnect in a packaged build.
The last post in that thread explains it fwiw.
yeah I did read it
so my issue is with packaged client and packaged server
and in 5.3, i don't have this issue
Then you'll have to debug it more and share some logs.
Ok, I will now reproduce the disconnect and will share the logs
@sinful tree what is the solution to this?
You'd have to replicate what you want without using maps. One potential way would be using an array of a structure that contains your key and value, then at least you can make an array that contains the key/value pairs that can replicate, and once replicated you can loop through the array and put it into a map for ease of use on the receiving end.
I am connecting to the server by calling a cpp function in the UI, from gameinstance
passing: `127.0.0.1` in the LevelName
void USurvivalGameInstanceBase::OpenLevel(FString LevelName)
{
UGameplayStatics::OpenLevel(this, FName(*LevelName), true);
}
hi all im making an interaction system and i am testing worst case scenarios and running 400 ping with 20% packet loss and im waiting a solid 1-2 seconds for the server to reply with the interaction interface, is tehre a way i can apply client prediciton (i think this is the name) to the interaction interface?
Are there any good docs that explain the key objects and structure of the engines code? Idealing covering multiplayer aspets and how it interconnects or is the only way to just read the code. I will read it but I also want a general guide since a bit of background info will help make the code make since when starting.
Those are partial logs only though?
i just copied everything from client/server window
also when i launched a dedicated server from editor as a seperate process, it also works fine
Thanks for your help, i managed to find out some posts mentioning that map does not replicate. I will figure out a way to convert variables, just didn't know that problem was with map type itself
Do folks here happen to know if it's possible to make Attach Component to Component on a Scene Component not replicate its attachment to clients? I want each client and the server to manage their attachments locally for a particular USceneComponent, but right now any time I attach a component to a component on the server, the change gets replicated to clients, blowing away whatever local changes they might have wanted. Is there a way for me to somehow bypass that?
I have Component Replicates set to false, but that by itself isn't sufficient I believe.
It doesn't look like USceneComponent allows you to customize this behavior, short of editing the engine.
My use case might be pushing the limits of what is customary first first person shooters in UE: I want to use the same exact instance of a weapon's static mesh both for the current player who has to attach it to their first-person arms, and for the third person version of the player, the way other players will see them from the outside, with the weapon mesh being attached to their third person model. It doesn't look like by default UE loves the idea of you attaching the same thing to two separate parents across the network. Managing visibility locally? Totally doable. Attachments locally? Not out of the box?
400 ping in total? The setup is confusing and it's possible you are applying double. Also 20% packet loss is insane, that's not a realistic number even in bad conditions
😭
Can you share the emulation settings you're using?
You're applying it two times - incoming and outgoing
apologies, ill make it 1 then
So you're testing between 400 and 800 ping
The only thing you want to use Packet Loss for testing, is to just make sure that your game can recover after
Outside of that, testing for packetloss is almost a waste of time.
In general anything above 300-500ms ping is not realistic for you to support
Even 300 is a lot
Yea
We try and aim for a smooth-ish experience at 250
Yeah exactly
Anything above that, youre on your own as a Player
Unfortunately there is only so much you can do to combat bad latency.
Specially without much cash for dedi servers
But even then, unless you literally restrict users to regions, they can always choose to join a server with 400ping
yep
They made that choice, they live with the experience.
Ohhh ofc
the issue is resolved by spawning the character with .5sec delay
your game should be functional on the server and for other clients if someone has an awful connection, but that messed up of a connection will never feel good for the person playing with it
guys how do i deal with packet loss
get a more stable internet connection
what if the players dont have a stable internet connection
it messes everything up
Component Replicates for dummies: what does that property do? Does it prevent all of the properties of this component from being replicated, even if they're set to be replicated? E.g. I mark a static mesh to be not visible on the server, will setting Component Replicates to false prevent that visibility from being replicated to the client's copy of the Actor? For the longest time I was convinced that was the case, but now I'm not so sure anymore.
I do need the whole log though if you want to get a chance at knowing what this is. The delay to spawn the character isn't a good idea, especially if the .5s are just hiding the issue. If it's ping related then a slower client will need a different delay and it breaks for them again.
if a player has meaningful packet loss, theres not much you can do to improve their experience
design your game to be functional if that happens, but dont focus your efforts on players with 300+ ping and high packet loss
itll exacerbate race conditions and other traps in multiplayer design
You can't fix package loss. You can only make sure, that your game doesn't lock up from it, by testing with ~1-3% and seeing if the player can get fully stuck somehow.
But that usually needs a special kind of shitty net code to happen
usually a result of relying on unreliable packets from my experience
i know i cant avoid it but my code is getting messed up when it happens
ill just figure it out
use OnReps with properties and other network events that are reliable to access information at the right time
The thing is, that doesn't mean package loss messes up your code. It means your code is messed up to begin with 
You'd be better off explaining what the mess is about. Otherwise you are trying to solve the wrong thing.
i need to do more testing
anyone here use iris filter thing? how do u specify what actor in a distance to filter them? because i want to after i filter them, in my significance manager, do something for visual stuff
like how can i say if an x actor is at x distance, we filter these actors out

are there struct for this?
https://www.fab.com/listings/137d22e7-963c-4979-90d8-5ed68add1f64 should I use this instead of int if I know variable won’t reach int16 limit?
Notice: This plugin is now open source. But you can purchase if you want to support the development.Github: https://github.com/edgarbarney/Int16forBPsDo you want to make your variables have less size and you don't need values greater than 65535? This plugin is going to help you to achieve your goal.This plugin adds a struct called "Integer16" to...
Nevermind it doesn’t work for blueprints
I'm not sure how "16 bit integer for blueprints" doesn't work for blueprints
Well I can just declare variables in c++
Hmm but there isn’t int16 data type in BP so guess I can’t utilise that
Agreed unless there's a bottleneck you've identified or something? But saving a couple of bytes in a packet is a bit of a micro-optimisation unless there are a lot of them?
only might make sense for networking payloads
well this is #multiplayer and I did say "packets" lol
You can tell from the screenshots that all they did is wrap int16 in a USTRUCT wrapper and expose a library for it
true lol my bad
A lot of fluff really
If bandwidth is a concern, I would also be curious about Oodle
Unless that's default now? (no idea)
yeah that's a good question, I wanted to look at it. Iirc it needed training so I don't know if they can automate it
There is some compression going on already because I tested some stress scenarios and the in/out bytes were lower than they theoretically should be
I have weird bug with move component. Client see itself lagging, like server is trying to correct his position even with ping 50, I have enabled in player pawn that it shouldn’t do it
There is a checkbox in component but it seems like it doesn’t work?
Wow they actually are planning it 
charging money for this is crazy
lol I thought it was free
The card is older than the last reply in the GitHub PR :D
hello! What is the recommended work flow for switching between debugging client, server, editor?
Currently, rebuilding my project takes about 45 minutes. So when I want to launch the editor, I switch configurations and its a 45 minute wait. Then I go back to debugging the client, and its another 45 minute wait. Obviously not sustainable, is there a better way?
My question is why rebuild?
If you rebuild, you are literally deleting all the build products and forcing it to start again
There's no reason do to that really
heh yeah, definitely not doing that on purpose, its just what happens when I press build
its currently compiling 3133 files. Its doing a full rebuild, I dunno why. I feel like switching configurations should not cause that
sounds like your building source
Yeah it def shouldn't be doing that, even if building from source
yeah definitely building from source. but yeah..
only thing that is weird that i noticed is when i do switch configuration and press build the first time, it fails wiith a bunch of UHT "could not copy dll" errors. I wonder if that is causing it to nuke a bunch of things and start over?
cause when i hit build again, that's when it starts rebuildng everything
maybe antivirus being a bitch?
haha! nah I don't have anything other than windows defender. But probably environment related somehow..
I DO have rider opened alongside VS2022. I use VS to code/debug and Rider is just there for when i need to add or rename files haha. But I wonder if that's causing issues. I'll try and close VS and change configurations in rider and see if that works
On server I need to check if two controllers belong to the same client (split screen). Is comparing their NetConnection a good way to do this?
me think that almost definitely causes issues
I compress some vectors/floats to uint16, uint8 loses too much information
But when I'm optimizing in such a manner I'm sure as hell not doing it in BP
Yup, that was the issue
we also compress vectors to int16 for positions but it's a very specific case. Also we further compress by dividing by a constant and multiplying back on client
Curious to get some opinions, is there a good argument to be made about using a custom netcode or a third party netcode like SnapNet or others instead of using Unreals built in replication system?
We're making a fast paced FPS with a maximum of 20 players in a lobby (typically only around 8). We've been using the Unreal replication to this point but were just wondering about alternate solutions. Also interested in potentially using Iris, but not sure about what that really changes compared to the default replication system
As with most questions like this, the answer is "it depends".
Depends on what your needs are, depends on what solutions third parties offer.
To be honest, if you are asking a question like this, you don't need a third party solution.
You need to learn more about Unreals netcode.
And how it relates to the result you are looking for.
i heard iris offers better control over stock replication and replication graphs are on their way out
fornite is a shooter with hundred players and that uses iris i think
I am very aware that we have lots to learn 😅 I was actually trying to ask for what some cases of "it depends" would be and if there are any good ways to tell if the scope or needs demand for something like that. I assume we are fine with Unreal's netcode but just wanted to ask about what makes someone consider other options! Sorry if I made my original message confusing
I read a lot of the Iris documentation, and the FAQ mentions that Iris may be less performant than the standard replication depending on use case. That kinda got me scared a bit to try it haha. It specifically mentions on smaller scale games with less player counts that it could be worse but depends on use case
It seems that it's not much development overhead to go with/without it, so we can try both if that is the case, but if it's a lot different then it would be a pain to set up the whole system to profile and then have to scrap it all if it performs worse
i think iris offers better control over updates and dirtying things. i dont know how much more bandwidth it uses tho sorry
No worries, appreciate the input 🙂
I'd think limitations of Unreal's network code would be the primary reason for considering alternatives.
A few I know of that could potentially be mitigated by third party solutions:
Unreal always requires a hard load whenever you're traversing from one server to another, so you can't really have a client moving from one server to another without some kind of brief pause/loading screen as the engine connects and loads up the assets it needs when joining the server.
Unreal can be made to support multiple worlds running at once within a single game instance, but it can only support replication within one at a time, and if I remember right, if you wanted to try and facilitate multiple worlds with replication at once, you'd have to rewrite much of the Unreal's source to do so. So this means if you want to run game servers, they each need their own instance of the executable running, rather than being able to have multiple copies of the game running off of one executable instance.
Unreal doesn't support Peer-To-Peer networking nor host migration out of the box. This means if the server happens to drop, then all connected clients will drop as well, it doesn't attempt to move the players to a different server, or establish one of the clients as the new host (in the case of listen servers).
I haven't worked with Iris, but I'm fairly certain it doesn't handle any of these limitations as it's still based around Unreal's built in networking system.
If you do decide to go with a third party solution for the network, you can't really use Unreal's own built in systems for replication, movement, and processing of the gamestate, so your Unreal game client basically becomes a tool for visually representing the gamestate of your third party solution and sending commands to it.
fwiw, the game you are making is most likely the best fit for what UE offers.
Building a game on a third party solution can often be a fool's errand. The company can fold, abandon the project, sell out, etc, then your game is screwed. And a lot of them are simply not battle tested in production.
Point in case on both fronts: SpatialOS
IMO if your concept can't be built on unreal networking the problem is the concept. Of course with games like fighting games or RTS you do need to roll p2p in a lot of cases. So it's not a hard rule or anything but these things should be part of the decision
lol
y stop at int16
let them have full spectrum of unsigned integers which go even lower
Hello guys I think the issue is the RPC serialisation but maybe I'm missing something :
I have these structs :
struct FServerFunctionParams
{
GENERATED_BODY()
virtual ~FServerFunctionParams() {}
};
USTRUCT(BlueprintType)
struct FAttributeParam : public FServerFunctionParams
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite)
FInvestigationAttribute Attribute;
};```
I have this generic RPC in my PC :
``` UFUNCTION(Server, Reliable)
void ServerExecuteFunction(UObject* TargetObject, const FName& FunctionName,
const FServerFunctionParams& Params); ```
With this Implementation :
```void ABasePlayerController::ServerExecuteFunction_Implementation(UObject* TargetObject, const FName& FunctionName,
const FServerFunctionParams& Params)
{
Blablabla tests etc
if (FunctionName == "OnAttributeSelected_Remote")
{
const FAttributeParam* TypedParams = static_cast<const FAttributeParam*>(&Params);
struct {
FInvestigationAttribute Attribute;
} ActualParams;
ActualParams.Attribute = TypedParams->Attribute;
TargetObject->ProcessEvent(Function, &ActualParams);
}
}```
My problem is that even after the struct static_cast my TypedParams values are all over the place, so I assume there is some memory shift or head pointer issue with &Params, is it due to the RPC serialisation/deserialisation ? How do I fix without having to write one RPC per type of payload ? Knowing that templating and Ufunctions are not compatible :'((((
That won't work
If you want to send polymorphic data use FInstancedStruct, that's the only way to do it properly
And it exists for that purpose
Ok thank you
Also note that it's vastly more expensive to do what you're doing, than just implementing different RPCs
And FNames should be passed by value not const ref
I mean these RPCs are quite punctual, it's all event driven no tick setup, you mean expensive in bandwith because of the size of the payload ?
It's more expensive to send in the first place
FNames are sent as strings, so for a function name like "OnAttributeSelected_Remote", you're sending an extra 26 bytes minimum, plus the object itself (another 2 bytes minimum, likely more if it's stably named), then the payload - and since it'll be an instanced struct, it will also need to send the struct type.
I suggest looking at how GAS sends target data if you want an example of how to recycle the same rpc
You can do a better version of what GAS does with FInstancedStruct - but I'm confused about why you would send the function name when you can infer that from the data type you send
I used to directly put the Struct as the params to the function in the ProcessEvent, so the struct had to perfectly fit the expected params, so I didn't need this extra step of extracting the params from my structs :
UFunction* Function = TargetObject->FindFunction(FunctionName);
if (!Function)
{
UE_LOG(LogTemp, Warning, TEXT("Object %s does not have function %s"),
*TargetObject->GetName(), *FunctionName.ToString());
return;
} ```
Im not familiar with them. How would you use the same rpc to send child structs of an InstancedStruct?
Do you just pass them by const reference to the rpc?
UFUNCTION(Server)
void ServerSomeData(const FInstancedStruct& TheData)
{
if (TheData->GetScriptStruct() == FMyStruct::StaticStruct())
{
DoA(TheData.Get<FMyStruct>());
}
else if (TheData->GetScriptStruct() == FAnotherStruct::StaticStruct())
{
DoB(TheData.Get<FAnotherStruct>());
}
}```
This still reeks of code smell but it's possible
I wouldn't actually advocate doing the above though
Even in a situation similar to target data for gas?
For example a weapon class, which can have various actions (non replicated uobjects), which then would need to use the weapon class to send RPCs (shoot data and stuff like that)
In this case wouldn't it make sense to use a single rpc to avoid having to keep adding different rpcs to the weapon class?
Love it, works great thanks, bye 🙂
How long do you reckon it'd take y'all to create a bog-standard multiplayer FPS?
I've seen some claims that it's faster to do nowadays with UE5 compared to back in UE4 but not sure how substantiated those are!
I mean there's an FPS template, multiple in fact
id say the biggest variable is how much you need to learn in the process.. that can slow things down
Fair point!
Are the templates any good?
the FPS templates are a good starting point, but last i checked there is no specific multiplayer logic in there other than the cmc ?
there isn't much logic in there in general. it's just the bare minimum to get started
There's also ShooterGame and Lyra, both pretty servicable
It's an impossible question to answer tbh
i found lyra to be a bit complicated to work out what was going on properly, but i am still new to game dev so...
Does Bog standard include lag mitigation (Server input rewind, client prediction, extrapolation, Reconciliation etc ?)
To be fair you would likely have this issue with any semi complicated software project you step into until you dig into it or get a guided tour. There's nothing insanely complex about Lyra. It's standard GAS and CommonUI driven by some neat data handling in their Experience system.
Gotcha, thanks for confirming!
I was thinking more in terms of gameplay but fair point on the net code side!
The issue is that you'd need to define your definition of standard. Are we talking traditional arena shooter with FFA, CTF, Team Elim, etc etc? The code for this stuff is rather simple if we're staying at 12 or less players. No need for insane optimizations etc. Are we adding in a full options suite? What kind of UI? Is it customizable? Do we have classes in this game that may require different UI elements than the rest? Do certain weapons need special UI? Are we allowing customizable crosshairs? What is your asset count? How many weapons are we talking about? Full character customization options or just armor? Are we a single person doing both art and programming? Do we have a team? What team size if so? What about assets in general? Anything from Game art to UI art, sounds, models for weapons and characters. Do we get these as asset packs or are we making them? What quality level? If they're asset packs are they actually functional or are we going to spend time fixing and optimizing them?
You're missing a lot of info even if you're just asking from a gameplay point. You can probably make an arena shooter in a week or two and have it pretty fully functional with a few different game modes and basic gameplay if you disclude any sort of special classes, character customizations and use blockout art for both gameplay and UI. Start on the rest of it and you're looking at a minimum of several months, more if you're doing assets yourself.
like 5 minutes if you have no standards
normal character movement is perfectly serviceable, you can just use RPCs to LineTrace for damage, enhanced input is pretty easy, damage is like a 5 minute YouTube tutorial
main difficulties come from making your game resistant to network lag and untrustworthy clients
unreal makes it very easy to get straight into just making gameplay, but there's arguably an unbelievable amount of boilerplate shit for a good feeling fps
anyone encountered the problem where advanced sessions causes unreal engine to crash?
it worked perfectly without it
and i added it to use the additional functionality
and now my multiplayer just crashes the moment i join to a client with another client
i'll try to update it but doubt that's gonna help
yeah still crashes it
This is very insightful! It's like they say, the best way to get good answers is to ask better questions!
Hadn't considered the optimization side of things!
if i use the default built-in one it works perfectly
You'd need to provide a crash reason for anyone to be of any help. But a lot of people use it.
A long time, im two years in, itll require at least intermediate skill level c++ and netcoding knowledge to implement properly. The templates lack major required netcode, are awkward to modify, and full of bad code practices, overall not meaningfully easier in ue5 to ue4
How close would you say you are after two years under your belt?
in my case, probably 40% done, not in a particularly playable or presentable state, but that is skewed since i dont intend to use marketplace assets or animations
bog standard multiplayer FPS can be done in an hour if all you're expecting is to shoot and kill other players.
as others pointed out, and just now, an online and networked fps like counter strike will take a lot of work trying to do it properly
this is also skewed as many current triple A fps titles still shortcut anti cheat
something like payday 2 or any non-competitive horde shooter can take a lot of shortcuts
Eh... When I hear bog-standard I think more like, completely uninspired, working prototype where fundamental gameplay systems work, which for a multiplayer FPS is basically:
- Supporting sessions whether through dedicated servers or listen servers. (Players can host, find and join games)
- Being able to shoot a gun and kill players. (Allowing some kind of gameplay that fits the FPS genre)
- Players can respawn in some way. (Allowing players to continue playing the game after being defeated)
Lyra itself has these three things already done for you. Reskinning it and customizing it to what is desired would definitely be a task, but things like game modes, additional movement systems, a variety of guns, optimizations, having some kind of purchasable weapon systems, and having a variety of maps to me doesn't fit into how long it could take to make a bog-standard multiplayer FPS because all of this would vary widely based on the skill of the person and what it is they are actually trying to make.
What types of shortcuts? I've played Payday 2 but I'm not savvy enough with net code to notice where they've cut corners!
Your definition of bog-standard is the same as mine so if Lyra has those three covered I'll take a look!
Though I definitely agree that customizing it beyond that point to make it unique will be another undertaking entirely!
hit detection being supplied by clients instead of the server, meaning no validation or anti cheat needed
The thing with Lyra is you'd also kinda need to understand the #gameplay-ability-system for a lot of its systems, as it's one of the highlights of that project, but it is a worthwhile and powerful system to learn and use.
Ah that makes sense! Though I imagine if Payday 2 were PvP instead of PvE then that shortcut would no longer be viable?
Will be sure to look into that system then! Any starter resources you'd recommend?
Lots of good pins in the #gameplay-ability-system channel. You can look into Lyra and there are some example GAS projects like GASDocumentation and Narxim's GAS example.
Thanks, will check those out!
yes cheating would then be rampant
Client-side hit detection would be very easy to fudge or mod
GTA5 is a good example of why you can't trust clients. The "hacks" there are only there because the servers allow clients to tell the server to do things XD
On the upside, their P2P servers mean Rockstar will never shutdown servers
you can do CSHD + verification, but your verification has to be fairly watertight
exactly, thats why most competitive shooters choose to host their own, balancing cheater protection vs longevity
That makes sense! Which anti-cheat do competitive shooter UE5 games typically use nowadays though? It's been a while since I've dived into FPS games so I'm a bit out of touch!
Lots of execution risk with that approach 😅
sswires reply above denotes what indie devs should use,
sswires — 6:43 PM
you can do CSHD + verification, but your verification has to be fairly watertight
third party anti cheat is incredibly expensive, so properly programming our own verification into shooter systems is the best indie devs can do
well you need to nail rewinding too for the serverside approach as well
because bad user experience for all is worse than some cheaters
Seems like there's a gap in the market for budget anti cheat providers targeting indie devs, but until that gap is filled CSHD may be the only viable approach yeah.
you can't rely solely on clientside anti-cheat
in any other non-competitive circumstance, such as for pve, like in a co-op shooter, i personally recommend forgoing validation
Yep, and harder to bounce back from as well. If cheating is fixed players often return. If the UX is bad they'll have no reason to come back.
your standard borderlands player isnt really going to care that billy modded an insta kill weapon
Right if it's co-op then a vote kick should be enough if they're unhappy with a teammate cheating
on a previous project, we completely disabled hit verification in co-op and it was never really a problem
exactly, even simple notifications like minecraft for example, where it'll warn the host that someone might be flying
cheaters tend to prefer making real players angry, not bots
Right, competitive PvP creates the incentive to cheat in the first place
Funnily enough there are lots of false positives with that so thankfully Minecraft doesn't kick automatically lol
Which project by the way? Anything I can wishlist or play on Steam?
well it was Insurgency: Sandstorm but the studio is dead and its corpse is just being animated by Saber Interactive
fun game
Is there ever a situation where you spawn a new actor on the server and you set its owner that same tick, and then when the actor replicates to the client the owner is set to null or not valid for some reason? Maybe if you spawn the character who becomes the owner and the actor who is owned both on the same frame, and then perhaps the client gets them out of order and cannot resolve the owner reference?
I have been warned of this, but I haven't personally run into this issue so far.
If you're setting the owner to something that doesn't exist on the client/isn't currently replicated to the client, the owner would be null on the client. My own test by printing the owner on begin play shows the client receiving the owner both when the owner is set on the spawn actor node and immediately afterwards on the return value of the spawn actor node using the set owner node.
Thanks for checking! So it sounds like the engine will always somehow give you a valid owner as result, if I read your second sentence correctly?
It gave me a valid owner as I told it to use an actor as an owner that I know for sure was replicated to my client.
If you were to say, use some other client's player controller which only replicates to the owning client and no others, then that owner would be invalid on other clients.
Oh wow that's actually in my library but I only played it for a bit because I was too trash to not get picked off constantly lol
Off-topic.. but damn, I had no idea about that.. that sucks
Even if I sucked at the game I could tell how well made it was
Did you join a new studio or become an indie dev after Sandstorm?
Hello, is there a case where AActor::Owner is not replicated in time to a client when the actor itself is replicated? E.g. if I have a player state, is it possible that on begin play it's owner will be invalid in case the PS is associated with locally controlled player?
I left the studio in 2022 since after the studio was bought by Embracer in 2020, a lot of horrible changes were made, particularly in leadership
The co-op mode is way more casual and that's what I tend to play whenever I hop on to see how it is
I am using GetPlayerName() to block multiple instance joined from the same PC
is it a good practice?
ofc i can do using their IP address, but it can be an issue if another pc on the same netwok will try to join
this is my custom session code:
void AArmaGameModeBase::PostLogin(APlayerController* NewPlayer)
{
Super::PostLogin(NewPlayer);
if (!NewPlayer) return;
FString DeviceID = NewPlayer->PlayerState ? NewPlayer->PlayerState->GetPlayerName() : FString();
if (ActiveDeviceIDs.Contains(DeviceID))
{
KickPlayer(NewPlayer, TEXT("Device Already Logged In"));
return;
}
if(AArmaGameStateBase* CurrentGameState = Cast<AArmaGameStateBase>(GameState))
{
if (CurrentGameState->GetIsMatchStarted() || CurrentJoinedPlayers >= MaxAllowedPlayers)
{
KickPlayer(NewPlayer, TEXT("Session Full"));
return;
}
else
{
CurrentJoinedPlayers++;
ActiveDeviceIDs.Add(DeviceID);
}
CurrentGameState->Execute_NotifyPlayerJoined(CurrentGameState, NewPlayer);
}
}
well, steam display names aren't unique, so I doubt it
not using steam
Also what's to stop the second instance just changing the players display name
if they try to change it, their first instance will be disconnected from server
and if I change it before I connect?
Also it's perfectly reasonable for two completely different people to have the same display name in game
So when Russian Jambax joins I get kicked?
Why would you even want to do this in the first place
getplayername is returning the device id
an IP address is about as a unique identifier you have without any sort of backing authentication, but those change frequently and 99.9% of people will have dynamic IPs
but from the same network, two pc's will have same ip
auth is something like Steam provides and a unique net ID (Steam ID) is about as perfect as an identifier you can get
i'm using custom null subsystem
well that doesn't mean much. the null subsystem just means there is no online service
you have no way of reliably identifying a user without one
hmm, and what about giving them accounts and custom unique ids
the id's the server will also have, and if any id joined we marked it on server as already joined
well if you want to develop, host, and maintain your own account system then knock yourself out
but for most people on PC, Steam or EOS would be enough
I applied for custom steam app id, they rejected my game 😄
so i have no plan anymore to depend on external services
also what is that: FString DeviceName = FPlatformProcess::ComputerName();
I thought you just paid the fee?
you do lol
computer names are not that unique either and the user can change it at any time
no i didn't lose money
but not if they are already connected
if they do, their old session will be terminated
right?
but what makes you think device IDs are unique anyway
well computer name changes typically require restarting the machine but if you're dealing with persistence then that's a no-go
and to reiterate: they're not guaranteed to be unique
even for me, when i install new windows, it change every time
that thing you can famously change in the installer right
hmm, than i have to think of some custom unique id's with my login system
I have an old NUC that is just named "MiniPC", that's not even close to unique
if we right click on the computer icon and press properties, it shows a long device id
yes, the thing you can change if you want
i think this should be unique for all pcs?
if they change it yes it can make issue if it match with other devices
if they didn't, it will be unique i guess
one more thing i think which will work is
FString DeviceID = NewPlayer->PlayerState ? NewPlayer->PlayerState->GetPlayerName() : FString();
FString PlayerIP = NewPlayer->GetPlayerNetID().ToString();
if(ActiveDeviceIDs.Contains(DeviceID) && ActivePlayerIPs.Contains(PlayerIP)){
}
now if they change the device id, it will not effect other players with same id
end my suffering
tbh i'd personally make some sort of simple text based username/password thing in sqlite instead of relying on windows to give the ID (if you arent using an online service at all)
this is the right method to get player ip
UNetConnection* PlayerNetConnection = NewPlayer->GetNetConnection();
if (!PlayerNetConnection) return;
FString PlayerIP = PlayerNetConnection->LowLevelGetRemoteAddress(0);
Which you should never need.
oh, is there any other method to get the ip of the connected player?
I'm not really sure how else to phrase that.
You said "This is how you get the IP"
I said "You should never need that."
How/What/Why would that insinuate that I meant anything to do with a way to get a thing I said you should never need?
ah, you mean i should never get the player ip?
why should not i if i need it to make sure that nobody is spamming the lobby
well, the device id is somehow generic on every join.
two login requests from the same machine.
Login request: ?Name=DESKTOP-WIN11PC-75991247428BB35BF6FED498F4001X4L deviceId: NULL:DESKTOP-WIN11PC-75991247428BB35BF6FED498F4001X4L platform: NULL
Login request: ?Name=DESKTOP-WIN11PC-996958E0422028A47E794BA35EDEFDE8 deviceId: NULL:DESKTOP-WIN11PC-996958E0422028A47E794BA35EDEFDE8 platform: NULL
only DESKTOP-WIN11PC is same on every join request, and the id generated is not unique
i think i need to modify the null system so it can generate unique id if the DESKTOP-WIN11PC is same on second join request
Oof sorry to hear that
I didn't even know there was a co-op mode 😅 Might reinstall and check it out sometime!
ip doesn't uniquely identify someone as their can be many people under the same ip
the only way you are going to reliably identity someone would be through some central server or a blockchain
ip + pc name
also there's nothing stopping someone from fudging their PC name or IP
you're trusting the client for this information
goal is to stop multi joins from the same pc
if they change the pc name, they have to restart and leave the game
so they can't join twice to spam the server from the same pc
they can just hack and change it
this is a silly problem to solve with silly answers
its their issue, if they change it they will be disconnected from server
To be fair, you have to trust the client at some point to give you information. Someone savy enough will be able to change w/e they want in the packets they send out.
sure and that's why a lot of games combine anti cheat with some sort of hardware id to permaban
without anti cheat it's likely trivial to just change the id the game collects from the PC right before sending it to the server
I just tested the method i am after and it now works fine.
Two attempts to join with same machine: both clients were kicked; ✅
Change the pc name without restarting it using some third party software while already connected to server, and the client disconnected because of tick failure on the netdriver ✅
this is the log when attempting to jon twice:
LogTemp: New Player Logged In DeviceID: DESKTOP-MYWIN11PC-XG92
LogTemp: New Player Logged In PlayerIP: 127.0.0.1
LogNet: Join succeeded: DESKTOP-MYWIN11PC-XG92
LogTemp: New Player Logged In DeviceID: DESKTOP-MYWIN11PC-A35B
LogTemp: New Player Logged In PlayerIP: 127.0.0.1
LogNet: Join succeeded: DESKTOP-MYWIN11PC-A35B
and i ignored the -Generic using this method
FString AArmaGameModeBase::GenericStringToUnique(const FString& DeviceID)
{
TArray<FString> DeviceIdParts;
DeviceID.ParseIntoArray(DeviceIdParts, TEXT("-"), true);
if (DeviceIdParts.Num() >= 2)
{
return FString::Printf(TEXT("%s-%s"), *DeviceIdParts[0], *DeviceIdParts[1]);
}
return DeviceID;
}
Microsoft should never allow changing windows ID, this will solve many issues on the first place
if user want to change it , let it reinstall windows 😄
blockchain 
Can’t you just use the pcs MAC address?
It’s practically what it’s for (uniquely identifying)
This whole train of thought started because "Steam rejected their project." Steam doesn't reject projects. You can literally put a screensaver with dogshit on it if you just pay the $100 and have valid tax records.
yeah I'm still confused by that part
the mistake is trying to comprehend
Which one?
if only authenticating users was an industry-wide practise with several solutions available
That could be a perfect idea in this case, but i am not sure if they change the mac at run time while they are connected to the server will they be disconnected or not 😄
No idea but you can give it a try?
At this point it sounds like you’re just trying to prevent multiple instances of the game running at once. If that is the case you could just do a named global mutex
https://learn.microsoft.com/en-us/windows/win32/sync/using-named-objects
Thanks for this, I will give it a try ofc
If you're relying on the client to tell the server their MAC address, then it's moot as a client can spoof any information sent to the server. If you're somehow using detection of MAC address on the server, then you could also end up blocking players who may be on the same network but separate PCs (ie. their MAC address for both clients could end up being the MAC address of their router)
if only Steam was being used to authenticate players
then you could also end up blocking players who may be on the same network but separate PCs (ie. their MAC address for both clients could end up being the MAC address of their router
Are you referring to public IP address here instead? Mac address should be unique per device
then you're still relying on the client to send that, and mac addresses are trivial to spoof
like even your phone can do it now as a public wifi privacy option
In any case I am with you if they are relying on the client sending that data, assumption here was they're doing validation on the server based on the connection itself not something they (misty) are sending
The amount of backend features one would need to code to replace Steam or EGS. The uniquely identifying players feature is just one little thing.
And imagine how annoyed players were with EGS becoming a thing. Imagine how much they enjoy downloading a game from some random website.
If they even find said website.
This means something is nullptr or is it related to other things?
Malloc Size=262146 LargeMemoryPoolOffset=262162
CommonUnixCrashHandler: Signal=11
[2025.09.16-15.36.58:192][636]LogCore: === Critical error: ===
Unhandled Exception: SIGSEGV: invalid attempt to read memory at address 0x000000 0000000000
[2025.09.16-15.36.58:192][636]LogCore: Fatal error!
0x00007fb462781520 libc.so.6!UnknownFunction(0x4251f)
most likely
but i'm checking for validity of everything before using it
do you not have a debugger attached that breaks on the bad read?
its a shipping build server pie running outside of my pc in an online server on ubuntu
locally it never crashed 😄
I think i have to build in debug game editor to get more logs
This block of code is making issues when player leaves the match if he was overlapping the damage zone
OverlappingCharacters array was changed when iterating.
void ABlueZone::DealDamageToVectim()
{
if (!DamageTrigger)
{
GetWorld()->GetTimerManager().ClearTimer(DamageTimerHandle);
return;
}
if (DamagePhases.IsEmpty())
{
return;
}
for (AArmaCharacterBase* CurrentTarget : OverlappingCharacters)
{
if (IsValid(CurrentTarget))
{
const float PhaseDamage = DamagePhases[CurrentZonePhase].PhaseDamage;
UGameplayStatics::ApplyDamage(Cast<AActor>(CurrentTarget), PhaseDamage, nullptr, this, DamageType);
}
}
}
Iterate backwards over the array.
Although it's a bit strange that this would trigger when they leave, given this is a singlethread thing. The code to remove the player usually doesn't run here.
It would be more logical that your code destroy the Target when applying damage, causing it to stop overlapping and being removed from the array.
If it really triggers from the leaving, then backwards iterating won't even solve that. Might need to copy the array into a local one before iterating it :<
No, I meant MAC address here, I'm just not sure what Unreal has in terms of a server detecting client MAC addresses - I know there is a means to locally get a MAC address of their current network adapter so that would involve the client sending the MAC address which again could be spoofed. I'm just imaging that if one were to try and have the server use the IP address of a client to try and find their MAC address, it would usually return the MAC address of their public facing device, which would usually be their router, not their PC or console or whatever.
I test it like enter the bluezone and the character is added to the vectim's array, and i leave the game while it was still overlapping and it crashed with the error i mentioned
Yes I think it just need to pass by copy , if the character is removed from the original array it will still be in the copy array and on isvalid check he will be skipped
Now doing this which works at least. for now
I think i need to force the players to register their mac addresses, and i will have an array of them stored in the server
so if they want to be validated by server, they should use the address which is registered in the server
and i have a combination of their mac:ip registered on server
And in doing so, you'll run into the problem that if you have a client registering their MAC address, someone who was persistent could just send a spoofed MAC address anyway, and still have multiple copies of the game on the same device connecting.
what i mean is, lest say you have this mac and ip registered in the server
mac: 1234
ip: 127.0.0.1
you can only join server if your device mac and ip is not changed, it will be verified when you send join packet.
if the mac is spoofed, it will not match with the registered mac address
and the verification will use combination of mac:ip
So what if my ISP uses dynamic IP addresses?
Or I happen to go to a friends house to play?
shit outta luck I guess
What if I buy a new computer? o_O
Or I have to get a new router?
or whatever network device?
dynamic ip is range base, 127.0.0.1/100 it mean it can be between 127.0.0.1 to 127.0.0.100
or tethered through an iphone which changes mac every session
and registerd the mac against the whole range
change the mac of the new router to use the old mac
just buy the game again
nice business
You're going to expect people who don't know how to use IP addresses to figure out how to change their MAC addresses?
all zero players will love doing that
I can help them by giving them a small readme text file 😄
Why not just make the game too hard to multibox
nobody is multiboxing Counter Strike because that'd suck
they multibox slow games like WoW and EVE
What is the problem your insane DRM idea is solving?
because allowing them to only join with registered mac/ip, can help me to bann them quickly if they cheat
they will not cheat, they know they will neeed to get a new ip
its mean ordering a new connection
Why doesn't Valve or Riot do this you think?
Oops, changed my VPN... Oh crap, I can't play any more.
whoops I moved house, there goes the game library
they don't want 😄
No, it doesn't work, that's why.
it does, i am testing it all day
You might be able to ban all cheaters, sure, but you'll also ban almost all players
Then you get class action lawsue'd because you deprived 90% of your theoretical customers of what they paid for
no, because everyone has unique ip, this is why combination of mac/ip verification
IP changes all the time
whenever you move
whenever your ISP wants to
whenever you connect to a different wifi on your laptop
i know this and every internet connection has a ranged ip address
example: 127.0.0.1/50
this ip can only change in its range
this is the same network
that's LAN lol
Everyone does not have a unique IP. My house has a unique IP, but that IP can be dynamic, so it's no longer unique to me. You don't know what standards my ISP would use to assign me an IP address, and you don't know what other IPs they may use in the event of failures or upgrades, or anything else.
ok so what if I move
can't play game
what if I want to play it on vacation? banned
switch ISPs? banned
inform me, I will do some steps to verify you
lol nobody will jump through those hoops
if they want gameplay without cheaters, they will do it
the idea is your account name and password is your ip and mac :d
that's a horrible idea
why isn't your account name, idk, your actual account that you bought the game under?
that works, i tested it today with friends
test it next year with strangers who paid for the product
If this game isn't free you will have approximately zero playerbase
they should be agree with agreement before they buy the product
if it is free, then you'll just get new accounts popping up like crazy
either way you're back to square one
new account registration only through me
registration will never be automated
all manual by me 😄
per day only 50 accounts registration
You won't hit that limit for a while, should be safe
today 16 registered 😄