#multiplayer

1 messages · Page 249 of 1

grizzled stirrup
#

Once all players are connected and a game has started with no join in progress, would destroying the session do anything negative there out of curiosity?

#

Or would it just play out as usual just without the ability to invite or join?

thin stratus
#

You shouldn't destroy the session though.

#

Just deny people in PreLogin/Login

river shore
#

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

thin stratus
river shore
thin stratus
#

You can limit the replication target of variables

exotic wasp
#

replication condition owner only!

river shore
#

cause I heard somewhere that you shouldn´t replicate ref but only soft refs is that a thing?

exotic wasp
#

im not sure that's true?

dark parcel
#

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.

river shore
#

thx guys ^^

torpid crest
#

seems like now without delay enhaced input is not init? 😄

dire burrow
#

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

torpid crest
#

oh it runs on server that's why

#

I need to do in client after possesing the pawn

dire burrow
#

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

dark parcel
#

No, interface has nothing to do with hooking an event for init.

dire burrow
#

why do you keep thinking every single thing i say has nothing to do with anything?

dark parcel
#

If anything that just make it harder to debug

dire burrow
#

Its a interface

#

it just makes life 1 tinny little bit easier

#

events wont be solving shit

dark parcel
dark parcel
#

Move the input binding to the client rpc function.

torpid crest
#

this works fine 🙂

dark parcel
#

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

torpid crest
#

any external plugin that would expose it?

#

from fab

dire burrow
#

did you press the eye ball

dark parcel
#

Nahh no such thing

dire burrow
#

oh

dark parcel
#

It's in the engine code and not marked blueprintable

dire burrow
#

ah

dark parcel
#

But anyone with cpp knowledge can just override it.

dire burrow
#

yeah override it baby

torpid crest
#

time to add C++ to toolset 😄

dire burrow
#

when you got c++ you can create a sub class of any thing

torpid crest
#

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 😄

dire burrow
#

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

exotic wasp
#

UPoopComponent

prisma snow
daring tangle
#

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

sinful tree
rich dune
#

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!

daring tangle
thin stratus
#

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

dire burrow
#

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

thin stratus
#

I don't really follow. What "Heatrotation"?

dark parcel
thin stratus
#

Ahhh

dark parcel
#

Also bad tutorial on youtube by codelikeme is titled "how to replicate variable in anim blueprint"

I think that headline still stuck on him.

dire burrow
#

JESUS CHRIST

#

you keep comming back to this

#

its IRELEVANT

rich dune
# thin stratus > But after a seamless travel, it seams like the PlayerController Begin Play is ...

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.

thin stratus
#

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?

rich dune
quasi tide
#

I just made a "PostSeamlessTravel" method in my playercontroller personally. Then just call that.

thin stratus
#

SeamlessTravel allows you to move information between the levels better than any other travel.

thin stratus
#

They are literally coded to have a function for that.

rich dune
#

to where?

thin stratus
#

To the new PlayerState

rich dune
#

Where do I access an old player state and write to a new player state for the same player

thin stratus
#

It calls on the old one and passes in the new one.

rich dune
#

which event?

thin stratus
#

The Event in the PlayerState that allows you to move data from old to new one after a SeamlessTravel.

rich dune
#

ah okay

thin stratus
#

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.

rich dune
#

so basically like this

thin stratus
#

Yop

#

Funny note: I exposed those a few years ago.

rich dune
#

Well we more or less never did know or need this because it's a match based FPS and everything resets on map change

thin stratus
#

Sad days where BP peeps couldn't use that

rich dune
#

Thanks, will give it a try tomorrow

thin stratus
#

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?"

rich dune
#

Now I know a bit more what to search. Always tought everything resets and Player Controller 'reconnects'

thin stratus
#

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

grizzled stirrup
thin stratus
#

Of course.

#

ListenServer has Authority, including over its Session.

grizzled stirrup
#

So for a listen server game, having an open quickplay type of situation can easily be exploited, interesting!

thin stratus
#

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.

