#multiplayer
1 messages · Page 264 of 1
You would modify the game modes spawning players or even simpler, just spawn as spectators with no input and then wait for an event (Press A to start) which then would make the players on the server possess a different actual gameplay character, done - just saved you some money
it will not on machine that doesn't get to execute the RPC.
e.g late joiners or if the actor is outside relevancy.
Yop, RPC are not meant to synchronize stuff
Currently already doing something like this. players are meant to be spawned with proxy input receivers and when the "Jump" button is pressed, spawn the player at X Co-ord based on spawn spots
So what's the issue then?
the issue still exists in my game...resume game not really doing what it's expected to do and the background goes all black even though i have only set a background blur for the game menu widget. i'm also facing trouble when trying to host a session after going back to the main menu, i can only seem to host the game from the host of the previous game and others cant host, and also cant join the session that the host created after. i've also shared the output log in this video as well
The issue is with animation montages, cause if i add the notify directly to the animation it works fine and executes once, adding the notify to the montage executes twice but the montage plays once.
Animation calls notify once, ✅
Montage calls notify twice . Engine Bug
in the original 4.26 project everything is working fine.
Recreating the montages fixed the issue in 5.4,
seems like upgrading from 4->5 , screwed the animation montages which calls the notify twice
i've set the input action event for the game menu in my player controller as well
spawned by server?
Does FFastArraySerializer have a limit on the size/amount of elements it can replicate?
Could be that they changed something and the update path didn't properly clean up the old way or so
It's not so easy to keep software updated across a lot of updates. Especially if it's projects created by such
I would say no. But you might get into a problem with large arrays on initial replication
Actors that are placed into the scene won't despawn.
You can't compare that to runtime spawned ones.
You can try setting the NetLoadOnClient or whatever it's called setting on the placed ones to the opposite of whatever it is currently
Ig I'm gonna have to figure out on my own
Yea that was exactly what i was thinking about, the delta rep is nice but its useless for a join in progress case for example. Does FFastArraySerializer handle that the same as a TArray or can it for example split the data to send over multiple frames i don't mind when the data gets to the client as long as all of it does.
That idk
alg thanks though
I know you will hit package size limits which will potentially make the whole replication more CPU heavy but that's only once initially I guess
I just need help with this one final thing and my project is done
💯
The Session stuff is usually because you didn't Destroy the Session of Host and Clients when they enter the MainMenu.
It's a good idea to simply put that into your MainMenu GameMode's BeginPlay, so you always destroy a Session, even if none is there.
You can also do a fail-safe and call DestroySession before trying to host/join.
If your Clients have trouble joining afterwards, then I assume you might not be cleaning up their Session after the Host left.
@cosmic trench Also your video seems to suggest you aren't using SeamlessTravel for your ServerTravel that goes from Lobby to Gameplay map.
You don't want to perform a HardTravel for that. Clients will disconnect and reconnect, which is not very smooth, and requires the whole "login" process to run twice.
On top of that, Subsystems like Steam will not work with that.
You need to mark the Lobby and Gameplay GameModes as SeamlessTravel in their Class Defaults.
But a few words of advice for after you've changed that:
- By default you can't test this in the Editor. The Server will simply not travel.
- You can enable that with a console variable but it's experimental and might cause a crash.
- If the CVar doesn't work for you, you will need to start the game as actual Standalone and/or package it. Standalone is faster (easiest way to do that is to rightclick the .uproject file and click on "Launch Game". I assume the Standalone option when pressing play (not the Play as Standalone, but the one that is in the list of "New Editor Window", "Play in Viewport" etc.).
- Since SeamlessTravel keeps the Clients connected (and parked on the Transition Map you can select in the Maps&Modes in your Project Settings), some of the code-paths you usually expect to call for connecting clients won't call.
- E.g. if you do something on "PostLogin" in the GameMode, then you need to move that to the GenericInitializeNewPlayer or so override instead, that calls for both connecting and seamless traveling.
What's the InputAction set to in terms of Triggers? The background going darker and darker looks like you are adding the menu over and over again, that's why clicking on resume doesn't do anything as you only removed one of all those widgets.
Make sure the Triggered doesn't call more than once (use a "PRESSED" Trigger for that), and maybe also ensure that the Widget won't get created if the PauseMenuRef is already valid.
It seems to be working properly now after adding the destroy session before hosting or joining a session and also added the destroy session on BeginPlay inside the main menu GameMode
I have set the pause menu now to show up only when the PauseMenuRef is not valid and now the darkness in the background is gone and i'm able to click the buttons (both resume and leave buttons) but once i press resume, i cant call the pause menu again when i try to trigger the pause menu input action again
I haven't set any triggers for that input action
Are you setting the PauseMenuRef back to null?
Then it's probably the HOLD Trigger by default. Try adding the Pressed one, that should ensure it's only triggering on press and not on hold.
That's what I'm trying to do but can't quite figure out how
You just set variable without connecting something to it.
once i do that, the darkness comes back again in the background
this actually fixed the issue, thanks!
Yeah I guess the InputAction is constantly triggering.
Probably cause the Key isn't counted as released when you switch InputMode
Might want to check if there is a "Flush Keys" or so function in the PlayerController in Blueprints.
now the only problem is, once i leave the session and start another session, i cant seem to control any of the players again
Or Flush pressed keys or so
That might go hand in hand with the fact that your InputAction keeps triggering. Are you properly changing the InputMode in those various situations?
i change the input mode to ui only when the pause menu is triggered and back to game only when i press resume
Is the InputMode initially UI in the MainMenu?
Are you ever setting it to Game when you enter the Lobby/Gameplay maps?
You are probably setting it to UI in the PauseMenu, then leave the Session and join a new one, but you never undo that and are stuck in UI InputMode.
fyi, the whole InputMode stuff is best to be handled a bit differently, or maybe even directly via the CommonUI plugin.
I usually have a base-class for my PlayerController and I figure out on Tick if Menus or Dialogs are open and then change the InputMode.
That's not super clean, but it ensures that the InputMode is handled in one single place. Requirement for that is that you handle your Menus and Dialogs that needs UI interactions in your PlayerController and keep references there. As well as a proper inheritance setup so that PauseMenu and MainMenu both count as "Menus".
CommonUI makes it a bit easier I guess, there you'd use an ActivatableWidget as the base for your MainWidgets. So e.g. for MainMenu, PauseMenu and HUD.
And that class gives you the option to return a preferred input mode, so whenever such a widget become "active" it automatically changes the mode back and forth, like a stack.
Makes things a bit simpler.
But for now you should just set the InputMode in your cases to UI and Game at the right times.
I wasn't doing that and then tried doing it in the lobby gamemode and it only worked for the host and not the clients, the clients still remained at the ui only input mode
GameMode is also not the right choice here, cause that only exists on the Server.
MainMenu GM would be fine, cause there is no Server/Client setup there.
But for the multiplayer maps you will need to use the PlayerController -> BeginPlay -> IsLocalPlayerController -> SetInputMode.
Okay it works properly now, thank you so much!
No worries (:
No but it makes the difference to the ones placed in the scene
Those ones don't despawn if they are loaded during map load
Which is probably what you notice with the runtime spawned one happening
Need someone big brain to give me advice, my multiplayer respawn system - when the 2nd player respawns, the 1st can no longer move.
Share code of your respawn system
Probably using GetPlayerController0 or stuff like that
Hmm. I just enable server streaming to true and enableserver streaming out to true... and in editor it's teleporting the second player to a different map.
Any suggestions?
in my player character -
calls this - also in my player char - (called on server reliable)
into my controller run on server
then to my game mode
I've tested and even though player 1 cant move - the movement mode is still set walking, the input returns a 1 when pressed - the player can, jump roll attack, just not walk or run / move
I'm close to giving up at this point 😂
The delayed posses is a bit strange
Also most of what you are doing seems so standard that you could just use the built in functions for it
Let the GameMode spawn the default pawn. Let the GameMode find/choose the PlayerState and simply call RestartPlayer after destroying the old pawn.
But that aside I don't see why you wouldn't be able to control the pawn anymore.
The second RPC isn't needed unless you want to call that by the client without death.
Actually both RPCs aren't needed
Your character shouldn't die on the client.
Damage and death should be done on the server already. Only the initial input that kicked off the chain of events that leads to the death should be a server RPC
And I would remove the delay
Actually this is your problem
In theory at least
You do the whole spawn stuff and then call unposses
Order of events is all mixed up.
- Unpossess old Pawn (keep a local ref)
- Destroy old Pawn (via local ref)
- Spawn new Pawn
- Posses new Pawn (without delay)
right, so I just switched around the unposses and spawn
and now the 2nd player looses movement when the 1st respawns
without dying at all
That's not right though
The unpossess should be in the respawn function
And it should be done after keeping a reference to the pawn so you can call destroy on it
Otherwise the returned controlled pawn is null
Do you have auto posses on in the character's class default?
This is in theory really straight forward
You cant call unposses from a game mode?
Why does that matter?
so how can I put it in the respawn function?
RespawnPawn is in the Controller?
The way you have it set up atm would mean calling RespawnPawn without Death won't unposses the pawn
Not the end of the world but still strange
No, I don't
have moved the unposses to the controller but still when p1 respanws p2 is still alive but cannot move
Hm, not sure atm. Something obvious most be wrong. Where is that first screenshot from? Why is Death a ServerRPC?
my clients were not taking any damage
so i made this server damage function
and at the end of it, if 0 health remains, it calls death
so they die...
Appreciate your help, will take another look at some docs and have another run at it.
I feel like your setup is a bit wrong. You should not need a ServerRPC for death. Quite the opposite.
That means your damage is already dealt on clients.
You know what RPCs do?
Basically, RPCs call on another instance of the game. Usually on a different Computer, but can also be the same Computer.
The Jump_RPC calls on the Server's instance of the game. It gets the MontageToPlay passed.
Then it calls JumpReplicate, which calls on the Server and all Clients. Server will be fine with the MontageToPlay being passed into the PlayMontage node like this, cause the Montage still sits in its memory.
But the Clients have no idea about the MontageToPlay. It's a different instance/process of the game, maybe even a different Computer. You need to pass it along the RPC.
Sadly Blueprints allow you to connect stuff across the EventGraph like this. In C++ this would be a lot clearer.
void AYourBlueprintActor::Jump_RPC(UAnimMontage* MontageToPlay)
{
JumpReplicate(nullptr)
}
void AYourBlueprintActor::JumpReplicate(UAnimMontage* NewParam)
{
PlayMontage(Mesh, ???, ...);
}
This is what you have in the lower screenshot. As you can see, the bottom function has no MontageToPlay available to it. It can only use the member properties and the inputs.
And this is the first screenshot:
void AYourBlueprintActor::Jump_RPC(UAnimMontage* MontageToPlay)
{
JumpReplicate(MontageToPlay)
}
void AYourBlueprintActor::JumpReplicate(UAnimMontage* NewParam)
{
PlayMontage(Mesh, NewParam, ...);
}
Hopefully that makes somewhat sense.
Yeah I think I get it. MontageToPlay is passed along to JumpRPC via the event input. Then it calls the multicast on all the clients, which is happening on a separate instance, so even if MontageToPlay is connected it isnt actually passed along.
Yop
You should generally not connect inputs of something that isn't part of the same top most exec line
That includes delays for example. You can't be sure the inputs are still valid
Am I doing things right when I plug variables into the the event input then? Whats the best approach to figuring out what to do on server and what to do on client (focused on performance and not cheat prevention). Right now my logic is to do as much as possible on the client, and to only pass along the final variable and trigger the event on server. So for example, figure out which jump AnimMontage needs to be played on cleint side, and only give the server the MontageToPlay and trigger the montage. The logic being to send/replicate as few variables as possible to the server, and to do as little work on the server as possible so theres less lag between client and server.
does that make sense?
If you are on the same machine you need to either pass along as inputs, or if it's something latent (something that doesn't call the same frame) you probably need to save it to a variable.
And if you send something to another machine you need to use the inputs.
Depends on your Game. Even with 50-100 players, the server can do quite a lot. If you only aim for a handful of players then I would suggest just sticking to doing most stuff on the server
So I should pretty much just take the action inputs and send those to the server?
In theory that's what most peeps do. Minus some prediction. But even that results in the "inputs" being sent to the server
If you fire a gun, send an RPC and do the tracing on the server, the damage on the server, the kill on the server and the respawn on the server. You can send RPCs back for one time events that aren't important, like hit events, VFX, etc. and you can set replicated variables (optionally OnRep if you need something to react to the value changing) for any state stuff.
After that you can think about prediction, but prediction has its limits and is pretty difficult.
E.g. even if you predict the weapon shot, you can't be sure the server sees the same enemies and the same location.
Which means you need to add a history and rollback to the server so it can figure out what the client saw to give more accurate hit validation. And you need to handle the rollback of false predicted shots. And ultimately you still only deal damage on the server. Cause predicting damage ends really quickly when you notice you'd need to predict death and also allow rollback of a falsely predicted death etc
So doing most stuff on the server is better. If you don't care about cheating then you can simply some things for the sake of better feeling for the client.
Such as doing the trace locally and sending the result to the server.
But that's not due to performance but just so the client feels better about shooting others
While others potentially feel worse about being shot
I'm doing something coop only, so I'd prefer stuff like damage to be applied based on what the client sees and not the server
what I'm not sure about is movement. I figured doing most of it client side would feel better, but I'm not so sure now. Movement is replicated out of the box as far as I know and I dont think theres any way to "bias" it towards the client? I think player position is corrected according to the player pawn position on the server by the character movement component.
pretty sure theres a ticky box to make it client authoritative
ACharacter does predictive movement so it feels like its client authoritative but the server verifies what is happening
if you're using a pawn you have to completely brew your own movement code anyway
this one?
Hey people, its been a while,
im trying to decouple my UI functionality from the inventory component by using event dispatchers.
are there any limitations on using dispatchers in MP?
thats rally helpful, thanks!
it's just a way to call functions in an event based way... it doesn't have much to do with multiplayer
you are on the right tracking making them a bit more decoupled though if that helps
the UI should represent information, it's not what sends it or defines what it is in most cases
The only thing EventDispatchers do is to create a newsletter like subscription setup, where things that are interested in the event bind to it, as opposed to the thing notifying everything, which also doesn't scale well.
They aren't a multiplayer concept.
thats what i assumed.
Yet, im running into a issue when trying to fire a UI function, which is running only on the server
well what fires it?
of course you still need to replicate information and run stuff on the client for a UI
What is the correct way to introduce a cooldown or delay to stop the player being able to spam inputs? Do I need a server-side timer or is there a simpler way to do it?
I would say just have it on both sides but have the server one use some forgiveness (because rpcs from the client could be fairly random in timing)
for example you could send the desire to do the input (bwantstojump or something) and wait to apply it until the timer elapses
Inventory - Add Item
old iteration im using interfaces to notify the UI to add items, update and so on
As of now its a function, but its called from a multicast event on the item
"called from a multicast"
I think you misunderstand what I meant
I am asking why the code runs on the server because something ON THE SERVER ran it
does the client not have some kind of representation of the item on it?
the common inventory setup is generally to use a fast array in c++ but in bp I suppose you are a bit more limited to just regular onreps for properties
not me getting confused by my own code
this stuff is difficult to get into but you kind of need to know on which machine stuff happens on
right
so i might have a problem with triggering the Inventory - Add Item, because sometimes it runs only on the server, sometimes multicast (using the same action)
ill have to investigate
also
inventory managed by an rpc seems very difficult to reason about
it should be sent as a replicated property or object
rpcs can represent requests from the client to do stuff of course (you kind of have to)
but from the server their state should be persistent and not rely on rpcs showing up
Anyone know why faking lag in editor settings doesn't work 5.6? Using listen subsession
show your advanced play settings and the in-game stat net
which settings should be used here?
to test derived attributes in GAS i have to sometimes run it under separate processes
seems like sometimes it would affect how events are firing
Also another issue I'm having when playing on laptop vs computer one player has faster physics than the other, I tried substepping and async and multiply axis input by get world delta time but nothing worked
what does "multiply axis input" have to do with physics?
it depends on what you are doing... generally it is faster to run in the same process as they can share the engine and assets
but testing that way is not as realistic as a distinct process
there is not one holy setup that you will always use... it depends on what you are testing and why
It's what Google said to do and ChatGPT
all physics is handled server side and inputs are sent through to server
I am asking what you are actually doing, I don't care what chatgpt says
why you did it isn't really concerning to me... I am trying to determine why your frametimes are changing the outcome
might be easier to use a select by bool pin for the float
with this does it send every frame you hold the input?
two things...
I would first suggest marging this input into 1 rpc
making these separate does not make sense
unless they don't ever happen at the same time
it's for this type of game
also you should embed wether or not the attach button is held into the rpc too I think
making it a replicated property is going to make it random whether or not it's true or false effectively
unless that's the idea, I don't know
also one thing that might help would be making thiis only apply once per frame
instead of multiple rpcs arriving in one bunch applying twice
you can accumulate or only accept one
as for the physics on the server just test it with different fps t.maxfps 30 and whatnot
you don't need a new computer test tickrate
you can even set each client to use a different tickrate in network emulation settings (this just makes them tick less than every time based on how much time has passed)
thanks for the info, seems like it's not an fps issue, but the amount of packets being sent like you said, I will see how to limit that somehow
spamming rpcs for input is fine but it doens't make sense to send anything when the input axis is 0 (unless it being set back is meaningful)
I think I will need these as seperate as they might be on keyboard and only be moving on X or Y
why does that force you to make two rpcs?
you can just make one that uses both inputs and sends 2 floats
that sends the rpc twice
you want to send it once when the value changes to be meaningful
it might be easier to just check on the player tick honestly
unless you can bind to either value changing in a way that always uses the second one last
just get the input axis on tick and send if either one isn't 0 imo
Can replication be turned on at runtime on a actor. A actor that was loaded from the map package not spawned at runtime. I've tryed AActor::SetReplicates but that doesn't seam to work i have a weird type of replication scenario anyway.
Dormancy might be what you want here
Im not sure about that heres my scenario I have a component that can be placed on a actor that the user has no control over the replication for example take the pcg actor that holds all the ISM components created from your PCG graph you can't set that actor to replicated via the unreal ed ui is there a way in my component to force whatever the owning actor is to replicate as my component needs replication
like this ?
Ok, just read the documentation on the RPC and what not, I had a-lot of variables set to replicate instead of repnotify. I changed that so there should be like 1000s of less traffic now
Hmm, client on my laptop moves even slower now
.1 is not a good value here to compare I think unless you want to ignore lower values
controller input could easily send a 10% alpha
mine is 5% I think
repnotify just adds that they will trigger a notify function
it does not really change how they replicate, just makes the client able to react to changes from each incoming read packet
Also the Tick thing didn't work but using Async Physics tick does kinda work. only thing the physics body that follows the physics object gets dragged behind lol
running it in Async Physics tick is a good idea, because that way it runs at the same consistent rate
can just read the incoming input there on the server and it should be more consistent
It's definately more reliable
Both my laptop and computer run (almost) the same speed regardless of framerate
Only thing now is trying to fix my skeletal mesh that makes the jiggle's root bone contrain properly
I have it on kinematic and constrain and all that but nope
even tried ooveriding async but that messes everything up
Out of curiosity, what happens if a player is mid-connection while the server starts a seamless travel to a new map
You mean they start loading the previous level then the server moves to another level before they finish loading?
Yeah pretty much
They will finish loading the first level and then should immediately start loading the new one
The Client sends an RPC to the Server after they load a level, just to confirm to the server that they made it.
Good to know, thank you
is it not possible to have different clients on different levels? i was hoping to create "worlds" on different levels like minecraft dimensions, but every time i try to travel to a different map all the clients go together
Not with a vanilla engine, would probably require some heavy modifications
uh thats looks like a big limitation
how does fortnite handle different matches on the same level? is it a different concept?
Unreal only supports 1 world out of the box.
i mean you have different matches on the same map, so you have different instances
Those are different matches entirely?
what does "different matches on the same level" mean in fortnite?
I think they run multiple servers on a single machine by having 1 per thread but that's multiple distinct programs afaik
idk i never played it, im trying to find a relatable unreal example
so i suppose the matches are entirely separated sessions
They definitely are
the simple solution is to just have the other match occur far away from the regular area in a distinct space
Thats highly likely, thats how we manage instances for our dedi servers
that makes sense, i was thinking it would be more like a dedicated mmo server where you can have players on different maps but on the same "channel"
plenty of games with "parallel worlds" where you just move 1km to a different area
I would say unless you really benefit from the isolated world it would be easier to just have them far away from one another
I don't know if there's a simple way to have a encapsulated networked world
spawning a new world is not that hard
but making it networked I have no idea
yeah that seems to be the way, i was wondering if i was missing something obvious to have multiple worlds
that's fair
thanks 
There is a concept of having multiple words. People have also managed to get this going without Engine Modifications. Those worlds will not really be able to communicate with each other though, at least not out of the box.
There are two to three concepts floating around:
- Client with a local world that is cut off the networked world an is thus only available to them.
- Client with a local world that connects to a different Server for a more seamless travel between servers.
- Server with multiple worlds, where clients can connect to individually.
In theory, they are all relatively straight forward, as they follow the design that the Editor already follows, which is to simply spawn a second UWorld, like the Editor does when you start playing in it.
Those UWorlds are ticked in sequence though. You can probably communicate between them, as you can simply grab both, but there are obvious limits, as both have their own NetDriver, PhysicsWorld, etc.
And then there is the more obvious limitation of performance. One world is often already pretty hard to keep running smoothly. I assume Fortnite runs one match per DedicatedServer, and then potentially a few of them per cloud server instance. Exact numbers, no clue.
There is also a plugin you might come across that talks about multi worlds, but iirc it's currently limited to concept 1.
I think concept 2. is what you can find out about a bit in this video: https://www.youtube.com/watch?v=2DGB8PLnQgk
Speaker: Md Asif
Summary: Unreal Engine can be modified to have clients that are connected to multiple dedicated servers. This enables MMO type games where the client can instantly travel from one server to the next because multiple server connections are active at the same time. The servers become stitched/meshed on the client and send informa...
Epic is also working on a "MultiServerReplication" plugin iirc. But not sure what the features of that are and how far it is.
Did you try and check the NetRelevantFor logic in C++ to see why it even says it's not relevant anymore?
Your actor does not have root component so that net relevant will false.
there's a few plugins that I literally learned about today that allow multiple simultaneous UWorlds
For standalone, owner is the same as player controller 0 right?
and it is different with dedicated server?
Standalone - it is fine to rely on PC 0 for those things. Unless you're dealing with splitscreen
For dedicated, just don't
ye, I just got spagetti and want to do simple switch between has UI or does not have UI
Hmmm is there a way to extend the connection flow to a dedicated server without engine modifications?
Think having the flow not be complete until additional data is received from the server
Trying to implement downloading Lua scripts from a dedicated server while connecting
I could do it post connection and just have an additional loading screen, probably the way to go with Unreal, but was curious about alternatives
thank you for the video, it changed my mind on some concepts
i was initially thinking about your point 3, where i would have a single server process with multiple worlds, but i dont really need that
Hm, you could communicate that initially via Beacons.
having a proccess for each world sounds way more managable and actually easier to integrate
That was my (original) plan, but I kinda want to have hot reload of lua scripts at runtime, or after a seamless travel
Which would bypass beacons
Yeah, I mean it's more or less the standard way tbh. Unless I'm misunderstanding what your idea now is.
Well, you can have both?
This was about the initial connection and the initial load after all.
Yeah that flew above my head, it would need to be after a seamless travel too
The alternative is: does the engine have a way to pretty much delay replicating anything to a player until I say they're fully connected and ready?
i.e. no other players, no gamemode, no gamestate etc
Without manually making them irrelevant to the player
Iirc Login has a Callback by now.
Don't know what you can all do during that time though.
yeah now that i stop to think about it you are right. i did some research early today and this is exactly what dont starve does for the caves
i think the concept of multi proccesses didnt sound good for me initially because i have only been testing the game on PIE with a listen server so i am not sure how that would work in practice
hmmm
With a ListenServer you are probably stuck moving everyone at once.
The whole idea of multiple worlds and what not is usually a DedicatedServer topic.
What about Iris, does it have anything that would make it trivial to "skip" players? Kinda like not adding a player to any node on the replication graph
Idk if you ever played Borderlands, especially the older parts.
They all ran on UE versions iirc, and you could only travel together.
Potentially, but that could turn into a strange micromanagement
You are better off just creating a custom Socket connection at that point.
Would have to be over Steam Relay so that'd be a pain to implement
I already have to implement support for SDR over online beacons relatively soon
Never went beyond the options I listed. You could check what beacons actually do to allow a connection.
my objective is to allow the player to host servers from the game, it should be as simple as "Menu > Multiplayer > Host" and then someone else can join. this might be a silly question but is this stricitly done with a ListenServer, or is it possible to spawn the extra servers for the other worlds?
I mean, in theory you do that via a ListenServer. So I player that is acting as the host.
usually any server packaged with a game is going to be a listen server
entire extra servers probably goes beyond that
You can start a process with a Dedicated Server too, but it's not that typical to do.
Issue 2 with Beacons was that now I have to implement it over beacons & in-game if I do hot reloading support, or seamless travel lua reloading, would have to open a beacon again
IMO this is best
Majority of the stuff can live in some shared classes though or not?
The old Unreal Tournament Repo has that.
Maybe yeah
They start a DediServer if you want to play.
it really sounds like you just need to have several levels as opposed to entire servers
Come to think of it I also have to implement networking of the map layout since it can be procedurally generated as well as custom made in a level editor
So that'd also be a step to connecting, so beacons are probably not a good idea for this since the map can change every round (map change)
server can load any number and tell the client what to load
agh
listen server will crumble doing that though
The absolute majority of UE devs/games does one of 3 things:
- ListenServer, where a Client is the Host.
- Mostly used for Coop games.
- DedicatedServer, hosted away from Players.
- Mostly used for competitive games, where the Client should not have access to the Server at all.
- DedicatedServer, hosted by the Players.
- Mostly used for games that have some form of persistent world where players join and leave and every set of players can have their own. E.g. survival games like ARK or even Minecraft fwiw.
UT spawned a local DedicatedServer instead of dealing with also supporting ListenServers. But that's, again, rather unsual to do.
keeps you from having different logic for the host ig
yeah probably, im still studying this networking part so i am learning the different solutions
I had a similar issue a while back and the path of least resistance was two levels in the same world that are just far apart
Yeah
The Ascent had some inner levels that were basically just far apart.
If you entered them you were teleported away to the sublevel.
with large world coordinationates there's nothing to really worry about
Actively having that run on a different "process" or server would have been a nightmare to manage.
As soon as you do that and you need those players to still be somewhat connected (maybe see themselves in their HUD), you notice that there is no communication between 2 servers.
you can have a level the size of the solar system and still not have precision issues
ARK also has listen server support, but they have a "tether to host" limit where you can't be over X meters away from them for performance reasons
yup
the game i am trying to build is very similar to minecraft in the sense that you have a "surface" world and you can enter a portal to go to the nether. but their map is infinite so it makes sense to split into entirely separate things
abiotic factor doesn't do that and the listen server lags if there are multiple zones loaded
The Ascent didn't have that issue. The only thing we did was divide the game into multiple huge levels, that took quite some time to go through. You had to travel together between those, but inside a given level you could go wherever you wanted.
Was a simple matter of using Level Streaming properly
if your world is infinite maybe multiple worlds makes sense
but literally anything less than infinite (that's a lot!) and same world is fine
Keep in mind that UE is originally build to be an arena shooter engine.
A lot of limitations are still present due to that.
If you want to make an infinite world game like minecraft, with subworlds and what not, then UE might not be the right engine in the end.
no public one at least, most of them just end up making their own engines for that
Yop, which is a whole nother can of worms
Not saying there are minecraft clones done in UE.
But you might also just not see where they use smokes and mirrors or simply accepted the limitations.
yeah that makes sense, my game isnt infnite so i am gonna try doing everything on the same world for simplicity
i didnt like this solution because im working on a chunk loading subsystem and it bothered me that i would have huge chunk numbers due to having the other "dimension" really far away but thats such a small thing to worry about
well you would probably just have two separate grids
chunk coordinates would be relative to their grid
yeah thats one way to deal with it
i was also thinking about stacking the dimensions on the y axis
Having two worlds for this might sound like a cool idea, as you can just connect to the other world if you step through a portal. But you gotta remember that it might make the whole server side of things more expensive in CPU time and that you might not have any proper data sharing between the two.
At least not without some extra work.
I could imagine this working though, fwiw.
it would really only be beneficial if you had a high quantity of instanced worlds I would think
Just needs a ton of boilerplate code. In theory both worlds are in memory of the server, so as long as you can get a hold on either of them, you should be able to even move data between actors of them.
I believe the two worlds could be async as well
Not sure, if it's just 2 dimensions, it might be fine to have your ListenServer just use 2 UWorlds.
But no one really has done that, so there might be a lot of hurdles and if unlucky some small engine changes required.
That I highly doubt
there's a plugin that I shant name because it isn't free, but it looked interesting
You need them to tick in the FEngineLoop. There are tons of UObject related things that don't allow being done outside the GameThread.
there's also an engine branch for server meshing I think
I looked into this shit cause I wanted to run a second world for HitValidation.
ah
Creating a second world is in theory really easy. I never did it for this kind of stuff, but I have created fake UWorld for Functional Tests.
There are some tutorials about that at least. I'm sure if one follows what the Engine does for creating the PIE world, or generally the first one, it should be easy to wrap that into some functions to greate "the second dimension" with a different level.
And since both of them will probably sit in the same array of FWorldContext, it should also be possible to access them.
And all their actors fwiw.
Might be a fun weekend thing to test out.
Client should probably only have one world though
And only connect to either of the worlds when changing portal
Might also want to only create the other world if there are players in it or so, idk
its great that it sounds possible, but it sounds a bit beyond my skills for now 😅
i found a plugin that does this but the second world is client-only so it doesnt support replication
i think thats the hardest part to get working
thanks for the thoughts, i really appreciate it, it cleared a lot of questions i had 
i might come back in a few weeks when i inevitably wont be able to get my chunks loading system correctly replicating to all clients heh
I have an array of FStrings that's larger than a bunch. How to send this to a client?
FFastArraySerializer could be an option? Although if it bunches everything that's dirtied, that's still going to result in too large of a bunch. Amortizing the data across bunches seems like the way to go, but I haven't found any tooling to help with that. Is the answer to write that myself?
I have smooth sync on my character and the root being a physics object, all physics is on the server but the client is not receiving the transform updates from server. not sure if it's a smooth sync issue or something else? If I read everything correctly client shouldn't have physics running which is what happens, but smooth sync isn't passing the physics root transform to clients
You'd have a better chance getting a valid response from the dev's channel instead of here.
I just gave up on that idea, although I wouldn't mind knowing why it won't work
I somewhat got it to replicate but not with smoothsync and even then. reliable yes, glitching all the bones on physics object Check.
Hey
I need to sync some buttons + levers in car cockpits using RPC from client to server.
player tries to push a button => Server_HandleInput(ButtonId, Payload), where payload is int8
the question is how to send ButtonId. For different cockpits ids for buttons are different. I assume sending FName "CarType1.Cockpit.HazardLightsButton" is less expensive than sending similar FGameplayTag.
It seems the best way is to encode all the button/event types as integers (or enum class?). Does it make any sense?
FName will serialize as a string. GameplayTags will serialize down to a minimal-size integer if you enable Fast Replication in project settings.
It's dumb that that settings defaults to false frankly
so let's say I could use FGameplayTag and it will implicitly be int anyway, so no need for If(id ==1) and I could use the tags for readability keeping the speed
Thanks for the setting, will look at
yep, but it'll likely be smaller than an int because the engine will only use as many bits as needed for any tag
good to know, thanks.
enums are still a good option too ofc, tags may make more sense when you need some sort of hierarchy/composition/modular game features.
well, let's say I just need to have ~ 100 buttons synced, and in every car type they do a bit different stuff
creating an enum per car type is kinda the same as having tags per car type
In that instance, I probably wouldn't make it per-car-type
Tags may make sense, but duplicating the same tags under a different top-most hierarchy is generally bad form, tags are designed to be used compositionally
E.g, a structure like this would be very awkward to run tag queries against
Car1.Button.Hazard
Car2.Button.Hazard
makes sense. in that case I would prob make Car.Button.Hazard regardless of the car type. but for specific stuff it would still require a unique tag Tesla.Tablet.Button1 whatever
so do you suggest using int+enums there?
If you're doing something highly specific, tags don't really make much sense IMO - but commonly people do use them as a replacement for enums
What structure makes sense is kind of up to your project I guess, but I would just caution against highly specific tags that describe game entities
The true power of tags comes from composition IMO
yeah, I see
at least, some data to try with
thanks
Can a actor marked not replicated have replication turned on at runtime (taking about a actor placed in the world not spawned at runtime)
I don't think so
damn thats a shame
I mean, meybe there is workaround but sounds wrong ;d
without replication it won't receive any updates, so you have to send enable command through different actor 🤔 and I don't know if you can even set this in run time
whoa i JUST realized quantized vectors don't actually quantize if they are serialized in a custom structs NetSerialize function using Ar << quantizedVector;
If there are more than 256 unique buttons (imagining some special duty machinery), enum would be not enough, if I want to use it in dropdowns in BP (enums shall be uint8)
Tags are limited to 65535 unique entries per project, right?
Yeah but if you get anywhere near that you've lost your mind
If it's really that extreme, just index them I guess
pretty sure you can?
you mean pure integer as is instead of enum/tag?
you could just replicate the button and use it's reference as the rpc parameter
no
for a struct with custom NetSerialize, is it necessary to mark all the fields as UPROPERTYs?
everything that you want to replicate has to go through a replicated actor at some point
Is the layout static or dynamic? Like, do you know the set of all buttons at editor time?
completely static
Unless we're talking about tons of states I'd just have the states live in the cockpit as replicated values
just 8 or so payloads
hmm. replicating server->client is another story (for some reason my custom struct NetSerialize has been never called)
though, to RPC from client, I need some IDs which buttons are "pressed" e.g. when player presses button1, I want to send to server(Actor, "Button1", true) and dispatch this call to corresponding Actor->HandleButtonPressed("Button1", true), where Actor has logic to handle all the different buttons pressed.
If you don't have that many and it's common then the ID is which RPC is called
Dunno your setup though. I'm doing modular cockpits but each control is an actor in my setup
Do your controls have different actions on them? Do you call different rpc or specify “action type” as param?
My system uses a graph
so for controls, they just output a float value to whatever they're connected to
ThrottleControl -> Engine.Throttle for example
But say you had some effed up vehicle that steered by differential throttle (2 engines)
You could:
SteeringWheel -> RightEngine.Throttle
-> Negate -> LeftEngine.Throttle
Well for my situation, i have ~ 100 (for now) buttons/levers which I want to call from client to server
Since rpc could be called only from objects client own, i put an rpc call on player character, specifying id of interacted button and payload
Did you add the Struct Ops for your Struct with the WithNetSerializer stuff? Can't recall if that was needed.
FYI working with ISMs are a pain, but theres a delegate you can bind to track index changes such that its possible to track changes in an external array (usually an issue due to internal RemoveSwap in the internal indice tracker)
Yes
pretty sure netserialize should always be called when going through an RPC... i believe it's for triggering OnRep's when the custom struct is a replicated variable is when you need UPROPERTY
I will show the code later on
so. My idea is
having some buttons player can press (using BP callbacks now). This calls
UFUNCTION(BlueprintCallable, Server, Reliable)
void ServerCommandInt(AMyCar* Car, int32 CommandId, int32 Payload)
{
if (Car)
{
Car->ParseCommand(CommandId, Payload);
}
}
Car->ParseCommand calculates some changes in state, and applies it to replicated struct
USTRUCT()
struct FCarReplicationData
{
GENERATED_BODY()
public:
ECarGearShifterState GearShifterState;
ECarBlinkerLeverState BlinkerLeverState;
bool NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess);
};
bool FCarReplicationData::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
{
uint8 StateGearShiftByte = static_cast<uint8>(GearShifterState);
Ar << StateGearShiftByte;
uint8 StateBlinkerLeverByte= static_cast<uint8>(BlinkerLeverState);
Ar << StateBlinkerLeverByte;
if (Ar.IsLoading())
{
GearShifterState= static_cast<ECarGearShifterState >(StateGearShiftByte );
BlinkerLeverState= static_cast<ECarBlinkerLeverState >(StateBlinkerLeverByte);
}
bOutSuccess = true;
return true;
}
ACar is smth like that:
void AMyCar::ParseCommand(int32 CommandId, int32 Payload)
{
if (CommandId == 1)
{
GearShifterState = Payload;
}
else if (SwitchIndex == 4)
{
BlinkerLeverState = Payload;
}
FCarReplicationData NewData;
NewData.GearShifterState = GearShifterState;
NewData.GearShifterState = GearShifterState;
ReplicationData = NewData;
}
UPROPERTY(Replicated, ReplicatedUsing = OnRep_ReplicationData)
FCarReplicationData ReplicationData;
AMyCar::OnRep_ReplicationData()
{
GearShifterState = ReplicationData.GearShifterState;
BlinkerLeverState = ReplicationData.BlinkerLeverState;
UpdateVisuals();
}
Any ideas why OnRep_ReplicationData is never called? any suggestions?
the 2 enums in your struct need UPROPERTY
well ,they are not BlueprintTypes, so I thought it was OK to have NetSerialize
Hmm i would honestly just male a proper struct and only send the data you need
Chaos vehicles has an example or maybe the old one.
Where you send the data that had changed
do you guys do anything special when you have a hig hcount of a smale base class of comps ?
I hate generic functions that look ambiguous
No?
But context matters
like a replicate manager
Vague question
yeah i know, i dont know how to precise it without giving a full paragraph
Give paragraph
to late for my lazy brain 😅
ill try the push model, never used it before
Mark actor dormant and only ipdate of it has changes
any ressources on what changes and what func/macro to use ?
Normal networking stuff
just have to call a macro when you want to mark dirty nah ?
Check the push model header
Most of the time you just mark a property dirty
Best is actually looking snd like playercontroller.cpp and actor.cpp
And how they did push model
Couple of nice mscri
those are big classes but ill look
Mscros
Just search like getlifteime
And MARK_
Also remember enabling push model means you must mark dirty for a prop to replicate
In our project all props are push model
so for the "paragraph" here is a short version
i got a component class which holds an array of Uobject which acts like fragments
you can easily have a lot of these, maybe one per any actor containing logics (so hundreds per map i assume)
so since im replicating the UObjects as a subobject of the actor component, and each UObjects replicates there properties, i wonder how i could optimize that a bit
yea, i debated a lot between using UObjects or instanced struct as fragments
Yeah I originally did that with inventory then switched to fast array and not replicate the item instances but create them locally lol
since they need functions and stuff i went for UObjects, more BP friendly to
But that's specific scope
Won't work here
I mean it could work but would require a lot if thought
But 1000s of subjects per actor
Is going to be costly and if these dint change st runtime pointless
not that much, maybe a few fragments per comps
(i mean, its a plugin so i need to be robust for intensive usages)
Bug if they have rep properties then it will be expensive
So, can you a bit wrap up it for me. If I have a lot of replicated properties, I though they will make an overhead (as discussed before with some people here)
though I decided to make the atomic struct + pack enums to bits later
Are there any better methods you've mentioned?
also ,what's about Client->Server RPC, any better idea?
Either way you cut it. You need to rep initially all objects
This is the cost then you have the cost of checking the objects.
Even with pushmodel
More rep props don't increase it that much especially with push model. When I did vehicles the vehicle had a state component that handled all interaction snd replication. We didn't do anything super special. We dilly sent a struct on tick unreliable with the clients local state data and replicated a version out to simulated
Nothing super special
This strict held some packed values bitflags etc
So ur was quite cheap
Cmc does exactly this also
Sorry for typos on phone
And it's late
hmm. I'm not familiar with Push Model
But I mean you send the state data as RPC, like not 1 RPC for each button like I did? (with id + payload)
well probably I need to make something similar
though, such struct shall have uproperties + replicated flags on them?
With what yhe player wants to do
Yes ofc
Let me see if I can find what we did
Give me a few
Appreciate. Because this drives me nuts, especially with amounts of buttons I plan to have (and not only cars in consideration)
is there anything i can use if i rep only once ? (read only frags), i only know about the COND_RepInitial thing
i wish there was an update rate per replicated subobject
how does replication happen when collecting props ?
does the world/engine gets all replicates actors on tick, and for each actor they get the replicated comps, and for each replicated comp they get their replicated subobjects
(while checking for dormancy and rep rate)
and @meager spade, would having a giant fast array replicated in one replicated actor singleton be better ?
one one replicated comp, which sends the updated data to all comps with their fragments
so like, each entry of that fast array would be
- the comp we refer to
- fragments
UNetDriver::ServerReplicateActors_BuildConsiderList Is a good place to start.
Though, Im not sure how much that has changed in UE5
With Iris and all the rest
RepGraph etc
im not using either
I have a free plugin I wrote that uses InstancedStructs to do an Itemization system. Take a look in my bio for the link.
It might give you some ideas. Its fully replicated using FastArrays.
still expensive
cause you have to gather all replicated subobjects, then check if they need to be replicated
and this has to be polled
cant be push model (even with iris)
so its pretty expensive if you have a bunch of Subobjects
like 100s per actors
I was only responding to his question about what process the engine goes through.
Not what is optimal
Iris is a bit faster
and UE5 has a smarter way (where you register to a list the objects)
but you still need poll those objects, you just skip a few steps
{
ReplicatedOwner->AddReplicatedSubObject(Child);
}```
like you can push and pull the objects
without needing the for loop or w/e
the thing is w/e solution i would find with instanced structs, i will not change to that over UObjects because instanced struct cant have things a UObject has.
unless i do an array of uScripts ... and accept both with custom property view
in ReplicateSubobjects virtual
What do you mean?
What things are you talking about?
If you mean like Blueprints that can execute code, you can easily associate static Blueprint Objects with Structs.
The Struct is the Data, then the associated Blueprint is the code that can operate on that Data.
You only replicate the Data.
thinking about it, you could do it smartly and only replicate the object if the object has changed, but i think removing it will destroy the object on the client side, so this might not actually work well. GAS abilities uobjects are not replicated unless you mark them replicated, so you could design the system to have a specific "bReplicate" to only replicate that subobject that needs replication, and not all of them.
some might not ever need replicated properties
and just be built from the static data
thats exactly what GAS does
Take a look at my plugin, you might learn some new things.
it my case they can be pure data frags or actually hold logic
Or look at GAS
if its not replicated, create local instance of the objects, if it should be replicated, only replicate that
instancedstructs are the new cool
you dont blindly want to replicate all subobjects
client can check if the subobject should rep or not and create a local copy
server does the same but produces a rep copy if it should replicate
this leaves it in the designers hand
@meager spade Do you know of a reasonable way to selectively replicate properties to specific connections? Is Iris capable of this?
is that what ur plugin does for items logic ?
Yes
hmm, right cause GetLifetimeProps only has a bunch of defined options but not per connection
i need to look into these
iris uses the standard GetLifetimeProps, for props
Look at FItemInstance and FItemDefinition
so i don't think so, and i havent seen "property filters"
its almost been 6 months without MP, i didnt dig into what unetdrivers, unetconnections and unetactorchannel really are and managed
only class filters
One issue I ran into with FastArrays and InstancedStructs for itemization was that, there wasnt a reliable way to not replicate everything to everyone, outside of just using OwnerOnly.
Thought maybe UE5 had a solution
feels like doing a giant FA is the best way for a generic system
(living on a replicated actor singleton)
its just that testing the few paths and profile them takes a lot of time, time that i dont really have
Sometimes its useful to architect a solution you think will be performant enough, then profile that.
If it doesnt meet your requirements, you can either optimize it, or use the knowledge you gained to explore a different approach.
You will never write a perfect system the first time.
thing is im doing a plugin so my requirements are "the most i can do"
i guess supporting 500 replicated actors with each 10 fragments would be the maximum ill optimize
You have to start somewhere, having no plan is worse than having a bad plan.
my infamous inventory rewritten 5 times 😆
Experience and knowledge come with time.
any of yall using server streaming? or know of any writeups on the issues it comes with?
If you write an inventory system enough times you will become an expert.
im maybe reading to fast or to tired to find it, but i cant find where your items handle logic in your readme
Depends on the logic.
An ItemDefinition is the static data of what an Item is.
This is where you would store objects that execute things for that ttype of item.
An ItemInstance is an instance of an ItemDefinition
It has access to its ItemDefinition and would then use it to execute whatever logic it needs.
The UserData is the most generic spot to add Objects that would execute Logic for an Item
The InstancingFunction is more specific to when an Item is created, you can override it to setup dynamic elements or introduce new functionality for when an item is instanced.
The Affixes are also something that could be used to store "logic"
For example you could theoretically extend them to apply a GAS ability to the Character.
But that isnt covered in the sample project
so your item instance is an UObject defined from a FInstancedStruct
which holds an array of user data which are UObjects
No
An ItemInstance is not a UObject
An ItemDefinition is not a UObject
They are both InstancedStructs
They can hold onto references to UObjects
NetDriver.h and PushModel.h are suprinsingly well documented
hello, im having network issues in my game (i think), some stuff appears to desync or fail to sync and sometimes even reliable events fail to fire it looks like
it also starts to have an impact on the game thread (i think? unless its caused by something else, most of the load appears to be in the EndPhysics tickgroup although i dont believe i have anything taxing that operates in that group)
what i want to ask is, would enabling iris replication somewhat help with this? or is everything in my hands with optimization?
i dont expect it to be a perfect fix that i just turn on and everything magically works, but if it does help make things faster before i try to start optimizing, it would be good
profile it to see what is actually slow
if net broadcast is slow you might see some gain from iris but be warned it is experimental and may not work for what you are doing immediately
thing is, it doesnt happen in the editor and especially not on a clean save of my game
it might help to just reduce distinct network objects or catch something capping out bandwidth from sending redundant data (network insights)
hmm
the editor is not the only place you can profile in
the editor IS YOUR GAME
just with some extra buttons on it
Insights can attach to remote and local builds that have tracing, a test build would emit events
you may need to start it with a console command I guess
trace.file MyEpicFile default
then trace.stop
network insights is more involved but you can just read the docs for that
hmm alright, thank you
i need a friend to wake up before i can start profiling since i dont have the issue in any of my save files, ill come back here if i find anything interesting
It would be a good idea to have them send it in for you to mess with locally in a test build
if possible
sometimes stuff like this is hard to reproduce though so hopefully that is enough
yeah, but i need them to be awake for that lol
as for network bandwidth profiling network insights is the fanciest (shows every single packet in detail) but you need to launch the game with some args https://dev.epicgames.com/documentation/en-us/unreal-engine/using-the-network-profiler-in-unreal-engine -NetTrace=3 etc (I think 3 is the max as of 5.6)
ive tried getting the savefile and running but i wasnt getting any issues, i also tried joining my friend's hosting world and i wasnt getting any framerate issues anymore unlike yseterday
he was getting terrible framerate though as the host so i got him to profile for me
i posted about it in the profiling channel
#profiling message
any useful commands to see net stats ?
like how much time the engine took to iterate replicates actors, processes bunchs, etc
that stuff is easy enough to see on a regular profile
yeah im just wondering if their is any cool net profiling commands, so i dont have to trace each time to check how much time it takes
I can't think of one but that seems like something that would be a decent stat command
I just use regular profiling every time
Stat net is mostly bandwidth related
is there a "authority" defined for a not replicated actor/component ?
because, if its placed in the level, it exists on both server and client, but if its spawned/added at runtime, it will only exist locally
remote role might be useful here
also role isn't really set until it arrives afaik
unless there's another flag I missed
okay
i assume not replicated actor/comps cant send/receive PRCs ?
thats what i got for now
main issue for me now is this will save some overhead in MP context, but will add some in SP context.
i guess i'll have to make 2 PSC classes, one for SP and one with networking
so it would look like that
Actor components that are not replicated can send/receive RPCs if the owning actor replicated
Really? I had no idea that was a thing
I guess they're stably named as long as they aren't added at runtime
Yea because they use the owning actors callspace or whatever its called
Even if they get added at runtime, this works.
It relies on stable naming though. And there is a function IsStableyNamedForNetworking or something like that.
Well that's what I was going for; adding a component at runtime won't give it a stable name by default
How much of a cost is even associated with marking a component replicated any way? Esperanza with push model?
I believe it is a pretty tiny cost. It sends the identifier for the component (which is an additional int I think?). Other than the normal cost of having something replicated. Which is mitigated with the push model.
If it's not replicated, the local instance has authority over it
Also true if it is replicated but the actor is torn off
thanks autocorrect for turning especially into esperanza
Is it possible to mix Ar << and Ar.SerializeBits in one NetSerialize function? I assume yes, but it's a bit tricky how to read those with Ar.IsLoading(), I have some garbage values, do I need to unpack it somehow specially?
Appreciate any reference
https://www.udemy.com/course/multiplayer-in-unreal-with-gas-and-aws-dedicated-servers/
I'm sorry if I shouldn't post the link here, just let me know and I'll delete it.
Is there anyone who ever used it? Do you recommend? Or do you have other recommendations to learn multiplayer (globally, not LAN)?
i dont have for AWS, but for general MP: https://notes.hzfishy.fr/Unreal-Engine/Networking/_Resources-(Networking)
the docs are a good entry point to https://dev.epicgames.com/documentation/en-us/unreal-engine/networking-and-multiplayer-in-unreal-engine
thanks
generally speaking, how is aiming replicated and predicted?
say I want to cast a ray to the direction the player is facing
depends on the game
I don't think using GetCameraComponent()->GetFacingDirection() is safe to use for multiplayer and locally predicted stuff
It doesn't seem to be correctly replicated if replicated at all
many games have the player do the raytrace and determine if they hit something. then the server just verifies if it's generally possible that it could have occurred
hmm okay
so generally speaking should I just associate to each "shot" a facing direction that will be sent to the server?
some make snapshots of player locations in time. then when a player submits a ray to the server, it checks where players were at that point in time and sees what that ray hit
that's safest but it'll feel like shit
it's weird cause I've never had issues using GetOwner()->GetFacingDirection() in CMC
GetOwner()->GetActorForwardVector().GetSafeNormal2D()```
That I mean
it's always been in sync
easy way to get some security is do that first method and see if the player hit the targets bounding box.
if that isn't enough use rollback
hmm okay
okay I just thought for a second
maybe you could update the facing direction when needed in the CMC
send it over with the compressed flags and stuff
and use it as a safe variable on the client and server?
that sounds pretty good, predicted and will be corrected
much better off having facing being a cosmetic thing unless you have game mechanics that heavily depend on it
in a perfect world you trust the client with nothing and the server performs/checks every single thing they do
yes but I'm pretty sure CMC already handles facing prediction
but also, trust the client as much as feasible for your game
i am telling you it wont work as is 🙂
ooh it actually handles rotation
how do I tell if, in the case of a listen server, am a client playing on the server?
because Authority will be true for every character
but how do I tell if this one specifically is controlled by the server? Can I use GetOwnerRole() & ENetRole::Autonomous_Proxy?
basically a IsLocallyControlled() function, that exists with GAS but idk for the rest
GetNetMode()
also if you're doing listen servers dont even worry about preventing cheating
host can always cheat
Hi, I have a question about Launch Character.
I’m not sure why, but on the server, the character’s mesh sinks into the ground after launching, while on the clients everything looks fine — the mesh doesn’t sink.
Does anyone know what might be causing this? (Multiplayer problem)
sounds like a desync, are you multicasting the launch?
when using DOREPLIFETIME_WITH_PARAMS_FAST i gives me this error for my fast array
other macros (not fast) works fine
(my goal was to use push model with FA)
PushModel doesnt work with Arrays
That must be new in UE5 then
Did you forget an include?
the type is in header
Did you forget the PushModel header as an include?
#include "Net/Core/PushModel/PushModel.h"
#include "Engine/Public/Net/UnrealNetwork.h"
Typically need both of these
when adding fast array entries, i should be able to keep a ptr to the struct entry fine until its removed right ?
Is it a static array?
no
No I launch character only on the server
Unsafe then
this
FPSPrefabPropertiesObjectEntry& APSPrefabNetManager::AddEntryFromObject(UPSNetPrefabSourceComponent* NetPSC, UPSActorPrefabPropertiesBase* Object)
{
return PrefabPropertiesObjectContainer.Entries.Emplace_GetRef(NetPSC, Object);
}
Other elements being added/removed can screw with it
I mean if you dont touch the array for the duration of that reference then w/e that's fine
Just don't try to store it
so, no way to store that
sad
i assume c++ is super fast at iterating arrays ?
i maybe doing to much micro optimization just because ill have 1k-5k entries
You will be fine iterating it to find an entry.
does this need optimization 🥀
ItDepends(TM)
lmao
tbf that only happens when joining, after that it settles down
but it still hangs around 4000 as soon as a player starts doing anything so idk
no idea why its so high though
there shouldnt be anything actively replicating really and 90% of replicating actors have the Min Net Update Frequency set to 0
Only way to find out what it is would be to use insights and see what's replicating
That way you'll get per actor/per-property breakdowns
network tracing works only in packaged right?
it works even in editor builds
i tried it in the editor earlier (i think?) and i didnt get any trace
It can be fickle but I find stopping and starting a trace before pie can help
also show startup args
on the editor? i set none
lol
but rn my friend is online so i can test in a real game scenario
does this look ok?
the editor is also a game
yep, I think that's good
do i need to trace.start and .stop still?
yes
i havent analyzed the trace yet but
w h a t
I think is because I change the Capsul Collision Half Height
is gravity scale predicted?
I'm assuming it's not
it's not even replicated 😔
so how would I change gravity scale predictively?
how often does it change? personally i'd just replicate it as a variable in gamestate or something and have clients update it with an onrep and just let the slight rubberbanding happen when it changes
it changes like once every 10 seconds
that would be bad to rubber band
i think i found a way I'll put it after
Hey, despite having all these classes:
my safe variable (which is not a compressed flag) is not being passed to the server
the reason is that PrepMoveFor is NEVER CALLED
and I don't know why 😔
Does FNetworkPredictionData_Server also needs to be overridden?
im having an odd issue, some actors are just... not existing? my friend is spawning in a replicated actor and it doesnt sapwn in for me (connected client)
also some actors in the map havent loaded on my client either, very odd
all i could find in the log is this and some other similar lines but idk if its related
[2025.07.24-15.50.19:877][ 0]LogNetPackageMap: Warning: InternalLoadObject: Unable to resolve object. FullNetGUIDPath: [3601]NOT_IN_CACHE
[2025.07.24-15.50.21:607][ 74]LogNetPackageMap: Warning: InternalLoadObject: Unable to resolve object. FullNetGUIDPath: [1941]NOT_IN_CACHE
[2025.07.24-15.50.21:607][ 74]LogNetPackageMap: Error: UPackageMapClient::SerializeNewActor. Unresolved Archetype GUID. Guid not registered! NetGUID: 1941.
[2025.07.24-15.50.21:607][ 74]LogNetPackageMap: Error: UPackageMapClient::SerializeNewActor Unable to read Archetype for NetGUID 1496 / 1941
[2025.07.24-15.50.21:607][ 74]LogNet: Warning: UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor. Actor: None, Channel: 239
Can the HUD exist before the PlayerState? 🤔
Where do I mod the engine code for P2P? Do I need source code?
I want to optimize for 300 players and remove lag by basing the updates off the highest ping dude in game
I think yeah, go where the HUD is made (i think PC or GM on Login) and where the PS is made (PC iirc) and see what gets logically always called before
gestures vaguely at the entire codebase
You will need to modify the engine source to mod the engine, yes.
Has anyone tried locking packet updates to the highest ping player to remove ping advantage? So all players get updates at the same time
You want to change the networking model from server/client to P2P and you're not sure if you need source code for that?
That work is incredibly complicated and is based on decades of work in the area.
Don't care just doing it no time to beat the bush
basically gonna P2P update across eachother and compare data(antihack) and lock to highest ping player, unless their ping is like, 300, in which case auto kick
You are describing deterministic lockstep which isn't something unreal engine supports by default
Thanks for the proper terms
It's likely several months of work, if not more.
mostly used with RTS games
I'll just cut the fap from the schedule
What type of game are you working on ?
they talked about it in 2015 here ---> https://forums.unrealengine.com/t/please-add-deterministic-lockstep-networking-for-rts-style-games/19255/10
Why p2p
rubber banding is scary okay?
why don't we throw ggpo with rollback too? 👀
Yeah you cant mix lockstep and realtime shit like fps
Tim even replied on that thread
2015 and not been added? epic needs to cuthe fap
you're telling me that if you add a 300ms delay to input in an FPS it won't feel good?
If only you knew ...
P2P cuz I dont need a million dollar server
UE misses a ton of shit
This is a question that has been raised in every generation of the Unreal Engine, and it is definitely not in the works. Lock-step execution can only work if every engine system on every platform is designed for absolutely deterministic execution. That’s not the case with UE4, as a big engine with a time-dependent game update model and reliance on a wide range of middleware and a wide range of platform and runtime OS-version and API-dependent optimizations. An engine could be designed this way, but UE wasn’t, and it’s not practicable to retrofit it for a special usage case.
Instead of lock-step determinism, I recommend working with the engine’s network replication framework. This code has fairly good performance and typical internet connections have plenty of bandwidth, so I expect it to be practical for RTS usage.
Also keep in mind that you can customize the engine’s relevancy checks (which determine whether a given object is replicated to a given client) based on the client’s view of the world, which will usually change fairly slowly in an RTS.
- Tim Sweeney April 2015
yeah I just started and i discovered that water is almost impossible
I made water in doom 2 in like a day
People can cheat in listen server and p2p
and if you use quantum computers, then you won't have to worry about lag
oh, I've been this naive before 🥹
If it was that "easy" we would see robust p2p anti cheat already
naaahhhh internet moves at 2gbs and 144 frames/packets a second is a mere few KB of data a second. They just suck.
you not only want p2p network, you want meshing with distributed authority
p2p is listen server, one person is the authority (and can cheat)
isn't it too early in the morning for trolls?
you want distributed authority
Why do uneducated hipsters always think real code is troll?
get lost
and it wont add 300ms
just means you can't play on slow internet
that's not what I meant. RTS games add delay to input to hide the lag from using lock-step.
dude the last RTS game was made 100 years ago its starcraft
this is 2025 and DIY code>corporate garbage code
It isn't so much about the amount of data you can send over the network its more like how much of it can you processes during a single frame while remaining within ms budget.
I don't think that a few KB of data will effect that
So you ideally want to keep the amount of data traversing the network low because you still have to process all the other stuff too
I'll make sure to keep that in mind cuz just upgraded my PC to 400mb ram
so you said fps with rev share on p2p, so its a PVE coop?
because if its pvp you'll have lots of cheaters using p2p
no its a highly competitive fps but right now im new so I'm trying to get water to work, everything else is easy
I know how it works and how to do variable compares you avoid injects
right now I need to get water working
what are you comparing variables against?
themselves thats how you doit
without a server for the trusted authority of the entire simulation a peer can just alter their memory and do whatever
k
if u make the code check if var X is the same as it was last frame or whatever that doesn't matter because a cheater can just have their program alter the same part of memory every frame after your check runs
but with a dedicated server it simply doesn't alter the memory like that and so if a cheater changes the variable in their memory, the server corrects it after
Say for instance a cheater teleports right behind another player and then tires to shoot them, on their screen they'll see themselves teleported but then on the next frame (or close to it depending on lag) the server teleports them back because their location is invalid
Does that make sense?
Also just to be clear I'm not saying using a dedicated server as the authority will prevent all cheats but it will at least make it more difficult for them.
2 day old account
Hello guys! I have an serious issue. Me and my brother test our multiplayer listen server project. When my brother the host, on my Pc the character animations jittering but when I am the host, on my brother computer the character animations are good. FPS is good, stabile 60-80 fps . What could be the problem?
Trying to understand FUniqueNetIdRepl. I have a custom UUID for each player in my database (I use Cognito for auth). Can I set that as the user's replicated unique net id in PreLogin from the Options passed in or what is the best practice here? I'm trying to use OSSv2 (the auth interface) as well
Water to work how?
waves + physics, just volumes that switch the CMC to swimming, just visuals, what
Animations on the Server for Characters are ticked through the CMC, which is a bit painful for ListenServers. Iirc one can play a it with the settings for that but I haven't dealt with that in a while.
Is there an event that fires on the server when a client connects to it? I know there's a callback function for OnJoinSessionCompleted, but that seems to fire on the client system. I attempted to use OnSessionParticipantJoined, but that didn't seem to fire at all.
Originally this is all due to the server not running OnPossess after the client connects to it, as, by my understanding, it's supposed to.
In fact, it seems like, despite using ClientTravel and explicitly stating not to use Seamless travel and having Seamless travel turned off in the Game Mode, that the behavior I'm experiencing is similar to travelling Seamlessly. I'm not sure what I'm doing wrong. Any ideas are welcome!
@dark edge Flat plane water that collides at peak waves instead of a generic box
painting surface and realistic sim physics irrelevant
Finally solved framerrate dependant physics sync. and changed from a physics asset to a controlrig character which now sticks to the characters root. but now for some reason the jump button and movement seems to be more laggy now and jump sometimes doesn't even work. any ideas? Jump is a simple sphere cast downward that sets a bool on repnotify and if true, set impulse Z
Why does jumping involve a repnotify?
That seems silly
My character does things in the air and the server needs to know if the character is jumping and not just not touching the ground
I wish they exposed what data I send in BP, I bought smooth sync to do this but I can't get it to work
are you using Character or did you roll your own?
it kinda sounds like you have 3 ways of syncing here
define "is jumping"
My own
Ignore the Branch that does nothing. I am planning to put different surface types in there for ice/sticky etc
Ow, I had the jump release on not reliable lol
My bad!
Although I do have one other question
It's hard to explain. but at the begining of matches or join the prediction is off, and over time it becomes more reliable, is that just how it has to be or is there some setting I need to do to improve it?
This is at the beginning of session. you can see the like magnetic replusion (this is with 12Ping)
And this is a little bit more into the match where it resolves. I guess it's not really an issue pre se, I just want to understand it. I also increased the lag and everything that predicts still works as if 100% synced no issues
Jumping is now fine btw
I wonder if I have to kinda freeze everything, wait for all the players to join then start simulation on server. I think that's the cause?
So far with my 2 weeks of reading and learning all these new things I think I have finally managed to get stable physics online brawler working with my custom player controller. however just that first related issue which is prediction related. which I think will be solved when I freeze everyone for a split second when they join
Yep, that was it. also can't turn off or on simulate physics anywhere in the player BP good to know! Game now has no bugs. that I am aware of
Trying to set up Online Services V2, with Common User/Common Session Subsystem (plugins from Lyra) but keep getting this error: Assertion failed: OnlineServices [File:C:\Development\Games\GameLiftUnrealApp\Plugins\CommonUser\Source\CommonUser\Private\CommonSessionSubsystem.cpp] [Line: 382]
I have a default service set like this in DefaultEngine.ini:
[OnlineServices]
GameDefined_0=OSBackend
DefaultServices=Null
And also setup IOnlineServicesFactory, FOnlineServicesCommon, IOnlineAccountIdRegistry.
Any ideas?
so the inventory and crafting is working "okay" but should i be handling it like this is it okay, ps im not worried about cheaters
You may want to try #online-subsystems they might have better directed knowledge.
Ah thank you!
Nevermind I fixed it, needed this plugin too
Been awhile since I've seen you here Meags
Oh hi! Yes I was busy working on the website and game launcher hehe
Hello, is there any way to make certain sub-object component properties not to be replicated to certain clients? Something like IsRelevantFor, but per-property basis in an actor component. I see that there's COND_Dynamic and GetReplicatedCustomConditionState(), but I don't see how I would identify what client it's evaluating it for, so that I would discard certain clients from replication of that property
(idk but im interested for the answer)
Is there a way to replicate an object to a specific team only? Assuming the team mechanic is already implemented. Something like a function callback for the rep condition?
i know theres a COND_NetGroup and you can control a players net group through their PC.. but i've never used it before so im not 100% sure how it works
Oh that's handy. Thanks man.
If anyone experienced in replication, I will be grateful if you help me out why the client to server to multicast is not working for the player rotation ?
no problem
Is there any known issues with 5.6 or is it safe to use compared to 5.4/5.5
at least a couple of things here. player controllers are only relevant to the owning player, secondly GetPlayerCharacter(0) is just going to refer to the first character available in the world, not a specific player's character
GetPlayerController(0) is pretty redundant when you're in a player controller BP
so what should i use instead?
if you leave it unconnected it will use the player controller it's running the code on
since its in the player controller blueprint
also im pretty sure "Get Hit Result Under Cursor" wont work on the server with a remote player so the first branch will always fail
why might servertravel work in editor but not in a packaged build?
my guess is that a player controller isn't getting assigned after travel and the level loading because its stuck in the default camera. via a widget that shows players connected, the server sees both players connected but the client does not.
Both players can quit and i can host a new session and the client joins just fine, but when trying to travel to a new level once a session has already begun, player possession only seems to be successful in editor
Q:
In a multiplayer game (assuming 4 players), is it realistically possible to create a moderately large, photorealistic map that performs well (i.e., is lightweight) on a listen server?
For example, something like an urban alleyway with a dense concentration of meshes...
Additional Info:
The GPU is a GTX 1660, and the CPU can be anything as long as it's not a bottleneck.
This image represents one grid, and the idea is to have about 20 of these grids
Why are you running client RPC?
the Hotbar inventory is stateful, you don't need to tell client to update via one time event like RPC, you gonna have bugs fairly quickly, especially with people that reconnect.
simply set the value on server and it will replicate to client, if you need client to respond to the changes, do it on the OnRep
as for 5.5, is {,,UnrealEditor-Engine.dll}::GPlayInEditorContextString still working ?
i keep getting Not In Play World
well the context of where you're observing it is important
but it worked last I checked
well here inside OnRegister/WSS Initialize im no getting it
i gotta say thank you too you as well man, i was fighting trying to learn with ai and i didn't believe what it was saying about the client RPCs and when i was deleting some of them it wouldn't fix anything well i saw that you were saying the same thing as ai and i figured finally i was definitely doing something wrong, was about to just butcher all the progress i made cause nothing would fix turns out i was just stupid all along and just had to delete ALL my Client RPCs and now it finally works all through the server. Literally spent all my weekend trying to figure out why. so thank you!!!
might be worth looking at replication graph
With Iris?
oh idk
thats exactly what iris filtering - group filtering specifically is for
granted ive only read the docs and never implemented it, since the API changed over versions and dev wiki example is outdated
But maybe someone has working example for 5.5/5.6
Yeah.
On that note im wondering if the filtering can be done on actor or component/subobject level aswell. I thought of some cases where i would like to replicate subobject data holder only to specific connections as part of a globally replicated actor
Right now, without Iris, I fear the only way to do it is to have a unique object per player and repeat the data for each team on each player.
Which is absolutely awful.
Im absolutely rooting for Iris, the legacy system is attrocious for scaling and rep graph is not easy..
Root away - it is the future
UE6 and FN depends on it
And FN already switched to it in 5.5 last I read
im trying to debug why a replicated actor which is spawned on server in a world subsystem isnt spawned on clients once they join
Is it set to replicate?
Are the components, including the root component, set to replicate?
yeah
its a empty actor (AInfo) so i assume no
Does it have a root component?
They are not.
AInfo hides the actor so maybe thats why
but i tried using AActor and had the same issue
Yeah. Probably a relevancy issue.
That's the other thing I was thinking of. Otherwise, show your setup.
If it has no root component that may affect relevancy.
Oh, didn't see you say that it doesn't have a root component.
yeah
You should always have a root component.
well i think unhidding the AInfo actor worked
because now i have a crash when the fast array is serializing the received bunch
which means it received the replication from the server
i think its because i used replicated on the container member var
idk, im testing now, getting a crash with not much info
(nvm its not the case)
Does anyone have any suggestions for a “most correct” way to implement a multiplayer knockback that can be locally predicted?
I’d been hoping to just locally predict a simple Impulse on a Character Movement Controller, but haven’t had much luck so far.
nope, still no replicated actor
it's getting added to the persistent level right?
ive done that (RootComponent = ....), didnt fix it
i compared my actor ctor with classes like gamestate
i dont know why its not working
is it because i spawn the actor inside the world SS ?
You probably want to implement it as a custom movement mode in the CMC or implemented in an FSavedMove so its properly replayed on the server
whats your constructor for the ainfo?
also when is your ss doing the spawn?
PrimaryActorTick.bCanEverTick = true;
bReplicates = true;
bReplicateUsingRegisteredSubObjectList = true;
bAlwaysRelevant = true;
im debugging with AActor now, not AInfo
same difference
Hello. I'm trying to replicate throwing an item like a bottle. When the input is pressed, it is run on server, spawns the actor and calls the throw event where it adds the impulse. From what I can tell, this should all be on the server, but the client doesn't see the throw
is the throwable actor replicated? is its position replicated?
The throwable actor is set to replicated, but I didn't set replicate movement
if you dont replicate the movement, then the impulse is getting applied only on the server, and the client is none the wiser that its moving
Alright, I'll set it to that. didn't think the movement needed to be replicated if it was run on server. Thought clients would still be able to see it. I also thought I heard in the past setting replicate movement can make movement choppy if there is some latency
itll look choppy even without latency unless you smooth the position
otherwise it will only move every time the network updates its position which might not be frequent enough to look good
you could also multicast the add impulse and not replicate movement at risk of somewhat desyncing the projectile
for clients its basically cosmetic though
Initialize
I see. that makes sense. Thanks
I got the throw to aim for the same spot for clients. Now for clients, the thrown actor sometimes bounces off a wall instead of running Event Hit, and then on the second bounce runs Event Hit. How is Event Hit handled for the server? Should event hit call a run on server?
I'm trying to make sure the bottle breaks at the same location for everyone
I'm also confused why it sometimes bounces of a wall for the client but not the host if movement is replicated
theres a few ways you can handle it. i would probably have the client hit handle VFX and the server handle gameplay effects like damage or something
I'm guessing I should run on server the hit location and spawn an overlap sphere to see if there is an enemy in range, then multicast the breaking effects/sounds
i dont see why collision should work differently on client and server. if you're replicating movement it might be possible that the position update tick hits right before and right after an impact occurs
you can do that, or have the client handle the effects
still stuck on this godam actor