Because they obviously don't give two craps about Blueprint support it seems for a Multiplayer perspective as much, sadly. I don't know why they don't just open more up for us in the end.
Cause that was never the plan. It's a scripting language. It was meant to turn some lights on and off from an exposed Button when UE released.
#multiplayer
1 messages · Page 257 of 1
Whatever it is today is merely because people started using it too much.
And I'm not looking forward to Verse either..
The more you know
But that's a different topic
It is a bit of a shame how much stuff is hidden from BP that doesn't need to be though... a lot of things I think would not take much effort to expose
That siad it's just not scaleable for many reasons and that aren't just perf... binary assets cannot be merged in large teams etc
Agreed on the first part there. Just expose it. Give blueprinters the QOL anyhow. It's where it is now, continue it
Performance is a wild topic. People who have small projects or those that just started on theirs are absolutely blind when it comes to that argument.
They don't see the problem until it's too late.
But their project might never make it to begin with..
I saw how expensive the Blueprint Graph of an AnimBP is.
I will never ever code in that thing again.
It's impossible to get across how expensive stuff should be and when to be careful but the the good news is it's VERY easy to profile stuff and see what is slow
I do like OnReps. And I use them when possible. But honestly, this fucking engine and it's lack of delegates in the most basic of places is infuriating. PlayerStates are a core example where there isn't any BP exposure to them being ready, or even being added to the gamestate array. Which is pretty insane when you consider that a PlayerState is a very core object for display a lot of UI data besides the possessed pawn.
It really does not shock me one bit that a lot of people hate UI programming in this engine given all of the steps you usually have to take to actually get started that should already be a core engine set of eatures.
Yeah, but the size a project needs before this shows up is usually a point of no return for most of them.
Definitely something that can sneak up on you
you can't profile something you haven't made yet
Also, what's the go with Iris ? The new replication system... Just better performance with the netcode I guess? Since UE's netcode at the moment is ancient right? But it still doesn't give Blueprint any favours........
Introducing Lyra and its weird Component system for things being ready.
Blueprint won't see anything of Iris.
Iris is mostly for perfomrance of polling properties and managing sending things to a lot of distinct objects, it doesn't change anything about the bp integration afaik
Exposing anything to Blueprints for Iris would be stupid
Even in C++ you don't really see the difference in the API, Iris just changes the lower level parts
besides if you need to make a custom serializers or use the rep graph
In theory, Iris even takes away from what you previously did in C++.
Cause you rarely add any custom NetSerializers with it
Right. Interesting. So Iris is the new and improved of the old netcode of UE?
On top of that, Iris is still very unoptimized..
Iris is getting better
It's ABSURDLY tryhard internally... they pack fucking everything into C arrays
Isn't UE's netcode at the moment like 1000 years old though.
Heard there were a lot of subobject bugs in Iris still too. :/
it's got some goofy parts like the still polling stuff for no reason but there is no way it's ever slower than the old setup once you pass more than a few dozen objects imo
So tryhard, that they mark the Owner an all its Subobjects dirty of any of its Subobjects is dirtied. So tryhard, that they poll the whole objects if a property gets dirtied, etc.
yeah it does have some small gaps still... It all works great once you fix the small hiccups though with some engine changes
Somewhere between user-level and c arrays, Iris is still behaving poorly
But there will be some updates the next weeks apparently, that address some of this headache.
Freaking mental how expensive Iris is without those changes.
yeah there's definitely still stuff like that but the foundation is the part that is harder to change... they are actively making the parallel on main
Overall, I love that you guys see my pain here and there anyhow of a simple blueprint guy like me where Epic is missing some crazy little QOL things they could add to Blueprinting that would resolve a heck of a lot quirky workarounds, but anyway. It took them long enough to add in the OnControllerChanged which is huge for me and my use cases. But that's about it. We don't get much else lol.
So.. It's like literally every other engine feature that isn't at least a decade old? 🙃 Fine if you just fix it.
It is faster and better than the old system, that's at least true.
The one part that I think was a big mistake was making serializers so absurdly overkill... They really could use a dumbed-down simplified API to help with serializing things that you don't need the speed with
The idea is that you shouldn't need them in the first place.
yeah but this is marked experimental still afaik so it's not exactly like they are misrepresenting it
fun fact: it doesn't support replays but you can actually run Iris and replays at the same time
with some small fixes to some default types it actually works
yes, 99% of the time you do not but inevitably your game will have something that can't just be a member bitset
NPP enters the room.
Just so you know, when peeps tried to PR changes into the Engine that exposed better versions of the 4 shitty little Session nodes that exist in UE, they were told to move it to a Plugin instead and handle it within the Community. That's been a long while, but that should give you an idea why BPs didn't get much new stuff in terms of Multiplayer features.
wait tf?
Yop, that's why the Advanced Sessions plugin exists.
NPP was made a fair bit before Iris came along at least
Why they do that. lol
Probably cause they don't want peeps to use Sessions in Blueprints, or rather they don't want to maintain support for it.
Yeah
NPP could probably change to use a polymorphicstructserializer but I am going to be honest and say those things are just insanely annoying to make work well even if they saved a lot of bits
worth it long term though
We do have a Serializer for NPP on the current project. But I didn't write that and I haven't had the joy of looking at it yet.
basically they are like an instanced struct serializer but ONLY for a subset of types, so it can avoid sending as many bits for what type it is
An Iris one that is.
Also there is that many plugins anyway on the Fab store that give blueprinters QOL anyway. Just have to buy them which is fine. I don't mind paying for someone's work to give us what Epic won't.
I saw a Plugin that makes global dispatcher listeners or something. Cool as. Don't know if it's optimized but I mean, no hard references.
"Global Dispatcher" is something you can easily make yourself fwiw.
serializers are not complicated to write at the bit level... most of the really crazy gigabrain stuff is done for you and 90% of custom ones are just a tree of bits
the complex part is making it work with the boilerplate of whatever you are dealing with and the occasional thing that breaks them imo
How would one do so?
Create them in whatever you consider the most global.
the one missing BP thing that pisses me off the most is probably no array sorting... Why not make that a native node??
Your GameState, or fwiw even your GameInstance, as long as that doesn't store any gameplay data.
Also, those marketplace asset kits like Survival Game Kit etc being fully blueprinted with every system of a survival game actually working. Cool. But as soon as you do some lag simulation with the Client Emulation settings. Things are borked beyond anything. Nothing works. The weapons / tools are completely server sided including the animations so you get input delay depending on how bad the ping is of course. These kits are up in the $$$. Definitely should be just marked as singleplayer only. Multiplayer kits like that just aren't it and aren't done right tbh.
a game state component, game mode comp (server only) etc
BP has no subsystems but you can still make something almost identical
Yop, Blueprint Projects on the Marketplace/FAB are a gamble. A lot of people made these and still make them, who learned there stuff from bad Blueprint Tutorials online and think whatever they are doing is correct, causing more wrong information to be spread.
fwiw, the C++ stuff online isn't necessarily better.
Did they ever fix that weird little license thing with code things on FAB?
yeah this is something that would not get much different if they were made in C++ imo... making good netcode is just hard either way
Seeing actual Steam Games pop up here and there over time that actually use the Survival Game Kit without changing anything but having their own level assets of course for the environment. It's terrrrrrrrible.
I get so annoyed whenever I see ALS animations used raw in the wild
ShooterGame.exe
ARK 😄
but tbh they work pretty well so I don't blame people, it's just me noticing because I have seen them
There was some weird wording on FAB that implied not so lightly that anything that contained code wouldn't be allowed to be released with a finished product.
Still saddens me how bad ARK got in the end. Could've been gold.
Now that they "remastered" their game to UE5.5 (ASA) we got ourselves Nanite everything (This includes the trees and grass and bushes mind you.)
and we have ourselves the same ShooterGame project that's full of crap.
Yeah. Everyone knows ARK as ShooterGame forever.
What's worse is, the game even uses the actual ShooterGame weapon system that is so badly netcoded still. Even in the remaster. The desyncs, everything.
ARK makes me incredibly sick now that I know UE better. :/ I used to love that game. Now I just get insanely pissed off when my game freezes for 30 seconds when I'm swimming to the underwater cave. And when I add a new area DLC it takes up 50 gigs per map.
I haven't played ASA though. Probably won't.
I've played and modded ARK since 2016. I have recently "retired" from modding ARK about 6 months ago.
Just be happy you haven''t seen their blueprints. You don't wanna know.
Their Human Anim BP alone is like the size of Las Vegas.
I could now. But before I couldn't even load their editor on 16gb of ram many thousands of years ago.
Their ASA Dev Kit is 950GB in size to download on the EGL.
Anyone want 8k textures for tree bark ? 😄
Copied for each and every map probably too.
Yeah their folders are messy, and they do indeed copy paste the same asset sometimes to some of the other maps, than just changing the materials.
ARK uses some of the marketplace assets too in ASA. Which they didn't do before in ASE.
Ultra Dynamic Sky.
Fluid Ninja
Blueprint Assist and a few others...
in some ways this is probably to combat stuff being changed from underneath them
Ultra Dynamic Sky looks great but man the BP is a bit on the heavy side
Yeah UDS is used widely across many games tbh.
that said it's simple to open it up and just cut out bits you don't use
and I'm not sure what I would do to replace how it works... I am not tech artist
Which would be fine. But like on the old game, you literally needed 500gb of space to house the game files. And this was years ago. You just can't do that kind of flagrant abuse of art assets.
Yeah that degree of asset spam makes me think they never audit it
And it isn't like a normal open world. It isn't a city with lots of different textures for posters and signs and stuff. The same trees and rocks are used through a whole map. The same dinos with a few skin variations are scattered around. It's just art asset abuse to the max.
Another thing that Blueprint doesn't have is replicated UObjects. Which is what ARK uses for items in inventories and stuff.
There is a plugin on FAB for UObject Replication in blueprints which will allow being able to use Objects to do stuff with for items in inventories in multiplayer. That's neat.
The best part of that is that it could be a checkbox in the object class, or a function override, with the add replicated subobjects functions being BP exposed.
Yet again such a simple thing to offer Blueprinters like me for sure.
Just like the Project Settings like Getting the Project Version. Which we cannot do either .-.
If i want to make a 4 player multiplayer game and then later add local play on which net mode and game mode should i be testing?
test as listen server + client with network emulation on from the start
assuming listen server is the model you're going for, dedicated is fine too
basically unless you are making an online game with dedicated servers you probably want a listen server
this means one player is both playing and the server
listen lets you get the server's view of the game which is sometimes helpful. Properly architected code can run in every configuration with no problem.
Do you mean local multiplayer like split screen or BG3?
or just single player
Will there ever be 2 players at one machine
Does anyone have experience using unreal’s default voice chat implementation through IOnlineSubsystem, FVoiceImpl and the functions in the player controller? I’m really confused why there’s no parameters in that class to modify the audio input device
I see a way to do it but it would require me to get a custom fork of the engine
My inspiration is BOPL battle but 3d and for now I want to make it an online game for 4 players but later I also want to make it local but I'm not sure if 3-4 splitscrens would be too cursed to play
Maybe I'm gonna drop out the whole idea for local play so I guess I'd want an answer for that
I'd only do local if it can be done without splitting the screen
looks like the original BOPL could but idk about in 3d
Ye it's not gonna happen 3d local split screen
What settings should I use still
For online 4p
Max
Just the way the engine is
test with listen server or dedicated depending on what you're targetting, probably listen though
so like, if you were to have bps in anim graph vs bps in a blueprint graph, are the anim graph bps running slower? Or are you just talking about overhead costs
Mainly talking about the BP Graph of the AnimBP.
I see
ya'lls discussion inspired me to go into my animBP and just start trying to cut out as much unessesary gunk as possible lol
should i check "launch separate (dedicated) server" on?
What is the best way to uniquely ID each client in a game? I know that this exists
/** Gets the literal value of UniqueId. */
const FUniqueNetIdRepl& GetUniqueId() const
{
return UniqueId;
}
But how reliable is it + I dont really understand its whole V1 and V2 stuff, I assume V2 should always be used right? But it returns this using FAccountId = TOnlineId<OnlineIdHandleTags::FAccount>;
So is this going to identify each player globally uniquely or just per session?
I was considering just a simple ++NextID on when the game mode creatures clients on login... Seems much simpler but I wish to understand the FUniqueNetIdRepl workflow
Okay after doing some more digging I see player state has TWO unique IDs, UniqueId and UniquePlayerID.
UniquePlayerID is just a static constantly incrementing counter I see, shouldn't they have made this a AGameSession value over using a static.
Anyway now I am even more confused on which to use when. I assume UniquePlayerID is what I would use for general gameplay identification/distinctions but then what is UniqueId for exactly?
int32 AGameSession::GetNextPlayerID()
{
// Start at 256, because 255 is special (means all team for some UT Emote stuff)
static constexpr int32 MinPlayerId = 256;
static constexpr int32 MaxPlayerId = TNumericLimits<int32>::Max() - 1;
static int32 NextPlayerID = MinPlayerId;
// Prevent possible integer overflow by wrapping the value to the max player ID
if (NextPlayerID >= MaxPlayerId)
{
UE_LOG(LogGameSession, Warning, TEXT("AGameSession::GetNextPlayerID had to wrap the Player ID, this probably shouldn't have happened. PlayerID collisions may occur! Is this function being called incorrectly in a loop?"));
NextPlayerID = MinPlayerId;
}
return NextPlayerID++;
}
void AGameSession::RegisterPlayer(APlayerController* NewPlayer, const FUniqueNetIdRepl& UniqueId, bool bWasFromInvite)
{
if (NewPlayer != NULL)
{
// Set the player's ID.
check(NewPlayer->PlayerState);
NewPlayer->PlayerState->SetPlayerId(GetNextPlayerID());
NewPlayer->PlayerState->SetUniqueId(UniqueId);
NewPlayer->PlayerState->RegisterPlayerWithSession(bWasFromInvite);
}
}
So from reading this function (Please correct me if I am wrong someone)
FUniqueNetIdRepl UniqueId - Platform specific globally unique identifier for a player, can be used for bans or block lists etc
PlayerId - Session based unique identifier associated with the player state
Now if that is true what happens if a client disconnects and reconnects? I know old player states are kept for a certain amount of time after a disconnect in case they reconnect but if they take too long then the player id should differ but the uniqueid should be the same?
/**
* Retrieves this player's unique net ID from the online subsystem using the platform user Id
*
* @return unique Id associated with this player
*/
ENGINE_API virtual FUniqueNetIdRepl GetUniqueNetIdForPlatformUser() const;
Doesn't matter
why? chat gpt says it does and i need to turn it on
Chat gpt is wrong all the time.
Why would a separate window for the server (vs it being in background) matter at all?
Daily reminder that ChatGPT is garbage and you should never trust it.
I don't understand multiplayer so idk
In case this isn't clear. That whole "Unique ID" and "Uniquely Identify a Player globally across games." only works if you have an OnlineSubsystem enabled that supports that. UE, by default, has no way of doing this.
You need Steam, EOS or something similar to have unique IDs.
Once one of those is enabled (if it's supported by UE), that UniqueNetId will usually be the given Subsystem's Unique Id E.g. the SteamId of the player.
That PlayerId (int32) is only relevant per session and also only if the Player doesn't leave for too long (+- whatever you set up for the Inactive PlayerState).
The UniqueNetId should remain the same (with what I wrote above).
Perfect thanks for confirming.
One last question, kind of related to Identifying things. Do you have any experience with a Build ID? As in I want some unique GUID that differs from release version to release version
BuildIds should already be unique in theory.
is there any available dev that can help me out that dont mind making some money lol
please IM me
You're better off actually describing what you want help with otherwise you'd be wasting people's time and your own if they can't help you with your issue, and by just posting what you want help with here could result in the help being completely free.
If you're adamant about wanting to hire someone #instructions has information on how to post a job offer which would at least then be visible to those actually looking for work, but I'd still recommend putting what you need help with in your posting.
@sinful tree Makes sense thank you.
I need help.. My Preview character in my inventory disappears after attaching an Item..
Does anyone know how to deal with that spring arm rotation lag on a client jitters? I have a flashlight attached to it and thats the issue
erm code?
i think i need to see your RPC calls to undetsnad whats going on
what kind of jitter are you referring to
if i have to ill post a video but basically I have spring arms with rotation lag for a more immersive flashlight effect but when on the client the rotations lag around which I presume is some sort of sever correction
you are RPCing wrong, your shoud spawn on the actor with multicast then call the multicast on the server
you are basically spawning two different actors
gotcha Ill see if it solves my issue
tbh im not sure thats whats causing it to disappear but you def do need to change that
I fixed that part..
I think the disapearing part has somthing to do with when I create a new render target
if i had to guess id say at somepoint the data for the refrennce youre trying to plug in to spawn the armor is returning null thus the invisibilty
its like pipes, its all gotta be hooked up between to properly flow from point a to b.
I would try to inspect the stuff actually in the render target if possible
I'm not sure what the nicest way to do that is. It might be interesting to have this object exist in the regular world to inspect directly
make sure you select the right world in the outliner options etc
I got it figured out
what did it ened up being?
It depends on how the rotation is sent over and obtained
if you are using getviewrotation etc
it can change depending on if they are locally viewed
fair enough
only thing is now the preview character is not animating whenever I equip an item
I have no idea what equipping an item means here I guess
There are a number of reasons something could not be animating from just not having an anim bp setup or something fooling unreal into thinking it isn't in the view bounds
Gotcha yeah I have no clue.. I do know every time I open the inventory it spawns a new preview character so I'm having multiple characters.. Think that's part of the issue..
You might have to be careful with cleaning up the old one or just changing meshes on it
none of its my code, the spring arm has its own rotation lag feature built in
yeah, I'm not talking about the spring arm
I'm talking about how the spring arm chooses the direction it should be facing
i dont even want any of it networked
I assumed this was the view rotation of sim proxies from your description
But is this the local player getting corrected?
yes exactly
I kind of thought client corrections were purely location/velocity only
I am wondering why the location affects the smoothing of the flashlight I guess
without seeing the math involved or how anything is attached I am not sure what to say
ill go back in ue5 later and ping you
looks like something else is setting the rotation on top
maybe but of host its works fine
not sure what you mean
I am saying I want to see what rotation the light is trying to follow in realtime
unless you want me to guess
It is not reasonable to solve this problem without seeing the actual things happening
in inherits the rotations of the parent socket based on its relative rotation and updates them in the post physics tick group
curious if bUsePawnControlRotation changes this
the bool turns the light backwards
then change the relative rotation to face the other way I guess
yea its still happening
and i have a funky thing i did where my camera follows control rotation or something, i made it like a year ago so i dont know how it works lol
idk worst comes to worst Ill just disable the lag and have a boring flashlight
ok i fixed by parenting it to the capsule instead
i have a system where when the players join the game they are in a UI. in this state, i add each player controller to an array of player controllers until the game starts. the problem is when assigning a team (done through a server rpc + replicated variable) and i press start, the team and color for each player is somehow set back to default (Red) but once they spawn in and posses the pawn and i press a keybind to call the same function im calling in the gamemode (GetTeam) it shows the proper team.
its important to know the team before spawning so i know where to spawn them. any help appreciated thanks!
tldr: not showing proper team until after pawn is possessed and the game has started
in my gamemode
ICustomTeamInterface::Execute_GetTeam(customPS, TeamNameEnum, TeamColor);
FString TeamTagString = StaticEnum<ETeam>()->GetNameStringByValue((int64)TeamNameEnum);
FString msg = FString::Printf(TEXT("Player ID: %d, Team: %s"), customPS->GetPlayerId(), *TeamTagString);
(replicated variables)
UPROPERTY(BlueprintReadWrite, EditAnywhere, Replicated, Category = "Team")
ETeam TeamName;
onrep it so you know when it actually shows up
no
Spawning a replicated actor on server only is correct
just curious, have anyone managed to send over 950kb/s constantly?
Anyone else having mover 2.0 + chaos mover crash on 5.6
that sounds like a rediculous amount of data, what is it?
Bump
OnRep like Megafunk said
on rep do what? Just see if it’s updating ?
so you know WHEN it updates
so stuff that depends on it can update
Does anyone have any really good ressources to recommend me for learning how to make multiplayer games, blueprints or c++ it doesnt matter. I want to start and I have been looking at yt tutorials and udemy courses but I dont know which ones are good.
Udemy courses are not good - especially in C++. I tried one, cannot recommend 😏
If you don't know Blueprints or C++, then I would really advice you to WAIT with multiplayer until you understand the basics of how the engine works. Multiplayer is just another deep level of complexity
I did the Tom Looman course on professional C++ game dev course (whatever it's called) - that was really helpful!
Sorry, I really should've given more context to my message and thanks for responding, I have a very good programming base with blueprints in UE5 and can make lots of blueprint systems(no c++ though) such as building/crafting/inventory/combat/AI, anything really, so I feel ready to start tackling multiplayer and actually c++, I want to learn that as well.
Can you give me a link to that course please so I can check it out?
Hey guys, first time posting in this section since I just started developing a small coop game with my friends.
Going straight to the question. We want to be able to playtest our work and have decided that for now we will be using the Steam Online System. I have followed a tutorial and I can test things locally which so far so good. But once I package the game and try to use vpn's on multiple pc's I can see the lobby/server I have created but unfortunately I cannot join. Are there any limitations or better ways to make that happen or the bandwith is terrible of the free Steam servers(Talking about app id 480).
If anyone has experience with those things please come forward as I am completely lost and I have no clue what to refer to, thanks in advance!
just google for Tom Looman - you will find his website 😉
As a sidenote - you can make multiplayer in Blueprints, but I would advice against it
You can use the Null Online Subsystem and run everything locally in LAN. Ofc that means no online play, so you need to be in the same physical place.
Don't know anything about VPNs
Yeah, LAN works flawlessly. Whole idea was if we can test with my team on an online server without the need for such things as all of us live in different countries. Does the Epic Online Subsystem have better support or 🤔
so for some reason it triggers TWICE when the server does it. when the clients do it nothing happens
this funciton is called whenever a player is setting their team.
void ACustomPlayerState::SetTeam_Implementation(ETeam NewTeamName, FLinearColor NewTeamColor)
{
TeamName = NewTeamName;
TeamColor = NewTeamColor;
}
any ideas why this isn't working?
you cant do replication or rpc's through widgets.. get those clicked events to go through the player controller class
can i make the server rpc in the player state?
then call the server rpc from the widget?
yup
thanks
no problem
is there some delay issue going on?
if i press blue it prints red, but if i press blue again it presses blue
note red is default
its like first click never registers, only second click.
if i press blue twice it prints red blue
then, if i press green twice it prints blue green
then if i press red twice it prints green red
its like it gets stuck on the old one then updates.
anyone know why this is happening?
RPCs don't happen instantly.
thats the problem im aware but how can i fix this?
There's nothing to fix. There is always a delay between when you send an RPC and when the value will change. Use Rep w/Notify variables if you want to do something when a new value is received.
why is on rep being called 4 times when a player presses the button once?
0 means red, 1 means blue, 2 means green
so its receiving the right change on the first click as we can see its printing"1"
i just dont get why that happens 4 times
3 clients plus server?
2 clients + server
Show the code path from the button click all the way to whenever you're printing this thing.
in my playerstate
button code
void ACustomPlayerState::SetTeam_Implementation(ETeam NewTeamName, FLinearColor NewTeamColor)
{
TeamName = NewTeamName;
TeamColor = NewTeamColor;
}
void ACustomPlayerState::OnRep_TeamName()
{
UE_LOG(LogTemp, Warning, TEXT("OnRep_TeamName triggered: %d"), static_cast<int32>(TeamName));
}
set team function
i understand why the print is wrong, i just dont get why on rep is happening 4 times
how long would i need to delay here to make it print properly?
you can't know how long it will be before the value is received. this is why you use the onrep.
oh ur saying print the message in the on rep
i forgot thats the whole point of the on rep lol
thanks
okay question:
the server rpc is changing the variables (blueprints) , which triggers my on rep (c++). does this run on server + all clients?
You gotta manually call the onrep function in c++ for the server. BP onreps fire on server too
so why is this printing 4 times
void ACustomPlayerState::OnRep_TeamName()
{
FString TeamTagString = StaticEnum<ETeam>()->GetNameStringByValue((int64)TeamName);
FString msg = FString::Printf(TEXT("Team: %s"),*TeamTagString);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, msg);
UE_LOG(LogTemp, Warning, TEXT("OnRep_TeamName triggered: %d"), static_cast<int32>(TeamName));
}
BP onreps are really just OnChanged
It should print once for each client in the game. You appear to be setting another value for the team color as well in your SetTeam function - are you doing a print in the onrep for that value too?
its a different print message
when i have 2 players (client + server) it prints twice
when i have 3 players (client + client + server) it prints 4 times
when i have 4 players (client + client + client + server) it prints 6 times
Which is why I'm asking about the other print message. That behavior is more like two values changing as you're getting two prints per client (server wouldn't print unless OnRep is manually called)
Breakpoint it
i have nothing else that adds to screen
my onrep team color just logs
also not sure why this is happening but for some reason 4 characters are spawning in
this is where i spawn each actor
its spawning the server client in wrong im not sure why but how am i supposed to handle spawning in the server-client instance differently?
i only spawn in 3 actors for 3 controllers, where else would it spawn in a 4th actor that has no controller?
Show the code that's spawning pawns
It’s in my game mode function spawn player for controller which only runs 3 times
Added a debug at the top. So it’s spawning it in somewhere else so I’m trying to ask where else it might happen
An overview of the essential concepts for writing multiplayer game code in Unreal, in under 25
minutes or your money back.
Sample project: https://github.com/awforsythe/Repsi/
Patreon: https://patreon.com/alexforsythe
Twitter: https://twitter.com/alexforsythe
00:00 - Introduction
01:24 - Net Mode
03:33 - Replication System Basics
05:13 - Acto...
The best video
GameMode has "SpawnDefaultPawnFor" which gets called that ends up spawning pawns for players that join the game, but if you have custom implementations of things, it can change how GameMode works.
I've seen that
This video + the compendium is pretty much all you need.
Compendium?
This compendium is meant to give you a good start into multiplayer programming for Unreal Engine.
rts. thought it's still below 1mb/s though, and around 0.1mB/s too.
Tysm
What
I'm not an expert on big data transfers but we're doing an RTS and generally speaking that sounds crazy, what kind of game and system are you pushing?
Sounds like an RTS with everyone being ACharacter
i have over 10,000 units rts all that over 700kb/s up to 950kb/s on estimate
wrong. i don't even use ACharacter at all.
how deterministic is it?
Ideally an RTS should just rely on synced inputs, then you can effectively have infinite units as all that'd need to cross the net is the commands. Hard to do though.
is there a common function for creating a randomized ID / string to keep track of specific actors? specficially am trying to create an 'active game' id that would be associated the game players are currently in , so i can check against this later, would be much easier than what im currenlty doing
almost impossible in Unreal without doing a parallel engine like Stormgate did
I don't think it's viable in that way. How did you get those numbers?
kill me xD Only CMC CPU cost won't be viable
Alright wanted to run this by some folks cause I'm a bit at a loss. Basically I have a GameFeatureAction for Spawning Actors that I'm working on. However, in a networked environment the actor I'm spawning is not replicating to clients and exists purely on the server (because that's where I'm trying to spawn it given this is a networked game). For reference, I know for a fact this actor would replicate normally if I spawned it during the regular flow of gameplay.
I imagine it has something to do about the timing of the game feature action and when it's executed, but I'm not sure when the actor spawning needs to be delayed to in order to have it get picked up for normal replication. Anyone have any thoughts?
If it must be unique per actor, then you can use GUID, but I'm not sure how helpful that would be for an "active game id".
If the actor is spawned by the server and the actor is marked for replication, then it should be getting replicated to clients that would have the actor relevant.
The only way that I can think of it not happening is if you're spawning it in a separate world, or if you're spawning it then changing levels.
What does this ID represent, an instance of the world on a server?
You can just have GameState cook up a GUID
not quite that , but an actor that gets spawned by the gamestate that handles it's own rules / tracking for it's own "minigame". so there could be many happening int ehory, but actually not really THAT many, so i could probably maintain / manage them by an index even but yea was thinking of something i could attach to each of the game's so that they could have something specific that would be separete about them.. but i did also realize after postwing that i would in fact have that type of thing by the host / player that intigated the creation of the game's epic id so that is stored and could be checked for to ensure it's the same game
Whatever the thing is that there is 1 of per minigame instance, that thing can cook up a GUID
Alright well here's what's even weirder... If I delay a spawn of an actor on my gamemode like 20-30s the same issue is happening. So something seems like it may be borked on my project 🥲
Oh weird... Getting this in my logs? UActorChannel::ProcessBunch: ReadContentBlockPayload failed to find/create ACTOR
Could it be that the feature isn't loaded on the client?
If the class is provided by the feature, I would assume the client has to load it too
Alas it's a class that's defined in my base game that the feature was just referencing. Doing a full engine recompile cause of the weirdness even when just spawning in something normally through my gamemode
I really cant tell what ive done wrong here. When I pickup ammo as the client player it adds that ammo to the server player ammo pool. Anyone see the error or is the error most likely somewhere else? The actor is replicated as is the ammo variable.
Not sure what the error that you’re trying to fix is. What do you mean by server players? Given that it’s a repnotify you have I’d typically only do that on the server and that repnotify would give the client the info upon being set
Sorry my listen server, Im referring to the listen server. Also server player singular, typo
The listen server can do whatever they want
They're the server
Replication will have no impact for a listen server host
Ok yeah I understand that but the ammo is only being added to the listen server's player
well this is executing on the overlapping player
what does OnRep_LightAmmo do in BP_Player_Character?
because I'm wondering how you're verifying this information
"Other Actor" on the event will be the actor that caused the overlap, not just a generic host player
I got a print string that tells me the ammo count of whatever player I shoot a bullet from. And my onrep_Light Ammo does nothing in my bp_player_character
Sliding in my own question: how can I ensure all players involved in a particular match get an event to countdown and start at the same time? My current logic is done via looping through the connected pawns in that match and sending them as client rpc to each pawn.
Assuming there’s another way to give all the players this info at once. I have a variable that I could wait for which gets set “all ready” which is true after all players are ready up. This could be the variable that triggers the event but still can only think to loop through the pawns that are connected to get the countdown to start. And tbh the four each loop isn’t terrible is only like a split second off but not ideal if there’s a better solution
yeah im aware of this which is why im so confused, like I have no idea what could be causing this issue
might post on forums idk
and the print string logic is?
This logic is in the child of my core weapon
the good old note telling you about the redundant cast
and is the "as BP player character" variable correctly set?
I know lmao but im just trying to access the light ammo variable
well you don't need to cast if it already is the thing
the light ammo is stored in the player bp not the child weapon
thats the as bp player character variable
I'm not sure why you don't understand that's a redundant cast
yeah I understand now oops
I can just grab it from the variable
still got the core issue though
what BP am I looking at, the weapon?
because the "light ammo" variable on the weapon is not the same variable as "light ammo" on the character
the weapon doesnt have a light ammo variable, it grabs it from the player
then why is target "self" on it
and what callstack are we talking about here. is it actually the correct instance of the weapon and is "as BP player character" set correctly?
and can you confidently say "yes" to both?
I can pretty confidently say that the correct weapon is being called but not the "as bp player character"
then where is that set? I couldn't help but notice it's not replicated
this is a function in the bp_player_character
and walking up the stack, what calls "setup weapon"
this is triggered by this, also in player bp
if this is getting too much for you tap out any time its fine, I understand
child actor component, cursed
im coming to understand that lmao
Bumping this
IsLocalPlayerController() is there any equivalent function in PlayerState?
guess which actor owns the playerstate
omg.. I will leave it there in case someone else thinks about asking such a dumb question
<turns off UnrealEngine in shame>
What happens if they join their own session? o_O
i have probably a stupid question since i dont know much about multiplayer. how hard would it be to make peer2peer in blueprint for a 1v1 game? as in, the only thing my server would do is matchmake and link one ip to the other and theyd communicate to each other directly instead of my server
UE doesn't support Peer2Peer. So it would be very hard :P
UE only supports ListenServer, so one player being the Server and Client at the same time, and DedicatedServer, so a headless Server, where Clients join to.
that would work, thanks
What's the game?
some space dogfighting game i wanna work on, nothing super special
Depending on how twitchy it gotta be it'll range from insanely hard to not that hard
if you want simple physics replication I've done a good bit of that, spaceships won't be hard. Predicting is what makes it hard.
fair enough
I'm running into some problems where it seems like PlayerState cannot update replicated variables on other machines or issue Multicast RPCs when these updates are happening from clients - is that normal behavior?
My example is PlayerName which is replicated fine from server to other clients.
But it's not replicated from clients to other clients or from clients to the server.
For reasons I need to write to the replicated variable locally on each machine and then rely on replication. But replication never happens from clients to other machines.
Also when I NetMulticast from a client the call is NEVER received on other machines.
This is all post-BeginPlay().
Am I doing something wrong?
Replication doesn't happen from clients to other machines. Replication only happens from server->clients. Server RPCs (Run on server) can only be executed on the owning client. Client RPCS (Run On Client) will only run on the owning client, multicasts can only be called from server and will execute on all who have the actor relevant..
Interesting. Is that the same case for PlayerControllers?
I'm running a ListenServer model, so I was assuming it would just work fine.
But yes, I replaced it with a Server RPC from the client to request changing the PlayerName, and the server then sends the name string back to the client - it seems a little backwards because the client already knows its own name.
everything
your only communication channel from a client to server is a Run On Server Event in some actor the client owns
That's the case with all replicated actors.
PlayerControllers only replicate out to the owning client, no other clients receive them, so you can't reference them across all clients.
typcially pawn or playercontroller
So as a general case, clients cannot just update replicated properties.
And clients cannot just issue Multicast RPCs?
Just making sure I understand this right. And thank you for the help!
Clients can change any properties locally but they won't be sent out to the server or to others, and yes, multicast is strictly executed by the server.
Makes sense, thanks!
Read the Compendium please
These are basics that are written down for the sake of not having to repeat them
The compendium is pinned to this channel
I believe I'm seeing a much larger than expected network cost for first time replication of an array using fast array replication (when a new client joins, and has to get the entire array). Is there a known large up front cost for first time fast array replication besides just the size of the array?
You should see the same upfront cost even if it was a simple TArray.
The Client has to get all of the current data in order to start syncing properly from then on.
Interesting, it's possible that I'm reading the Network Profiler wrong, thanks
I did some network profiling for my game and I found that my creatures are eating up a lot of bandwidth just replicating their movement. Is there a standard way to reduce that?
Reducing their update rate frequency or culling distant ones could help
Could also reduce their quantization level in their movement replication to not use as much detail
Should I reduce the update frequency globally or is there some strategy to modulating it?
Quantization detail seems promising.
Both depending on need
As for how to reduce quality based on distance I am not sure because there are a bunch of legacy and newer things that do the same thing
The ideal setup is things near the player's view are higher than ones very far away
Iris uses prioritizers and the old setup is repgraph or something
I forget
Can quality be updated per-client?
Quality of what?
Frequency, sorry.
I'm looking at Repgraph documentation right now. It seems like it's just binary Update or Not, right? Or can groups have different frequencies?
Also repgraph is being deprecated with iris
Just to be clear
Not a big rush there as doing the same thing with prioritization is definitely doable later
I'm working in 4.27 so that's okay.
@nova wasp Is it considered acceptable to dynamically adjust replication frequency and quantization at runtime? Are there examples of best practices?
@left marsh There is nothing wrong with adjusting things like NetUpdateFrequency at runtime.
You can also use things like Dormancy etc to aid in reducing overhead.
Dormancy? I'll look it up.
Yes, you will want to learn and use Dormancy where ever you can.
In my project, I have a large number of creatures that will spawn and be killed frequently.
You might also want to learn about TearOff
I've used tear off, thankfully.
Just something I remembered, I vaugely feel like Dormancy isn't useful or disabled when you are using RepGraph.
You might want to check that.
It depends if the local reading onreps expect the change... I would say try to not change it if possible
Frequency can be per connection but per connection serialization is very difficult I think
In respect to this
It's technically sent but I've seen issues with replays assuming the wrong level
This may be a tough one to answer. Unsure.
I know that Functions do not have the ability to have their own replication settings. Only Custom Events do.
But I saw something where you can copy the Custom Event UI code over to the function UI Code in the Engine Source and you can make working replicated functions just like Custom Events. Now that sounds and looks a lot cleaner for graphs and many could benefit from it. But I wonder what drawbacks or issues this may cause. If none, why wouldn't Unreal provide us the option to have replicating functions?
Purely just asking. I ain't doing this lol. But it sounds nice to have replicating functions.
You must be referencing in regards to Blueprint?
I sure am 🙂
The reason is that RPCs cannot have return values.
Functions can return values. Therefore they cannot be RPCs
Events have no return value and so are suitable as RPCs
Ahhhhhhhh. That clears it up.
If you were using C++ you would come to realize this on your own.
In C++ functions are the same as Events.
The ARK Dev Kit actually has replicating Functions built into it. I just learnt this now lol. They apparently work.
RPCs in C++ are just functions
The only reason why they might have done this is to allow those functions to be marked as protected or private
Beyond that I have no idea why they would have made functions in BP be able to be RPCs
Outside of also supporting return types
Actually. You might be on the money. None of the graphs ARK has used replicated functions. Nowhere at all. So I'd say they just use those protected and private toggles from the same UI. Makes sense that way.
I would imagine any RPC with a return type would have to incur a second RPC to send back the result.
Thought I'd ask anyhow. Seems like replicating functions could be so nice. But logically yeah. Makes no sense to.
UE5 I believe allows you to mark Events with access modifiers (protected etc).
So thats not really an excuse anymore
Tbh, BPs have tons of usages for functions where you have to configure them a certain way for them to work. E.g. widget bindings.
The return value is no real reason for functions to not be able to be RPCs
Marking a function as one can just remove the return param and disable the option.
But heeeey
Well in terms of understanding the result of that would be confusing.
But I get your point
BP does a lot of weird things without you knowing or making it obvious
I mean, CustomEvents and the EventGraph are already a confusing concept
Given c++ doesn't have such a setup
The fact that Widget BPs still allow you to set the replication of variables is another funny one
lol
Epic protects BP users from being confused there but half the other stuff in Blueprints is technical enough that you gotta know c++ to not break shit
Or the GameMode. But they gotta keep their lobby tutorial alive somehow
I find it silly that they still use that excuse, when there are so many examples of that being broken or ignored.
I think it would be fair having function RPCs as an alternative
Especially with clean graphs in mind
I might have a look at that
Things like local variable support would be nice in those instances
Yeah. The only other thing that would be nice with functions is having latent nodes automatically provide binding pins when used in functions. But that's a bit more complex
So it's definitely possible to have Functions replicate then? From what I am gathering here? LOL.
I don't know if someone can make a plugin and give this option to blueprinters. (I don't know if that's how it works) It frees up the Event Graph a lot more that's for sure.
Probably a bit more involved than what a Plugin could manage to add. Meaning, it probably needs source code changes.
As I said earlier, in C++, RPCs are just functions.
It was purely a design choice to not allow BP functions to support RPCs.
Yeah. Interesting. I feel it would make graphing so much cleaner is all. But oh well. Worth asking and getting an answer on it ! 🙂
Thanks for your inputs!
I've done it.
Thankfully legit no other issues.
Other then the previously mentioned return values, but I also knew that.
Is it possible to make a actor not replicate its attached parent?
You could use a DOREPLIFETIME_ACTIVE_OVERRIDE
You can toggle the replication of specific properties using that Macro inside of PreReplication
oooh
Thanks
The fact you've managed to get replicating functions is cool lol. But yeah, not being able to use return values makes sense as stated above.
Imagine that
how would the return value work? as a handle to a delegate of the returnvalue?
that's kind of a neat idea though, I think that could be useful
lots of things are just client > server -> and back
Sounds like a logical approach.
Whatever pattern is reasonably appropriate for any asynchronous system would work I would think.
Basically just an async call
Except your waiting on a network packet return instead of a thread return.
I feel like this is something that most backend server libraries have built in
promises etc
I could swear I've seen a similar pattern before
Have it a dropdown or a checkbox to enable this on a Function.
When it's selected/checked, create a new Function in the same class automatically (OnRep is already doing that), flag it has a response RPC and lock the Inputs to the Outputs of the other functions.
This shouldn't be impossible. It ain't going to be pretty either. This was a bit of a joke tbh.
In C++ it could be marked with a simple ResponseRPC = TheOtherRPC, similar to ReplicatedUsing = ...
Code generation can check if the input of "TheOtherRPC" fits the return and OutParams of the main RPC.
But tbh, this is probably overkill and again mostly a joke.
Having functions as RPCs in Blueprints would, however, be neat.
guys i call this but my Event Damage on another player is never called even i damage it why?
when I play as server its okay
but when as client i cant destroy him
when i debug this one is called only if i destroy it like server
if i try destroy it aas client this one is never called
my guess would be that the player doesn't own the object it's trying to call the RPC on
usually damage is done purely server side and the only reason for a client to send a damage RPC like that is to verify a hit
Hello,
Trying to confirm what I've been reading and researching about Dormant actors 🙂
1- Setting Dormancy to Initial means the actor when spawned or when a client joins will replicate everything once and then stay Dormant
2- For both BP and C++ before editing a replicated variable I need to wake the actor (must be in server context) using FlushNetDormancy
3- For both BP and C++ before calling a Server->Client RPC I need to wake the actor same as variables
4- After doing 2 or 3 I then call ForceNetUpdate to request the change to happen immediately if needed (any cases where this isn't needed?)
5- Client -> Server RPCs work fine even if dormant
6- Making actors dormant will save CPU performance for the server but not remove it entirely there would still be a cost from having the actor replicated in the first place but it's no where near it being awake all the time.
Can anyone help me with replication for my game please? (In vc preferably so i can screenshare)
people usually don't want to get in a VC to help
cause it's easier for you, but 100 times less efficient and waste time for everyone
I think if anyone wanted to help it'd be 100 times easier for both of us because i don't have to explain each blueprint and how i've used black magic to set them up to interact with each other but you're free to have an opinion ig
I see for 5.6 they made quite a few updates for Iris. Is it still something that’s only suggested for large scale projects or could it be used for more small scale games like a close quarters fighting game
Can probably also use it for a smaller game. Just not sure how much gain you get from it.
As long as there’s no downsides to using it for a smaller project I don’t care much for the gains (of course improvements are great, but I understand if there’s not many). It’s more so to learn and have the knowledge for future projects that may be large scale. But this is for a project I will be shipping, so if there are downsides I might as well just wait for a future project to use it
You are free to join a voice channel and ask for help there. But it is indeed rare that someone jumps into voice from a channel here.
You don't really want this to be an RPC. You should limit (Server)RPC usage to the earliest places in your code that are Client driven.
For dealing damage, that is usually the key input that triggers an attack, fires a weapon, or similar.
After that initial ServerRPC you can then stay on the Server and you shouldn't have any problems with that function anymore.
And fyi, having an RPC that passed the Actor and Damage to the Server means that any Client can simply tell the Server to apply damage to another player without a way to confirm that it's actually a valid, non-cheated attack.
Even if you don't care about cheating, you are still blocked by the requirement of ServerRPC needing a owning connection. And the "enemy" you are trying to damage is usually another player, an AI or something else spawned by the Server, and that player calling the RPC usually doesn't own that one. That's why it's failing for you atm.
One of my main concerns is pricing on dedicated server hosting. I see mentions that it’s likely much cheaper to use Iris for large scale projects but unsure if that applies for small scale, if it’s the same, or could even become more expensive
I think there was some gotcha somewhere regarding dormancy at least in the legacy system
where waking actor from dormancy is not entirely free since it has to create its representation state in replication system from scratch, including sending all its replicated properties to all relevant connections
thats why im asking here in the text channel not just randomly going in vcs begging for help
4- After doing 2 or 3 I then call ForceNetUpdate to request the change to happen immediately if needed (any cases where this isn't needed?)
I think that's more about it polling the Actor state in general. If you have an actor that isn't really important, it can be unneeded to force the net update instead of just letting it poll the next time it's up.
You'd need to post information about your problem though.
its multiple problems thats why im asking for vc so i can share lots of information faster
I get it. We are just trying to make sure that you aren't waiting forever, cause "lots of information" and "multiple problems" is something you rarely find someone for (especially for free). We are usually already busy with users sharing little info and one problem.
I would suggest you split this apart and start somewhere at the root of the problem. There will also be a lot more peeps here in this channel that can help you that are simply not willing to join VC (e.g. me).
But you can, of course, also just sit here and wait for a person to go into VC with you. Up to you.
I understand but how can my main problem (which lets say is RPC calls) be split when everything should be connected?
Can anyone explain how Bunches work?
and if everyone says different things on how to approach my problem then they may not work on other actors / components
I have a creature that is sending 2.5k network traffic on spawn, 90% of which is a "bunch"
You could, for example, show an example of where you are struggling with RPC calls. Once that one is cleared and other problems have partially been resolved, you can go to the next problem. Even if that involces RPC calls somewhere else. Members here usually asnwer and explain these things in a way that you usually get the full width of info anyway.
You don't need to cover all your RPC problems in one giant question.
it's still almost definitely cheaper than just having awake actors
apart from maybe the most efficient being having a manager replicate the data and clients just spawn representations
can anyone tell how can i put rifle overlay on default while replicated it seems this way isn't working am using GASP+ALS by Polygon Hive.
What is SendBunchSize? It's taking up most of my network traffic in the profiler when I spawn a new monster.
show the insights trace
Has anyone successfully managed to have Unreal connect to a server without UEngine::Browse, or atleast do the connection before tearing down the existing world
it's always been sucky to be on the same map as the server you're connecting to and you get a massive hitch when browsing for reasons
wondering if this new multi server tech epics working on has some goodies for this
Hi I have a starnge problem and has been stuck at this from last 3 weeks. I have a Car Pawn whose parent class is Wheeled Pawn Class vehicle using VehicleMovementComponent in a multiplayer setup with a dedicated server.
Problem:
When "Replicate Physics to Autonomous Proxy" is OFF:
->Smooth local movement (no jitter)
->But position/rotation goes out of sync between client and server
When "Replicate Physics to Autonomous Proxy" is ON:
->Server and client stay in sync
->But the vehicle jitters badly for the client
It seems that when "Replicate Physics to Autonomous Proxy" is ON server tries to correct client position again and again to keep things in sync that causes jitter. And when its OFF client completely gets out of sync i.e its position on client and on server(including other clients) is also different. Any help will be much appreciated
I actually want smooth motion without any jitters but not at the cost of desync in positions
Insights trace? Like unreal insights? I'll have to check that one.
I've just been looking at netprofiler
also pay attention to the starturp args here
this will not work without them
Isn't that what Beacons are for?
Initial spawning of actor is pretty expensive. It has to send everything including the class.
Any way it can be made cheaper?
No. But if you do it often with the same classes you can consider pooling the actors at the start and then reusing them throughout the game
Morning, I'm looking at a new prototype that has quite specific requirements for character movement. Specifically sections of crawling through narrow, claustrophobic areas. Movement should be restricted based on the orientation and position of key physics bodies representing hips, legs, etc, and respect physics constraints.
A capsule for the player is not going to cut it, so with this in mind does anyone have any recommendations for this? The game is co-op and players should be able to interact with each other too, hence multiplayer considerations.
I tried Mover on a different prototype about 6 months ago but I had a lot of issues so we went for standard CMC move extension, but the requirements for this prototype are more extreme.
CMC is probably the way to go but a bit restricted on the primitive capsule side..if capsule requirement, in engine solution is probbaly going to mover like you mentioned but as of now, mover is not battled tested yet,especially NPP. if for last resport, the GeneralMovementComp from Fab which i've heard great things but cost money.
maybe, you can try manipulate the default capsule to rotate during narrow area?
i know movement through narrow area is possible because ive seen it before but most of what i heard is either impelment the primitives needed themselves or manipulate the capsulecomp to make it work..obviously some collisions issue might happen with lots of primitives
maybe others can chime in or you can try ask some folks in the animation channel
🤔
AFAIK the capsule with CMC cannot be rotated, you can just shrink it down. It needs to be driven by physics I think.
Another alternative is making a new PawnMovementComponent but that would be a ton of work
ah that then i dont know, sorry 😦
??? Anyheads up or a direction i need to look in?
It feels like after some quick testing that whenever I edit a replicated variable on server on an Actor that is set to be Dormant initial it replicates fine in Blueprints without calling FlushNetDormancy so is that different from c++?
Hello everyone!
Has anyone found any workaround with AnimNotifies triggered twice on listen server?
It's still not resolved in 5.4(
I'd be very grateful!!!
NOTE: Please, don't tell me to use DO ONCE or something like that, I mean any real solution, maybe in engine source.
have you tried setting the "Montage Tick Type" to branching point?
but what about actually then joining the map
Have you tried fiddle with the physics replication settings?
Yes but tweaking with physics didn't have much affect. I guess it has something to do with Client or Server authoritative flows. Because when I toggle ON Replicate Physics for Autonomous bodies and Switch OFF replicate movements it somehow stops jittering but gets back to desync issues and vice versa
I also have tried manual replication through code but it also didn't work out as it doesn't resolve the desync issue although it doesn't cause jitters
You nuke the beacon and join the session and map?
Depends a bit on what your goal here is
Seamlessly joining a server with no hitch / net driver tearoff
especially, even if you try connecting to a server, unreal hangs your current net driver
even when it doesn’t connect
Show your current replication settings
Hello everyone! I want to learn about multiplayer in unreal engine 5. Can you please recommend me some material on this topic? thanks for earlier.
Check the pins on this channel. Lots of resources in there.
Okey thank you
Sorry for replying late just reached home. Here's the replication settings currently Replicate Physics to Autonomous is turned OFF so vehicle goes in desync for clients.
This class has VehicleMovementComponent Attached and its parent class is WheeledVehiclePawn.
Physics replication settings in project settings
Dunno if vehicle does anything on its own but it's at least worth looking at them
I've been reading up on this:
https://vorixo.github.io/devtricks/phys-prediction-use/
It looks pretty great, but I see some major bugbears for my use case.
Do you think it'd be possible to formulate something using the predictive resimulation system that uses the outputs (forces and impulses) of my code as the "inputs" as far as physics replication is concerned?
The more I read about it the more I'm starting to think that Predictive Interpolation is what I want. I don't necessarily want to have to do any rollback as the work between your inputs and the resultant physics forces is huge, it could never run inside NPP.
All I want is to let a client get "ahead" of the server a little bit.
I managed to get the insights trace set up. Looks like most of the traffic is "BlueprintGeneratedClass". So if I nativized my class it would be cheaper over the network?
Is there a way I can identify what the "BlueprintGeneratedClass" is meant to be?
i'd assume its the blueprint of the monster you're spawning and having issues with.. do you have any arrays marked for replication or anything that could potentially send lots of data?
though it could be any blueprint, not 100% sure if theres a way to label blueprints for the profiler
The monster I am spawning is present in the insights and labeled. This blueprint generated class is something else.
I'm doing some world streaming using ULevelStreamingDynamic::LoadLevelInstanceBySoftObjectPtr (which is what Valley of the Ancient does from what I can tell) which runs on the clients and the server when certain events happen. However, shortly after running that I'm hitting a persistent check failure in UNetDriver::IsLevelInitializedForActor. Specifically the check is Assertion failed: World == InActor->GetWorld(). Anyone else run into this or have any suggestions as to what I might have to do here?
Anyone know why my actor packets are being filled with blocks of "N/A"?
can you share a screenshot? you can block out names if you want
okay so this is a package map export
what that means is it's sending a stable named package over the network the "huge and slow" the first time
this will happen early on when the server and client negotiate smaller IDs for things
This is a first time I'm spawning this particular critter.
for example you send a montage asset ptr to the client, they get it as a giant path first
so in this case it's probably the class path
this is completely normal
it should be smaller in ensuing calls
if this is spawning an actor this is probably not easy to work around
this is just how it works
Gotcha. Now I understand. I'll look at other ways to improve performance. Thank you.
one place that you could get some gains howeverwould be if you were doing something like
sending 3 different assets (for exmaple animation sequences or montages) in an rpc or onrep or something that are like
- anim1
- anim2
- anim3
arguably if all 3 of those are always together it would be cheaper to send one single asset that contained all 3
but the good news is they become cheaper after the exports are resolved
So the first time I load any asset will have a high overhead, but after it's cheaper?
One thing I do wonder about is if there is a way to basically pre-warm this package cache in the connection so you can pay upfront and get cheaper sends sooner
loading is not the term here, more "sending and receiving"
Sure. So the first time I send and receive a particular asset it will have high network traffic?
packages across the network do load when they show up depending on some settings but that's not what makes them take bandwidth, having to send the full path to /game/myawesomecontent/thing/thinganim/ is pricey bandwidth wise compared to just a number
This is a critter I spawn very often, so it's possible the problems I'm seeing are more in its behavior than its spawning.
also not sure if this insights graph really describes the rate of send
I got told by my lead that this critter is responsible for like 50% of network traffic, so I'm doing all I can to investigate. I'm new to multiplayer profiling, and I appreciate the guidance.
well if it's the only thing changing state it's going to be the only thing sending lots of traffic
things that move around are always changing of course
does this game involve moving large distances away from the critters that walk around? perhaps you could set a netculldistancesquared (it is squared so sqrt to see the distance used I guess) to be lower
however be aware that network relevancy can introduce some annoying issues. the object will be destroyed and recreated when you get near it
Well for one, Unreal comes with networking support out of the box, so its "free" if you will.
Rewind and Client prediction is more of a choice on a per feature basis than just something that exists everywhere.
The Character and CharacterMovementComponent as well as GAS #gameplay-ability-system support these things. But beyond that it is up to you to introduce them to your games features as needed.
There are so many aspects to networking in unreal its difficult to really explain in a comprehensive list that compares to something else, especially in another engine.
I will say there are less barriers to entry with networking/multiplayer in Unreal.
That doesnt necessarily mean its easy to grasp.
Thats hard to answer, but generally I would say yes, in that, as a beginner, you will have a better time of doing multiplayer in Unreal, since it has a lot of user friendly features ready to go.
Whether or not that's what's best for your project totally depends.
The type of game you are making will have a large effect on the answer to that question
Not every game should be made in Unreal, not every game should be made in Unity.
You should evaluate the tools that they are and how they will enable you to make the game you want to make.
Choose the right tool for the job.
If your goal is to minimize the time and effort between what you have now and having a completed game up to your standards on a storefront, then Unreal is the best IMO
I would agree with that statement
But that still comes with the caveate that is it depends on the game you are trying to make.
If you are trying to make an FPS/TPS game, then Unreal is by far the better choice.
If you are trying to make a 2D platformer for mobile, Unity will be better IMO.
I can't think of anything besides true 2D / Pixel stuff that I'd rather do in a different engine.
If all you want to do is focus on creating gameplay, then Unreal will be a much better experience when it comes to networking/multiplayer.
Just because an Engine is capable of complexity does not mean its a bad choice for low complexity games.
But yes, if you are making a 3D FPS Coop game, then Unreal will enable you to do that.
Another thing though, there is nothing simple about an FPS Coop game.
Making games is hard.
Making multiplayer games is even harder.
Dont be fooled into thinking anything is easy.
You dont have to learn C++ before using Unreal
You can use Blueprint.
These are all the settings related to physics
project settings
which settings specifically?
Project Settings - Physics - Replication
Try:
angle lerp 0
Error per linear and angular difference 0.1
Done
Should I now enable "Replicate Physics for Autonomous Bodies"? to test if correction is causing jitters or not?
thanks a lotmate turned on Replicate Physics for autonomous Bodies" packaged server and tested it with these new correction settings. Now theres no jitter and sync cars are moving smooth now. Im really thankfull for this you dont know how long I had been stuck at this
Have anyone try root motion montages with multiplayer? It basically works but only if the network connection is super good otherwise with decent ping (50-100ms) it would rubberbanding a lot. Any solutions for this?
I could try to turn off server correction while playing the root motion montage, but I haven't figured out if it has any drawbacks.
In theory, as long as you start them roughly at the same time on server and owning client, it should be fine
You can disable the corrections while it's playing, epic does that in the motion matching example, but in theory it's not needed
Hey everyone, how can i clear UniqueNetId of the user before joining to a dedicated server? Thanks a lot!
Hi, I am working with FFastArraySerializer to store inventory data, I noticed that sometimes if i pick up many items in a row I get a crash like in the picture.
During these events there are 2 places in which the array is used:
if (Items.Items.Num() == 0 || !Items.Items.GetData())
{
return FInventoryItem();
}
for (FInventoryItem InventoryItem : Items.Items)
{
if (InventoryItem.Name == InName)
{
return InventoryItem;
}
}
and essentialy
Items.Items.Add(Item);
Items.MarkItemDirty(Item);
whe adding new item to the array.
I suppose this is because the array tries to replicate while adding new entry? Any idea how can I mitigate these crashes?
really? In what part particularly? I also have a dive in the motion matching sample but only heard that it's not multiplayer ready yet.
Yeah but for decent ping like > 50ms it's unplayable because montage get play at different times, that's why it create rubberbanding.
Then why not accelerate the playback on the other client based on when it was played?
Even with smoothsync? I am using motion matching sample as in my project and it seems to be very fluid when simulating bad internet connection
I'm pretty sure it allows multiplayer.
Thing is, CMC syncs this up, so the ping shouldn't do much more than cause a correction if mistimed
There is also no need to use SmoothSync
Feel like this gets overused a lot :D
Never had to touch that in the 10+ years I'm using UE.
Hey everyone, how can i clear UniqueNetId of the user before joining to a dedicated server? Thanks a lot! Or just ignore the NetID as I am currently getting PreLogin failure: incompatible_unique_net_id Thanks!
i feel like you shouldn't have to mess with that unless you are doing some low level networking stuff.. maybe the dedicated server is using a different OSS for some reason?
Yeah I do not want to mess with it at all, I am just getting the Oculus UserName from the headset at runtime through OculusOnlineSubsystem, this is all before we join the server. We are running a Linux server, I only need the Username when the app starts, and then I do not need the OOSS at all. Sadly during connection to server, this causes a problem.
ah, well that id check is in AGameModeBase::PreLogin which is a virtual function so you could possibly override it and copy the code from the original function just without and unique id check
and not call super
Tried to create a customGameMode with overriding the Prelogin already, but that part did not execute as the PreLogin failure: incompatible_unique_net_id run earlier it seams.
@tardy fossil
Probably i will stop messing around with this and just go with the Platform SDK and get the username through there.
yea thats ran when you call the super::prelogin
but yeah using the platform sdk is probably a better option
Your problem is that you mix Subsystems.
Your LinuxServer isn't running the Oculus Subsystem, while your Client is.
That causes the Mismatch, because the LinuxServer probably uses the NullSubsystem and has no clue what to do with the Oculus one.
Epic, at some point, started to block the ability to mix those. In theory you should use a "cross platform" subsystem, where Oculus users authenticate at with their Oculus account (e.g. EOS).
As pointed out, the check happens in the GameModeBase::PreLogin function
void AGameModeBase::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
{
// Login unique id must match server expected unique id type OR No unique id could mean game doesn't use them
const bool bUniqueIdCheckOk = (!UniqueId.IsValid() || UOnlineEngineInterface::Get()->IsCompatibleUniqueNetId(UniqueId));
if (bUniqueIdCheckOk)
{
ErrorMessage = GameSession->ApproveLogin(Options);
}
else
{
ErrorMessage = TEXT("incompatible_unique_net_id");
}
FGameModeEvents::GameModePreLoginEvent.Broadcast(this, UniqueId, ErrorMessage);
}
If you want to work around this you shouldn't override this function.
You should inherit from UOnlineEngineInterfaceImpl and override IsCompatibleUniqueNetId
UOnlineEngineInterface* UOnlineEngineInterface::Get()
{
if (!Singleton)
{
FString OnlineEngineInterfaceClassName;
GConfig->GetString(TEXT("/Script/Engine.OnlineEngineInterface"), TEXT("ClassName"), OnlineEngineInterfaceClassName, GEngineIni);
// To not break licensees using this, prefer this if it is present, and warn. Remove in 5.7
bool bUseOnlineServicesV2 = false;
if (GConfig->GetBool(TEXT("/Script/Engine.OnlineEngineInterface"), TEXT("bUseOnlineServicesV2"), bUseOnlineServicesV2, GEngineIni))
{
const TCHAR* V1ClassName = TEXT("/Script/OnlineSubsystemUtils.OnlineEngineInterfaceImpl");
const TCHAR* V2ClassName = TEXT("/Script/OnlineSubsystemUtils.OnlineServicesEngineInterfaceImpl");
OnlineEngineInterfaceClassName = bUseOnlineServicesV2 ? V2ClassName : V1ClassName;
UE_LOG(LogOnlineEngine, Warning, TEXT("bUseOnlineServicesV2 is deprecated, please instead configure [/Script/Engine.OnlineEngineInterface]:ClassName=%s"), *OnlineEngineInterfaceClassName);
}
UClass* OnlineEngineInterfaceClass = nullptr;
if (!OnlineEngineInterfaceClassName.IsEmpty())
{
OnlineEngineInterfaceClass = StaticLoadClass(UOnlineEngineInterface::StaticClass(), NULL, *OnlineEngineInterfaceClassName, NULL, LOAD_Quiet, NULL);
}
if (!OnlineEngineInterfaceClass)
{
// Default to the no op class if necessary
OnlineEngineInterfaceClass = UOnlineEngineInterface::StaticClass();
}
Singleton = NewObject<UOnlineEngineInterface>(GetTransientPackage(), OnlineEngineInterfaceClass);
Singleton->AddToRoot();
}
return Singleton;
}
The getter for the interface spawns the singleton when it's not valid.
GConfig->GetString(TEXT("/Script/Engine.OnlineEngineInterface"), TEXT("ClassName"), OnlineEngineInterfaceClassName, GEngineIni); shows you that you can specify your own class name via the DefaultEngine.ini.
[/Script/Engine.OnlineEngineInterface]
ClassName=/Script/MODULENAME.CLASSNAME
E.g.
[/Script/Engine.OnlineEngineInterface]
ClassName=/Script/YourGameModule.YourOnlineEngineInterface
This is the default one:
[/Script/Engine.OnlineEngineInterface]
ClassName=/Script/OnlineSubsystemUtils.OnlineEngineInterfaceImpl
Just be aware that they are shifting towards some version 2.0.
Although, I also just saw that there is this:
bool UOnlineEngineInterfaceImpl::IsCompatibleUniqueNetId(const FUniqueNetIdWrapper& InUniqueNetId) const
{
return InUniqueNetId.IsV1() && (InUniqueNetId.GetType() == GetDefaultOnlineSubsystemName() || CompatibleUniqueNetIdTypes.Contains(InUniqueNetId.GetType()));
}
So maybe before creating your own, check what CompatibleUniqueNetIdTypes is
/** Array of unique net ids that are deemed valid when tested against gameplay login checks. */
UPROPERTY(config)
TArray<FName> CompatibleUniqueNetIdTypes;
Might be worth just adding oculus to that
[/Script/OnlineSubsystemUtils.OnlineEngineInterfaceImpl]
!CompatibleUniqueNetIdTypes=ClearArray
+CompatibleUniqueNetIdTypes=Oculus
Also DefaultEngine.ini
How can I create a different render target for each player in my game... Like for the preview character in the inventory..
so Im just prototyping some stuff in blueprints to get familiar with networking. (Before moving over to Cpp) And Ive run into a problem.
I spawn an item actor through a pawn on the server. I set the owner to be the player controller which if I understood things correctly should be the local player.
But when I try to call an event on the actor it only works on the server because the server somehow retains ownership.
My goal currently is to just have this print in the item (third picture) to run locally. So I can trigger effects etc locally and then follow that with server only stuff.
Ive also tried printing out the name of the owning actor immediately after the spawn actor node and it does appear to be the remote player (this is a listen server setup)
But when I print the ENetRole enum from the item actor it always says Simulated proxy on the client. Meaning the client does not have ownership.
I'm wanting to understand best practices for replicated variables.
I have an INT "Currency". This is mostly a server variable, but there will be times where I want to display the amount to the client - say in the inventory panel, for example.
I could set this variable to replicated, or I could write an RPC that passes in the PlayerController reference. That RPC triggers an event that queries the currency on the server, and responds to the calling player controller with the amount - I can then pass this amount to the widget.
The RPC route feels like a lot of work each time I want a server variable.
Two questions:
1 - Would the RPC approach consume fewer server resources in practice, should I be doing this for most of my variables?
2 - If yes, how can I determine when I should be using RPCs and when I should be using Replication?
Use replicated variables for stately things. If you want something to happen when a client receives an updated value, then you use OnRep / RepWithNotify which gives you a function that is called when a change is received.
Render Targets aren't replicated, so you can just use a single instance locally.
Would you define the above example of currency as "stately"?
I'm thinking yes? I suppose if the currency changes while the panel is open, I'd want to reflect that state.
The third picture doesn't appear to have anything to do with networking. If you're able to get an appropriate reference to the object and call the Use event, it should work.
Yes. You collect a coin, you now have 1 coin. That is a state.
that is what I thought too, I'll have to double check the reference, I think I realize now that the item may not actually be added to the inventory component..
or rather the inventory doesnt replicate properly
yep.. whoops
gotta figure that one out
I add the item to the inventory as a reference on the server and the component is set to replicate bute vidently that isn't enough
fixed it! I forgot to set the reference to replicate as well. 
lol, that was like 1-2 hours of faffing about
thanks for the help @sinful tree your comment got my two brain cells to collaborate enough to realize my mistake
Kinda funny how much I struggle with networking when I literally used to work on an mmo before I left gamedev. 🤫
Hey all, in a multiplayer shooter with multiple Game Modes to choose from, is making a multiple GameState, PlayerState, and HUD class for a specific "Game Mode" a bad practice? E.g:
- AGameMode
- AGameMode_Deathmatch
- AGameMode_SearchDestroy
- AGameState
- AGameState_DeathMatch
- AGameState_SearchDestroy
- APlayerState
- APlayerState_DeathMatch
- APlayerState_SearchDestroy
and so on
If they only vary by that much you don't necessarily need to do that
You can include all the data you might care about and just opt in or out of it
Ok, but in scenario where the game modes have data that cant be abstracted to something like scores or teamScores. Is it acceptable? Or are there any better approach?
I'm on my network optimization journey again. Is there any way to reduce the network traffic when spawning an actor for times after the first?
I'm seeing some major spikes in network traffic whenever I spawn a new critter in my game. Network Insights it's mostly components.
Dang, this is hard 😦
Show the insights
The answer is generally to not replicate stuff you don't need to
But what can I say without actual information
I'll prepare a censored version.
Are they replicating components?
If so why
Replicating an entire component means you must send and update information about it
Very common for people to make components replicate that have no real reason to
Seems like the biggest expense for my critter is replicating components on spawn, and when using an ability
Okay but you already mentioned the components
I am asking why they replicate
If it's a GAS component it is rather difficult to replace or pool I imagine
I am concerned you are replicating something like a random mesh component without good reason to
By replicating components, you mean replicating on spawn or replicating over time?
Replication being enabled at all
If they replicate over time they are probably in the first net bunch anyways
I see. So if a particular component appears in Network Insights on spawn, it's because it was marked for replication?
I would need to see the actual packet to be sure
I'm not able to construe information unless I make a quick example
first of all you don't have a very high verbosity
so I can't see the individual names of types in here
I think if you raise the trace verbosity you should be able to
pool them and spawn upfront (if it hasn't already been mentioned)
That wont' reduce network traffic
unless it's all upfront I guess
but these are kind of dynamically made so idk if that's reasonable
I think it's a good idea
moving to a network manager scheme is often a good idea
Well if you can reduce the spawning by pooling and reusing existing ones that is how you reduce network overhead of spawning them over and over
How can I increase verbosity?
Network manager scheme?
This is pretty late in the project. I worry that pooling will cause an enormous number of issues.
You inherently pay a high cost for creating networked objects, that is why pooling should be a first step in designing this for a networked context
I've switched verbosity from 2 to 5. Running the test again.
this basically just means storing information for multiple things in one single manager object
-NetTrace=3 to increase verbosity to what I think is the current max of VeryVerbose
Alright. I'll run the test again.
this might make the trace file larger I guess but you want more information here, not less
I'm spawning a trio of these critters, letting them run around and attack, then killing them. This is with two players in a listen server.
these other components being replicated is questionable unless they aren't and they still somehow show up in here
Let me check.
BaseCritterCharacterComponent is a BP class, deriving from a C++ class.
also I think the gameplay attributes are replicated subobjects
I think you could probably save a fair bit by merging some of them together
but that might be quite annoying to implement
easier than not using gas though lol
basically each replicated subobject means you have another thing that can be a target of replicated state
which means sending anything to it requires a network ID to the object
so more unique objects means more IDs have to be sent for them when they get changed
Seems like the same results?
sometimes this can be a good thing to help segregate away things that are unrelated etc or to have something that can come and go
which version is this?
4.27
you should be seeing something like this I think at least for the updates later
notice how each property has a separate little rectangle?
Yes. This is all the stuff before the actual critter is being spawned. I'll get a shot of the rest.
This will take a moment. gotta do a lot of censoring...
after this first animal spawns do you still get these massive 2500 bit headers?
Yes. You can see in my latest screenshot. The cluster on the left is the first spawn of the critter. The selected frame is the second spawn.
what is this Content thing?
Expanded:
ah it's just nothing
this is the header every state for any object must receive I think
that includes bits that describe the rest of the header
a bit silly it doesn't just early out with an earlier bitflag
but idk what the statistical averages are
I guess the main takeaway is replicated subobjects = more objects must be sent in the initial bunch
One thing you could do that would probably be non trivial but is a proven method that Fortnite did
is only create GAS components when they need to be created
when the thing does something ability related or gets hit
a but difficult to just add later I imagine though
but for starters why are there so many replicating components
the GAS stuff makes sense as GAS has unique state internally
but why are the others replicating
Oh yeah. Fortnite did that because they had lots and lots of destructable objects in an open world.
Yes it makes sense considering each buildable thing is very simple and there could be hundreds
that never get touched
My game is not open world, and every critter is relevant and needs to be ready to fight. Our AI system also depends on reading what abilities the critter has.
Good question. I'll start going one by one and try to understand.
are the non GAS components set to replicate or not
This codebase pre-dates me. 😐
Almost certainly.
Basically unless they have something very unique that is hard to share they should not do that
and the attributes could probably be heavily merged together if possible
basically you have like ~400 bits of actual information in this screenshot
there is no getting around having to send their initial position in most cases
and then about 300 bits or so of just... empty content headers for what I assume are replicating sub components
Is replication of a component determined at the component class level or on the actor level?
CoreCritterCharacterComponent, for example, I can see has four properties being replicated.
both
the component must mark itself as replicated somewhere, it can even by dynamically when it is created
but a defaultsubobject is probably doing so at the class level of either the instance on the actor or the component class
just check the actor bp
Yeah, I can see that the constructor has it marked as replicated, and there are onreplifetime properties.
The component class.
then you must pay the cost of sending it as a stable network object
There's four properties being replicated. I'll look and see if there's a way we can avoid doing so.
OTOH, if I were to make it not replicated how much network traffic would I save?
It would depend on each one
assuming the amount of information is the same in its replicating properties
Assume it's only being used in the Spawn.
you would save the cost of the initial header for the network id, the export, and some of the content header if my assumption is correct
the amount of stuff saved however would depend
if you had a replicated subobject with HUNDREDS of properties
it would probably actually be cheaper to have it still as a subobject because the things sending to the parent might have to mask out each of those properties
basically you have a tree with lots of leaves right now
but if you have a very deep branch of things to send it can help because that lets things much more easily skip sending that state
but if it's just like 3 things... you are wasting a few dozen bits every time
from my reading of this
for example I would say the GAS component probably deserves to stay as a component due to the amount of things it has on it arguably
but an entire component to send like 3 small things is not good and also arguably incurs cpu costs on the server as well in a small way
also TBH the default unreal bandwidth limits are pretty low
it would probably be worth investigating if this is actually a problem with the real connections or of the server CHOOSING to cut off the send because it hits the limit from settings (how to determine this is not clear to me frankly... I can look around)
also @modest crater is correct I think that having these sent ahead of time would front-load the costs as it would send the spam of headers sooner so they can move on to just sending IDs with state on demand
but idk what the shape of how these change looks like
https://vorixo.github.io/devtricks/network-managers/ an artilcle that describes what I mean by network managers
Thanks. This article looks good.
I'm seeing some unsual packets midway through the test. Let me get a screenshot and explain my thoughts....
It looks like NewActor is being called here, even though all three critters should have been spawned at this point.
that I can't help with I think, you just need to see why it's being created by debugging what the server is doing
it could be leaving relevancy and re appearing somehow
I migth be missing something about what the first one was even doing as well, it could be a separate packet for initialization and the initial bunch
would be curious to see how many times the client did beginplay on the actor
yep that must be it
the initial one was so huge I think it decided to split it up into two or more packets
uint8 bPartial:1; // Not a complete bunch
uint8 bPartialInitial:1; // The first bunch of a partial bunch
uint8 bPartialFinal:1; // The final bunch of a partial bunch
that said I don't know if it's easy to fit this into one packet anyways
if the actual information is that large then that's just... it is what it is I guess
but I guess my goal would be to remove the overhead of it being 20 different components as much as reasonable
@left marsh to me honestly this doens't seem that crazy if there are really just like 6 of these
I feel like you aren't pushing replication THAT far with so few total objects
I am curious what the actual reason for needing to reduce this is
is the server not running at a decent framerate to send things quickly? etc
That makes sense.
fwiw it's not an indictment of your setup as much as just each packet being quite small on purpose
I send the entire game frame in one giant rpc and it takes dozens of packets in sequence
This is my testing setup, where I'm just spawning 3 of these things. In a proper level we're looking at over 100 over the course of about 20 minutes.
Tell me about Repgraph. It seems like that's mostly for open-world stuff?
All my players are going to be in close proximity.
yeah I'm not sure honestly... I think it would save some cpu time on the server if it could group things better https://dev.epicgames.com/documentation/en-us/unreal-engine/replication-graph-in-unreal-engine
I'm more used to situations where you can reliable say "this is very far away, we don't need to update it as fast"
Current concern is network traffic, rather than CPU.
also repgraph is a bit old now with modern ue5 so I have never had to use it, it was what epic had to make to make fortnite scale a bit better afaik
I've been experimenting with adjusting replication frequency. Maybe I can do so more broadly, not just on the actor but on components as well?
yeah in that case then just start with reducing reduncant replicating objects as I said
I'm not sure if you can update components in a frequency
Thanks a lot for the detailed explanation @thin stratus much appreciated.
hey, anyone have any idea where to look when actors just suddenly between activations of Play In Editor... stop replicating?
and seemingly pretty arbitrarily?
topleft is server, each of those hex locations is replicated, but the top 3 just... don't, anymore?
and it's spawning the client players pawn as a generic unit without the attached info on client, it seemingly just never replicates the client characters variables?
all of this worked fine like. 10 minutes ago, and i don't think i changed anything related to it, but i must be wrong
restarted PC, didn't fix
severely confused
(i do have a backup from a day or two ago despite not having full version control for this project, so i'm not screwed, but like. what is happening here)
everything is replication via blueprints
the actors that are now suffering from inability to replicate seem pretty unrelated to each other? including the player pawn, some units, some locations. all are actors, is all i got.
The hex tiles that don't appear on client never trigger beginplay on client side, so i assume they're literally never replicated, despite being marked as Replicates
I'm very confused. everything i'm testing just gives the impressions that certain blueprint actors have started completely ignoring replication from server to client, but still work the other way around
@drifting crag are you running some reliable RPC on tick somewhere?
i don't put RPC's on tick, but i could check to make sure some wires haven't gotten crossed
(especially not reliable RPC's. i get the impression that'd be bad)
Yeah it would be
Despite that you'd need to share how you are spawning the hexagons
Your UI on the left is also failing to show the playername
yeah, the client isn't getting their own name, which is interesting
the client also isn't getting their own player character, but is getting the server
PlayerState probably also not replicating properly
Hard to help with. Might want to try and check Network Insights to see if something shows up there
so far i'm getting issues with pawn, "battlemanager", locations, units, tiles and playerstate
these do not have much in common except the client has stopped receiving updates to replicated variables
thanks for trying! i'll check network insights
Ok, figured out the source of the problem, to some extent
Marking Always Relevant on the misbehaving actors fixes things.
...i think i'll need to sort out why they were suddenly being treated as not relevant, but this seems a lot more solvable now
(playerstate was replicating fine, i was wrong. the logic for the UI just didn't move onto updating the name before it loaded the player info, including their board unit reference)
The default net cull distance isn’t very far imo
ye for our RTS we also mark units etc as always relevant
yeah, net cull distance was my first guess, but the affected things seemed arbitrary, except for the hex tiles being consistently on same side of map
i do suspect it probably is net cull distance
does that have side effects beyond preventing distance culling? given this is a strategy game with a small map, i don't particularly want anything to distance cull, so i guess i'm now on the hunt for the best method to disable that as a whole
I don't know much about network relevancy, I think there used to be ways to customize the parameters to decide whether it was relevant or not, and there are other tools (something something graph?) to improve upon that iirc.
But basically if you actor is always relevant it means that it's always updating (unless you stop it manually etc), which can be a desired thing or not depending on your game. For us actor replicate really few properties and we handle the rest quite manually
gotcha! thanks
yeah, the only states i really care for with relevancy in my game is "relevant" and "only relevant to owner" for hidden information, i think
this line from docs gives me the impression i can probably find a way to bonk net distance culling altogether
yep probably. Also using network managers is a good idea if you're going to have a relatively high amount of actors. Fast arrays serializers too. In general everything you can "batch" will benefit a lot
yeah, my games networking requirements are... mostly modest (turn based cardgame), so might not need much optimization maneuvers, but i should still look into network managers.
awesome. Yeah turn based helps a lot, since you don't need to sync data continously. If your game is deterministic enough you could get away with replicating inputs only, but replicating state has advantages
yeah am doing state replication cuz i'm iterating/prototyping as i go, and it's a whole lot easier to make quick changes with, i think
might eventually swap to a system that just tracks player actions and lets you view boardstates from previous turns by reproducing them via that, but that'll be a lot more worth engineering once the game is less in flux
shouldn't over-engineer a prototype
yeah. The benefit of Unreal state replication is that you can support late joining easily, otherwise you need to somehow replay the whole game in fast speed when somebody joins later, if that's something you want
yeah, it's a concern i had when considering that approach. and for the idea of being able to hover previous turns in the turn history to see the boardstate as it was then, i'd also need a way to go... backwards? or to also re-do everything from the start like with a joining new player.
so might also be a solid option to just try to store things as a state/struct or such, but that'd get very unwieldy with a lot of information to store for every player action.
haven't quite found a good solution yet.
i dont plan to support late joiners, but i do want to support re-joining, because internet connections are what they are
effectively the same needs, anyhow
you could save state for each turn, that's probably doable
definitely doable, just saving format gets increasingly wildcardy as the game gets more complex
i have a location on which is a unit on slot 3 that has 4 status conditions and the status conditions are storing information of all sorts, including integers and references to other units etc
possible but a lot of engineering and puts a burden on adding new stuff that doesn't fit into existing implementation
i'm not too familiar with how to effectively store information of such varied types and quantities
like, for handling a unit referencing another unit, would probably need to setup a map of some sort that lets it figure out what its referring to. give every unit a number and save the number instead, that sorta thing.
lot of solutions like that?
ahh I see. Yeah probs that can be a good excercise, to figure out a way to represent state
yeah no clue, never was in that scenario tbh
i prefer to spend my time game designing instead of doing too much elaborate programmy work so maybe i'll just leave that idea behind unless i can eventually get a programmer on the project
and just stick to pressing some blueprint replication checkboxes
ahh yeah if you don't have a programmer and it's prototyping just go for it
with additional testing, i conclude that it was in fact just net distance, and for some reason the thing it "culls" from doesn't seem to be the camera. unsure where it's measuring from, don't care enough to investigate for now, always relevant, problem solved :)
thanks for the help!
i THINK its based off the player's pawn.. so i'm not sure how that works for a spectator pawn as the server doesn't know the location
Huh. I'd assume the pawn is just at 0,0,0 then. Doesn't explain how this suddenly started happening, but would explain why it's not the camera.
or if the server was spawning the spectator pawn, it'd be where the server spawned it and not move.. but yea doesn't explain why it just started happening randomly
Has anyone here implemented delta serialization for structs that implement custom net serializers and if so what is the best approach you've found for doing it?
It measures from the view target.
Which, if you have a possessed pawn is the pawn
hm, the view target was manually set to be a separate camera actor, but
...it wasn't set on server, only locally on client?
so maybe the server was still using the pawn as the view target for purposes of net distance culling. that would explain why camera movement did nothing to the net cull?
Yop that sounds plausible
Hadn't thought about managing view target for servers for purposes of net culling. Today I learned, cheers
Try it first. I'm also only guessing a bit here. I'm relatively sure it is like that though
Clients do not have to respect all view target changes from the server
They can entirely ignore ClientSetViewTarget and set their own
Also even if the view target does't exist on the server clients still send their viewpoint as an rpc in some situations
yeah, i hadn't done any viewtarget changes on server, just on owning client. i assume that was why the net cull didn't care for the clients actual view target position, if its based on the servers view of that clients viewtarget, which was likely the pawn that was never moved from 0,0,0
you can override APlayerController::GetPlayerViewPoint iirc
By default it uses different values depending on situation
By default it will use the PlayerCameraManager or ViewTarget when playing
and when spectating (In the controller state sense) it will use a LastSpectatorSyncLocation which is sent from the client
The reason for this is because the Spectator pawn is 100% local only in the default implementation