grizzled stirrup
#

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

thin stratus
#

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.

grizzled stirrup
#

Or I guess having some kind of server browser so you can avoid bad actors

thin stratus
#

Yop

dire burrow
#

but yeh zero games work if it wont do the bone modify replication

#

fix it unreal 😄

quasi tide
#

What are you even going on about

ashen plume
#

quick question, i cant seem to get an up to date controller rotation in cmc to compare against input direction

thin stratus
ashen plume
# thin stratus 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

torpid crest
#

[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

thin stratus
#

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.

torpid crest
#

sooo like this

thin stratus
#

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

torpid crest
#

got it

thin stratus
#

Rest seems fine though, yeah

torpid crest
#

ok 😄 it's build time 😄

agile pendant
#

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 ?

fossil spoke
#

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.

daring tangle
thin stratus
mighty apex
#

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/

nocturne quail
#

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

nocturne quail
#
Epic Developer Community Forums

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...

nocturne quail
#

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

exotic wasp
#

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

nocturne quail
prisma snow
# exotic wasp no real reason to update unless there are features and fixes you want

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

echo pasture
#

I just can't bother with all that stress

sinful tree
#

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.

nova wasp
#

Owner no see in reality means view targets

#

It's a bit misleading

#

Possession generally sets the pawn to be the view target

vapid gazelle
#

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;
blazing bear
#

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.

vapid gazelle
#

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.

nova wasp
#

but yeah overriding the onrep should stop it from applying this

vapid gazelle
meager heart
#

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?

thin stratus
#

This looks like BasedMovement kicking in when you land and correcting the relative location.

meager heart
#

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

trail olive
#

Question about FFastArraySerializer is doing something like this makes using FFastArraySerializer more or less not relevant due to nesting ?

fossil spoke
#

You cant have a FFastArraySerializer struct type within a FFastArraySerializerItem struct type.

#

You cant nest FastArrays.

#

Well, you probably could.,

#

But

#

Like.

#

Why.

trail olive
fossil spoke
#

Your diagram is like super confusing.

#

Better to write it in psuedo code

#

Than how you have done it.

thin stratus
# meager heart Seems like with physics objects the server and client really are having trouble ...

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.

fossil veldt
#

Epic is working on a Chaos-based Mover 2.0 implementation, but I would not touch that for a longer while.

thin stratus
#

Snacks, why would you want to inflict even more pain onto yourself?

fossil veldt
#

I don't dare

#

i just got upset at the mere mention of it]

thin stratus
#

In the end, that isn't actually too surprising. We were pretty much expecting that move.

meager heart
# thin stratus Physics in Multiplayer aren't really easy. You can set it to `bReplicateMovement...

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?

thin stratus
meager heart
#

very interesting, something's probably not replicating properly with that. Thanks for the info!!

meager heart
# thin stratus Physics in Multiplayer aren't really easy. You can set it to `bReplicateMovement...

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?

thin stratus
thin stratus
meager heart
#

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!

thin stratus
#

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.

meager heart
#

Yeah that makes sense, easier to access and intercept that stuff in those functions

torpid crest
#

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.

chrome bay
#

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

torpid crest
#

maybe this is right answer

chrome bay
#

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.

torpid crest
#

I see

chrome bay
#

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.

torpid crest
#

yeah they have ID as integers so basically I can have components ready and just send ID value and each client will handle that

chrome bay
#

yeah, and that's probably the best way IMO

torpid crest
#

cool, cheers

clever spear
#

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.

blazing spruce
#

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

rose egret
#

when is reliable multicast RPC of GameStateBase available for a connection/client ? I supposed after AGameModeBase::PostLogin ? buts seems one frame is droped 🤔

sinful tree
rose egret
#

@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

sinful tree
#

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?

exotic wasp
#

multicast sounds wrong here

#

multicast is usually wrong

#

easy trap

severe widget
#

Do clients require every individual frame of data?

chrome bay
#

No, they don't get it anyway

rose egret
sinful tree
#

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.

waxen socket
#

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.

meager spade
#

OnRep for damage? interesting design

waxen socket
#

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.

exotic wasp
#

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

waxen socket
#

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?

exotic wasp
#

why reliable?

waxen socket
#

Because running into an enemy causes character death and therefore, it has to occur.

exotic wasp
#

handle death on the server

#

you could always just do some sort of form client prediction

waxen socket
#

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.

exotic wasp
#

what kinda ping are you talking?

waxen socket
#

I'm simulating "bad ping" in the editor which is 100 - 200ms.

exotic wasp
#

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

waxen socket
#

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?

exotic wasp
#

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

waxen socket
#

Thank you for the advice. I wonder what ping most devs consider when configuring replication.

sinful tree
#

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.

waxen socket
#

Thanks, Datura. 🙂 I'm not concerned about cheating. Is that why you mention that?

sinful tree
#

yep 🙂

waxen socket
#

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.

sinful tree
#

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.

waxen socket
#

It won't be every frame, but it might be two or three times in a second.

sinful tree
#

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.

waxen socket
#

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.

exotic wasp
#

the issue with having client authority is that anything that involves another player influencing them is going to be utterly broken

sinful tree
#

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.

waxen socket
#

Thanks to both of you for the advice. My game doesn't involve many player-player interactions, mostly player-computer.

sinful tree
#

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.

exotic wasp
#

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

waxen socket
#

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.

potent tundra
#

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?

exotic wasp
#

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

waxen socket
#

Okay, I understand what you're saying. Thanks again.

graceful flame
#

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.

quasi tide
#

Just change it on the client.

graceful flame
#

Its a replicated actor though

quasi tide
#

In the onrep, check on the client what color it should be based on w/e criteria

graceful flame
#

I need to replicate the component because it scales up and down based on certain events, but only the color should be different.

sinful tree
quasi tide
#

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.

graceful flame
#

ahh yes ** GetOwner Cast To PlayerController Is Locally Controlled** was the key part I was forgetting about

#

thanks

quasi tide
#

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

torpid lantern
#

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.

quasi tide
nova wasp
#

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

bright summit
#

can I send pointer to UObject through client rpc?

prisma snow
bright summit
#

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

prisma snow
#

Also probably you want to replicate items, not RPC them

prisma snow
bright summit
bright summit
#

what's your idea for it?

prisma snow
# bright summit 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

bright summit
#

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

prisma snow
#

you can have a base class for inventory items so that all of them have a common interface if needed

bright summit
#

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

magic karma
#

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?

dark edge
#

Show the parent class and the component layout.

magic karma
#

Character is the pawn controlled by the player controller. IIRC it's Actor->Pawn->Character

magic karma
dark edge
#

So it is a Character? That's already replicated with server authoritative movement out of the box. It's correcting you.

prisma snow
#

Yeas you cannot set location for character directly because CMC overrides it (and already handles movement replication)

nocturne quail
#

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
exotic wasp
#

i used it for my inventory and i am happy with it

bright summit
exotic wasp
#

yes

bright summit
#

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

sinful tree
#

Are you trying to RPC the reference immediately after spawning it?

sinful tree
#

That's probably the problem. The RPC may be getting received before the object gets replicated , if that object is replicated properly.

bright summit
#

but as I said - replicating TArray and checking the values in OnRep also gives nullptrs

exotic wasp
#

i remember having this issue. it wasn't related to subobject replication iirc

bright summit
#

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);```
exotic wasp
#

you set bReplicateUsingRegisteredSubObjectList to true in the component right?

magic karma
bright summit
exotic wasp
#

ill advised though

#

client authority is a can of worms

bright summit
# exotic wasp ill advised though

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

magic karma
exotic wasp
#

if you dont want to use the cmc just use pawn and make your own movement component

#

that is non trivial tho

exotic wasp
magic karma
exotic wasp
#

i mean, you can

#

theres nothing stopping you from just rpcing the position to the server and having it accept it

magic karma
#

You're saying these nodes need the character movement component?

exotic wasp
#

no, but they wont do anything unless you make something ingest those inputs

magic karma
#

I'll test it out and see if movement breaks. Thanks for your help

exotic wasp
# bright summit What I did is an actor component which handles registering subobjects for replic...

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);
}
bright summit
#
// 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 🤡
exotic wasp
#

im assuming you probably did something identical for your component

bright summit
#

yeah

#

I don't know what I missed

exotic wasp
#
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

bright summit
#

where are you spawning the instance of inventory item?

exotic wasp
#

is there a reason you are using the ReplicateSubobjects function?

bright summit
exotic wasp
#

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

bright summit
#
// 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

exotic wasp
#
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?

bright summit
#

nope, same

#

:/

grand kestrel
#

@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

gleaming vector
#

lol

thin stratus
#

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

grand kestrel
thin stratus
#

Why?

grand kestrel
#

No idea 😄

#

I might try reducing to 30fps and see what happens, but first I gotta update my sim for regular CMC jumps

thin stratus
#

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

grand kestrel
#

Let me get some more info first

#

Yeah

thin stratus
#

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

grand kestrel
thin stratus
#

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

potent tundra
#

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

meager heart
# thin stratus Eh, smoothing just means that you take the current Transform and the Replicated ...

~~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)

pallid mesa
#

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

potent tundra
pallid mesa
#

whats not working?

potent tundra
#

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

pallid mesa
#

ah wait so you want to apply an impulse on input on authority? or when you walk against the ball?

potent tundra
#

the first yes

pallid mesa
#

you gotta apply the impulse on the server if you dont mind about predicting it

potent tundra
#

needs to be applied on client first so it can be smooth

pallid mesa
#

doesnt need to

potent tundra
#

Ive basically just hijacked the jumping part of your ball character demonstration

pallid mesa
#

applying it on the client first wont make the interpolation more smooth, it will simply be more reactive

potent tundra
#

Yes well thats what i mean

pallid mesa
#

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

potent tundra
#

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

pallid mesa
#

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

potent tundra
#

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?

potent tundra
pallid mesa
#

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

meager heart
# meager heart ~~Do you have any suggestions on which functions to override for this btw? For c...

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

potent tundra
pallid mesa
#

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

potent tundra
#

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

pallid mesa
#

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 ?

grand kestrel
#

@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

potent tundra
#

i tried both resim and predictive interpolation

#

had the same issue

pallid mesa
#

and you have everything on on project settings, no warnings on the output log?

potent tundra
#

not that i remember, i can remake it again

#

to be 100%

#

lemme do that rq

grand kestrel
#

Oh maybe it is actually related to this, because my apex time will differ if gravity gets modified

pallid mesa
#

yes, i think that might be the case

grand kestrel
#

Ya it IS that lol

pallid mesa
#

specially if you are modifying gravity mid time

grand kestrel
#

I disabled the cvar and its 100%

pallid mesa
#

pog

grand kestrel
#

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

potent tundra
pallid mesa
#

in this case? i think it should be on... but im not 100% certain, dont have the engine in front of me

potent tundra
#

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```
pallid mesa
#

so in the actor itself are you setting predictive interpolation on physics replication mode?

mystic estuary
#

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?

potent tundra
#

ts pmo sb atp 🥀

#

Thanks anyways your article was goated

pallid mesa
#

pog! o7 happy deving @potent tundra ! glad you got it figured

pulsar abyss
#

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.

potent tundra
pallid mesa
#

error refers to how much error chaos net chaos allows between contexts

#

so higher means less aggresive

potent tundra
#

hm okay

pallid mesa
potent tundra
#

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

pulsar abyss
pallid mesa
#

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

tulip robin
#

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.

pallid mesa
tulip robin
#

beautiful, thanks

pallid mesa
#

written by Zhi Kang Shao from Epic Games, they are amazing

tulip robin
#

your a lifesaver

pulsar abyss
#

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.

pallid mesa
#

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

pulsar abyss
pallid mesa
#

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.

pulsar abyss
#

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.

pallid mesa
#

yes, if you want to modify engine plugins/engine code, it has to be done that way unfortunately

wanton sleet
#
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 ?

pulsar abyss
nova wasp
#

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

nova wasp
#

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

grand kestrel
nova wasp
#

Component visualizer?

grand kestrel
#

Nope

wanton sleet
twin juniper
#

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.

sinful tree
twin juniper
pallid mesa
potent tundra
#

@pallid mesa yo why cant i set the values for prediction?

#

like make it more/ less aggressive

#

i see no option for it

pallid mesa
#

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

potent tundra
#

only options for default and resimulation

potent tundra
#

okay if you give the item a networkphysicssetting you can edit from there

#

:/

tardy fossil
#

That’s a huge resimulation threshold

rose egret
#

wasn't it possible to run standalone build as dedicated server (with -server commandline) ?
or i need to build for dedicated server ?

prisma snow
supple field
grand kestrel
grand kestrel
#

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)

tardy folio
#

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.

nocturne quail
#

@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

#

i'm afraid applying this change could break the engine

sinful tree
# tardy folio Hello everyone, I’m looking for help solving a frustrating issue I’ve been stuck...

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?

tardy folio
#

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

nocturne quail
sinful tree
tardy folio
# sinful tree How are you setting the value of the nested structure? As an example, here's wha...
  1. First im creating a temp copy of a structure
  2. Values are changed using set member in Struct node
  3. 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)
sinful tree
tardy folio
#

It has 3 vars of type map

sinful tree
thin stratus
#

Either you start both, Server and Client via the Editor (incl Standalone), or you package both.

nocturne quail
thin stratus
nocturne quail
#

yes, and then i added

[ConsoleVariables]
net.IgnoreNetworkChecksumMismatch=1
net.CurrentHandshakeVersion=2
net.MinHandshakeVersion=2

and that error gone, but still disconnecting with errors

thin stratus
#

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.

nocturne quail
#

Mine is linux dedicated server and windows client

thin stratus
#

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.

nocturne quail
#

yeah i am not mixing in 5.4

thin stratus
#

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.

nocturne quail
#

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

thin stratus
#

Then you'll have to debug it more and share some logs.

nocturne quail
#

Ok, I will now reproduce the disconnect and will share the logs

tardy folio
sinful tree
# tardy folio <@218956378654507008> 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.

nocturne quail
#

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);
}
rare wharf
#

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?

pulsar abyss
#

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.

thin stratus
nocturne quail
#

also when i launched a dedicated server from editor as a seperate process, it also works fine

tardy folio
vapid gazelle
#

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?

prisma snow
rare wharf
#

😭

prisma snow
#

Can you share the emulation settings you're using?

rare wharf
#

not sure why but here

#

just testing super worst case scenario

prisma snow
#

You're applying it two times - incoming and outgoing

fossil spoke
#

Dude 20% packet loss is rediculous lol

#

1% is borderline

rare wharf
#

apologies, ill make it 1 then

prisma snow
#

So you're testing between 400 and 800 ping

fossil spoke
#

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.

prisma snow
#

In general anything above 300-500ms ping is not realistic for you to support

fossil spoke
#

Even 300 is a lot

prisma snow
#

Yea

fossil spoke
#

We try and aim for a smooth-ish experience at 250

prisma snow
#

Yeah exactly

fossil spoke
#

Anything above that, youre on your own as a Player

#

Unfortunately there is only so much you can do to combat bad latency.

prisma snow
fossil spoke
#

But even then, unless you literally restrict users to regions, they can always choose to join a server with 400ping

fossil spoke
#

They made that choice, they live with the experience.

prisma snow
#

Ohhh ofc

nocturne quail
exotic wasp
#

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

boreal flicker
#

guys how do i deal with packet loss

exotic wasp
#

get a more stable internet connection

boreal flicker
#

what if the players dont have a stable internet connection

#

it messes everything up

vapid gazelle
#

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.

thin stratus
exotic wasp
#

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

thin stratus
#

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

exotic wasp
#

usually a result of relying on unreliable packets from my experience

boreal flicker
#

i know i cant avoid it but my code is getting messed up when it happens

#

ill just figure it out

exotic wasp
#

use OnReps with properties and other network events that are reliable to access information at the right time

thin stratus
exotic wasp
#

^

#

its hard

thin stratus
#

You'd be better off explaining what the mess is about. Otherwise you are trying to solve the wrong thing.

boreal flicker
#

i need to do more testing

karmic briar
#

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?

torpid crest
#

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?

Fab.com

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

lost inlet
#

I'm not sure how "16 bit integer for blueprints" doesn't work for blueprints

torpid crest
#

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

chrome bay
#

Seems outrageously unnecessary tbh

lost inlet
#

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?

torpid crest
#

Yeah you are right

#

Not worth the hussle

#

There are better things to tackle

prisma snow
lost inlet
chrome bay
#

You can tell from the screenshots that all they did is wrap int16 in a USTRUCT wrapper and expose a library for it

prisma snow
chrome bay
#

A lot of fluff really

lost inlet
#

If bandwidth is a concern, I would also be curious about Oodle

#

Unless that's default now? (no idea)

prisma snow
#

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

torpid crest
#

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?

chrome bay
#

Wow they actually are planning it party_manny

exotic wasp
prisma snow
thin stratus
boreal scarab
#

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?

chrome bay
#

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

boreal scarab
#

heh yeah, definitely not doing that on purpose, its just what happens when I press build

chrome bay
#

45 mins :/

#

How many build products does it kick off? like 100's/1000's?

boreal scarab
#

its currently compiling 3133 files. Its doing a full rebuild, I dunno why. I feel like switching configurations should not cause that

sage lance
#

sounds like your building source

chrome bay
#

Yeah it def shouldn't be doing that, even if building from source

boreal scarab
#

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

exotic wasp
#

maybe antivirus being a bitch?

boreal scarab
#

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

twin vessel
#

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?

exotic wasp
grand kestrel
boreal scarab
prisma snow
bronze glade
#

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

fossil spoke
#

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.

opal pulsar
#

fornite is a shooter with hundred players and that uses iris i think

bronze glade
# fossil spoke As with most questions like this, the answer is "it depends".

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

bronze glade
#

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

opal pulsar
#

i think iris offers better control over updates and dirtying things. i dont know how much more bandwidth it uses tho sorry

bronze glade
#

No worries, appreciate the input 🙂

sinful tree
# bronze glade I am very aware that we have lots to learn 😅 I was actually trying to ask for w...

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.

thin stratus
grand kestrel
#

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

dire burrow
#

lol

#

y stop at int16

#

let them have full spectrum of unsigned integers which go even lower

wary sand
#

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 :'((((
chrome bay
#

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

wary sand
#

Ok thank you

chrome bay
#

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

wary sand
chrome bay
#

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.

twin vessel
chrome bay
#

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

wary sand
# chrome bay You can do a better version of what GAS does with FInstancedStruct - but I'm con...

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;
    } ```
twin vessel
chrome bay
#
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

twin vessel
#

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?

wary sand
#

Love it, works great thanks, bye 🙂

hollow estuary
#

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!

chrome bay
#

I mean there's an FPS template, multiple in fact

tardy fossil
#

id say the biggest variable is how much you need to learn in the process.. that can slow things down

hollow estuary
soft gulch
#

the FPS templates are a good starting point, but last i checked there is no specific multiplayer logic in there other than the cmc ?

lost inlet
#

there isn't much logic in there in general. it's just the bare minimum to get started

chrome bay
#

There's also ShooterGame and Lyra, both pretty servicable

#

It's an impossible question to answer tbh

soft gulch
#

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...

wary sand
kindred widget
hollow estuary
hollow estuary
kindred widget
# hollow estuary How long do you reckon it'd take y'all to create a bog-standard multiplayer FPS?...

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.

exotic wasp
#

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

idle jay
#

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

hollow estuary
hollow estuary
idle jay
#

if i use the default built-in one it works perfectly

kindred widget
ashen plume
hollow estuary
ashen plume
sinful tree
#

bog standard multiplayer FPS can be done in an hour if all you're expecting is to shoot and kill other players.

ashen plume
#

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

sinful tree
#

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:

  1. Supporting sessions whether through dedicated servers or listen servers. (Players can host, find and join games)
  2. Being able to shoot a gun and kill players. (Allowing some kind of gameplay that fits the FPS genre)
  3. 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.

hollow estuary
hollow estuary
ashen plume
sinful tree
#

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.

hollow estuary
hollow estuary
sinful tree
#

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.

hollow estuary
ashen plume
hollow estuary
sinful tree
#

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

hollow estuary
lost inlet
#

you can do CSHD + verification, but your verification has to be fairly watertight

ashen plume
hollow estuary
hollow estuary
ashen plume
lost inlet
#

well you need to nail rewinding too for the serverside approach as well

#

because bad user experience for all is worse than some cheaters

hollow estuary
lost inlet
#

you can't rely solely on clientside anti-cheat

ashen plume
#

in any other non-competitive circumstance, such as for pve, like in a co-op shooter, i personally recommend forgoing validation

hollow estuary
ashen plume
#

your standard borderlands player isnt really going to care that billy modded an insta kill weapon

hollow estuary
lost inlet
#

on a previous project, we completely disabled hit verification in co-op and it was never really a problem

ashen plume
lost inlet
#

cheaters tend to prefer making real players angry, not bots

hollow estuary
hollow estuary
hollow estuary
lost inlet
#

well it was Insurgency: Sandstorm but the studio is dead and its corpse is just being animated by Saber Interactive

exotic wasp
#

fun game

vapid gazelle
#

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.

sinful tree
vapid gazelle
sinful tree
#

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.

hollow estuary
chrome bay
hollow estuary
hollow estuary
mystic estuary
#

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?

lost inlet
#

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

nocturne quail
#

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);
    }
}
chrome bay
#

well, steam display names aren't unique, so I doubt it

nocturne quail
#

not using steam

chrome bay
#

Also what's to stop the second instance just changing the players display name

nocturne quail
lost inlet
#

and if I change it before I connect?

chrome bay
#

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

nocturne quail
#

getplayername is returning the device id

lost inlet
#

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

nocturne quail
lost inlet
#

auth is something like Steam provides and a unique net ID (Steam ID) is about as perfect as an identifier you can get

nocturne quail
#

i'm using custom null subsystem

lost inlet
#

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

nocturne quail
lost inlet
#

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

nocturne quail
#

so i have no plan anymore to depend on external services

#

also what is that: FString DeviceName = FPlatformProcess::ComputerName();

lost inlet
#

I thought you just paid the fee?

chrome bay
#

you do lol

lost inlet
#

computer names are not that unique either and the user can change it at any time

nocturne quail
nocturne quail
#

if they do, their old session will be terminated

#

right?

chrome bay
#

but what makes you think device IDs are unique anyway

lost inlet
#

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

nocturne quail
lost inlet
#

that thing you can famously change in the installer right

nocturne quail
lost inlet
#

I have an old NUC that is just named "MiniPC", that's not even close to unique

nocturne quail
#

if we right click on the computer icon and press properties, it shows a long device id

lost inlet
#

yes, the thing you can change if you want

nocturne quail
#

i think this should be unique for all pcs?

nocturne quail
#

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

chrome bay
#

end my suffering

tardy fossil
#

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)

nocturne quail
#

this is the right method to get player ip

    UNetConnection* PlayerNetConnection = NewPlayer->GetNetConnection();
    if (!PlayerNetConnection) return;
    FString PlayerIP = PlayerNetConnection->LowLevelGetRemoteAddress(0);
kindred widget
#

Which you should never need.

nocturne quail
kindred widget
#

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?

nocturne quail
#

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

hollow estuary
exotic wasp
#

the only way you are going to reliably identity someone would be through some central server or a blockchain

exotic wasp
#

you're trusting the client for this information

nocturne quail
#

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

exotic wasp
#

they can just hack and change it

#

this is a silly problem to solve with silly answers

nocturne quail
#

its their issue, if they change it they will be disconnected from server

quasi tide
exotic wasp
#

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

nocturne quail
#

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 😄

regal hazel
#

It’s practically what it’s for (uniquely identifying)

kindred widget
#

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.

chrome bay
#

yeah I'm still confused by that part

prisma snow
#

the mistake is trying to comprehend

thin stratus
prisma snow
#

if only authenticating users was an industry-wide practise with several solutions available

nocturne quail
regal hazel
nocturne quail
#

Thanks for this, I will give it a try ofc

sinful tree
lost inlet
#

if only Steam was being used to authenticate players

regal hazel
#

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

lost inlet
#

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

regal hazel
thin stratus
#

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.

nocturne quail
#

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)

exotic wasp
#

most likely

nocturne quail
exotic wasp
#

do you not have a debugger attached that breaks on the bad read?

nocturne quail
#

locally it never crashed 😄

#

I think i have to build in debug game editor to get more logs

nocturne quail
#

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);
        }
    }
}
thin stratus
#

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 :<

sinful tree
# regal hazel > then you could also end up blocking players who may be on the same network but...

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.

nocturne quail
#

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

nocturne quail
nocturne quail
#

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

sinful tree
#

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.

nocturne quail
#

and the verification will use combination of mac:ip

sinful tree
#

So what if my ISP uses dynamic IP addresses?

#

Or I happen to go to a friends house to play?

dark edge
#

shit outta luck I guess

sinful tree
#

What if I buy a new computer? o_O

#

Or I have to get a new router?

#

or whatever network device?

nocturne quail
#

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

dark edge
#

or tethered through an iphone which changes mac every session

nocturne quail
#

and registerd the mac against the whole range

nocturne quail
dark edge
nocturne quail
sinful tree
dark edge
#

all zero players will love doing that

nocturne quail
dark edge
#

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?

nocturne quail
#

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

dark edge
#

Why doesn't Valve or Riot do this you think?

sinful tree
#

Oops, changed my VPN... Oh crap, I can't play any more.

dark edge
#

whoops I moved house, there goes the game library

nocturne quail
dark edge
#

No, it doesn't work, that's why.

nocturne quail
#

it does, i am testing it all day

dark edge
#

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

nocturne quail
dark edge
#

whenever you move

#

whenever your ISP wants to

sinful tree
dark edge
#

whenever you connect to a different wifi on your laptop

nocturne quail
#

this is the same network

dark edge
#

that's LAN lol

nocturne quail
#

just example

#

you can check your ip range online

#

if its not static

sinful tree
#

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.

dark edge
#

ok so what if I move

#

can't play game

#

what if I want to play it on vacation? banned

#

switch ISPs? banned

nocturne quail
dark edge
#

lol nobody will jump through those hoops

nocturne quail
#

if they want gameplay without cheaters, they will do it

#

the idea is your account name and password is your ip and mac :d

dark edge
#

that's a horrible idea

#

why isn't your account name, idk, your actual account that you bought the game under?

nocturne quail
#

that works, i tested it today with friends

dark edge
#

test it next year with strangers who paid for the product

#

If this game isn't free you will have approximately zero playerbase

nocturne quail
#

they should be agree with agreement before they buy the product

dark edge
#

if it is free, then you'll just get new accounts popping up like crazy

#

either way you're back to square one

nocturne quail
dark edge
#

ok so no players

#

best of luck

nocturne quail
#

registration will never be automated

#

all manual by me 😄

#

per day only 50 accounts registration

dark edge
#

You won't hit that limit for a while, should be safe

nocturne quail
#

today 16 registered 😄