#multiplayer
1 messages · Page 248 of 1
If I play it in Server only, wouldnt it supposed to print 1 time?
So simply, When doing in server, it prints 1 time.
When doing in client, it prints 2 times.
Both on server.
As you see, I printed the Owner actor's name, It both prints for same client. And number of players is 1. Playing as clien.
Just out of curiosity.... What happens if you put a HasAuthority node (the one for gameplay abilities, not the one with the bool return) and place it before the playmontageandwait node?
Try it with False first and activate the ability from the client.
shouldn't server be responsible of overlapping ?
If I start it from client, and not check authority inside the Anim Notify. I only get once.
There is literally no reason to print 2 times on the server, even if i am playing as 1 client... IDK. I already checked for duplicate methods, I only call the method one time for the server. But maybe this Play Montage and Wait is called twice on the server idk...
Here, Ability is called once. So Play Montage and Wait is also called once.. But its Notify is called twice, when triggered in client, and printed double in server.
I also tried 3-4 clients at the same time.. It just prints 2 times..
😦
Where is this SECOND Server log comes from?!! From dedicated server when played in client?! But why 2 times. There are no other players.. And it comes from same client.. Gosh.. I think there is something i dont know about anim notifies or replication..
There is definitely something else going on... This is in a Test 4.27 project, but I only get a single print for server and client from my animation notify regardless of who is triggering it. (first print log is server activation, second print log is client2 activation)
And run as client with only 1 player:
Have you restarted the editor recently? 😛
Yes. :/(
This is how I use my ability. Already checked that its called once on the server.
Why are you activating it like that?
Testing Things out. Any recommends? I dont know if this is the problem. It prints one time on the server.
😦
Something really strange going on.. Ah.. I will delete and restart from start i think..
So if i create 4 players. As you see everything works fine, EXCEPT Server has 2 times.. 😄 WTF man.
I managed to find the problem. The ability in question was being granted only on Possess, which is never called on the client.
Btw, I think this is not related to GAS.
As you see, If I play montage on the server. It will still print 2 times on the Notify. Also Validated that Play Montage is called only once.
Would it be related to Anim Graph or smth? Since my Anim State variable is already Replicated
Possibly. If you're entering some state that could cause that montage to play that's a possibility.
This is my anim montage.
My State is only for Upper Body/Lower body, to set idle anim etc. Nothing relevant to that montage actually. Something is really bugged out i think..
Does something look wrong in my Anim Notify?
Not that I can tell... Animation stuff isn't usually my forte to be honest, but there's nothing that sticks out to me.
I think this is related to this stuff.
That depends a bit. Here it is better if one handles it everywhere, or at least on Server and OwningClient.
Because due to the Movement Prediction, Server and OwningClient will perform the same movement, and they will both step into the overlap at the same "time".
Means both will apply the LaunchCharacter stuff at the same time and everything stays nicely in sync.
Is setting replicated variables on event tick expensive? Too expensive?
no
what is this variable?
Hit Result from a line trace that runs on tick
I'm guessing you're maintaining an AimPoint or something of the sort?
You need to remember that the client won't see that thing updating butter smooth though, they'll get it at some varying rate. You'll want to do some smoothing clientside if it's meant to be shown
If it's meant to be seen by the owning client it'll be lagging behind their view. What actual mechanic are you making?
Wondering if there's a better approach to it tho, it's just that I cannot find a way to get linetraces running properly on server RPCs for on clients
What are you trying to do?
I want the item to smoothly fall to the floor using a timeline. Before the timeline starts, I do a line trace is to the hit location. This trace is called from a Server RPC, and if it hits, the hit location is saved in an EndLocation variable which is replicated. Then I call the "PlayDropEffects" multicast which lerps the actor to that EndLocation using a timeline for a smooth drop effect
The issue is, when the server tries to perform the line trace on the client's character (character is passed into the interaction logic), the trace fails completely. Wondering if it's because I'm running the trace on the camera but I don't see why that would be
this logic is not being ran in the player, but is ran in the interact parent class, which i call in the children of it. i do it this way for a more modular system
are all dropped items dropped by some player?
yeah
You can do it like:
Client:
DropButton -> trace -> call DropItemtoLocation(Item, Location) //run on server event
Server:
Check that Location isn't like miles away from the character's location -> get item, call MulticastDrop(Location)
Everyone:
Item plays timeline, lerps location towards the target location.
the server doesn't need to do any traces
although you'll have the be careful to gracefully handle the item state, does it not have replicate movement turned on? What would a late joiner see?
yeah that makes more sense, thanks for the help!
replicated movement makes it very jittery, doesn't seem to work well with timelines, so i turned it off.
you probably want to turn it on when the timeline ends
that way a late joiner sees the replicated position of the thing, that is, it lying on the ground.
ohhh yeah, damn, didnt even consider that at all
thanks a bunch
can someone tell me why i still can use cheat engine and change the value of x?
i used rpc run on server to multi cast and made the server change the value
Does BeginPlay only get run on the Server? I am trying to figure out why the client is not running a necessary function that's under begin play.
btw i used the client net mode with running a dedicated server on so i'm not playing as a server and i still can change the value on client
Just because the server is the source of the initial value, that doesn’t mean the client isn’t storing that value in memory.
Also, if you’re testing PIE, you may have both the server and clients in the same process
Detection of CheatEngine or similar things is pretty complex
stand alone game - i have tested changing value of only server values variables in the game mode and i could not, just to make sure i don't have any auth to server
You might’ve locked the value of the float variable that is the input property of the event?
So even if the value changes from replication the client could just use its own value
Just because you're using server authority to send the value, your server does not ultimately get full control over client machines. You can tell them what to do, but they don't have to do it.
Server RPC = client telling server to run function in the actor in server's version.
Essentially you just ask the client for a value without any check.
So ofc a client can just run a cheat engine and just tell server hey, run this function with X that i passed which is 999999
General rule in multiplayer is to trust the client as least as possible.
And as for movement, you normally only grab the input from the player.
You dont ask. Hey what's your position in your world? Instead you just ask which input direction is the player currently holding. Then server can resolve the direction and location the player is going simply from the direction input the client send.
Should I worry about this? It used to not be a problem
from reading the code this might actually cause some weird issues because it guesses the remote role early
doesn't seem that hard to fix... just do what it says?
Well the actor doesn't have the option to set replicate in the properties though?
And yes right now I'm having some weird replication bugs like the server seeing different values from the client
Read the error message... this is not a property window problem
this is about something calling SetReplicates before the actor is initialized instead of setting it directly
ok
just breakpoint the error log, no need to guess
Not sure if fixing this will help with your recent issues but warning logs are not sensible to ignore here
I'll figure it out. I was going to ignore it at first because warnings are not usually a problem for me.
Is this related to the issue? I tried to cook the content
Got many of these
what would an input action have to do with replication issues?
I believe in most games input is local only
no it's not only that as I said. There's multiple of those warnings for every asset
Well I guess that is true though. It's not related with the replication errors.
What might be the reason an Anim Notify called twice on the Server, when playing as Client as 1 player.
Here the result is;
Playing Montage prints 1 time.
But Owner Name printed 2 times in the server.
"Play Montage" prints as 1 time, validating that input is called only once, and the montage.
@remote tusk are you aware triggered runs every frame?
use started if you want to fire something on Press
if you hook up a print to the Notify Begin exec pin, does that also print twice?
only UAnimNotifyState has begin
this is probably a single UAnimNotify (where it's just a single event, not a range of time that begins and ends)
I would try to see what the callstack looks like for each invocation in the actual code
afaik montages can get weird with dead instances calling again depending on ticking rules on the server
My trigger is set to "Pressed" only in the input, so as you see "Play Montage" log prints only once.
Yes. Its really weird behaviour, I couldnt solve it since the last night..
I validated that this Play Montage nodes work only once. But Anim notify gets twice.
And this is only happening on "Client." Server is printing only once when played on server instance.
If i start game as client,and only one player.
It prints 2 on the server.. Regardless of "Client" count..
Am I doing smth. wrong by using Anim Notify inside "Montage" and not in Sequence?
I use anim notify and anim notify state all the time inside montage with no issue.
Now I will try something. I will use simple Anim Montage Notify, and subscribe to On Notify Begin see how it looks like.
OnNotifyBegin is for AnimNotifyState
just use the regular AnimNotify
it's working as intended
the problem doesn't lies from using the AnimNotify vs the AnimNotify you create in the montage imo.
I meant on the Play Montage node
Let me try this now, lets see whats going on. 😦
It only prints one, when used Anim Notify, and use On Notify Begin node.
Well there is no custom notify for that. I am testing this if smth. wrong with my GAS setup, but nah. It also didnt work for Play Montage node with "Custom Anim Notify that i previous earlier.
I use upper body/lower body to seperate.
I also tried to log "Mesh Component" name if there is multiple meshes that playing the anim.. 😦
Its weird that it only happens on client.
I can solve that with "Trigger Once" in Gas when waiting for event.. But still, Anim Notify triggers twice makes me angry and trying to solve it..
As you see its a simple Anim Notify, called on a Montage..
try changing your Montage Tick Type to branching point as a quick test
Expected behaviour was Client and Server only, when used GAS. But server triggers twice IDK.. I think smth. wrong with my animations.
I thought problem was with GAS. But I also tried Play Montage node on server only.
Alright
LMAO
this worked?
But how? Why... MY WHOLE 6 hours was just for a montage tick type?! 😄
Thank you very much man.. Thank you. But How this is worked, that was wrong
maybe some weirdness with the fact a dedicated server ticks slower by default or something
branching point is more precise
Hmm IDK. This also happened on P2P btw. 2 players, one is listen, one is client
Thanks man anyway.. I will search into on that!
no prob
Are there any chance that my Montage is in Loop or smth? Its not looped on the settings though.. Anyway.. This was the problem.
Should i be "best practicising" to make branch point for every montage i will replicate?!
There's no p2p but aside from that mine doesn't get called twice on Queued
not sure if there would be a problem in the future though
Maybe because its some kind of animation replication stuff on going behind IDK. 😦
I'm not totally relieved that it works with only changing Tick type. 😂
Should i be using "Anim Notify" to check Traces for harvestables? Or are there any better ways
I simply Play Montage --> On Notify Hit --> I trace and send data to server to attack.
I cant even now if this is true or not.. 😄
I'm currently implementing some Server functions, now I wonder, since for example I have a EquipItem function. What are common patterns approaches here?
Currently I'm creating a ServerEquipItem function (which is annotated with Server), and that function then calls the EquipItem function which is just blueprint BlueprintAuthorityOnly).
I wonder, does it make sense to just have the EquipItem function be a Server function in the first place?
Also wonder should I maybe add a Authority check in the EquipItemFunction and then call the server function from there (and remove the BlueprintAuthorityOnly annotation), and then on the server the EquipItem function is called via the server call again.
Is there some common patterns/approaches that make sense?
F... you ChatGPT, some guy called Omnicide is better than you!
In Server -> Equip Item (i assume you will spawn the item) -> Change your Equipped State enum which is replicated (create it) to sync for animation.
Then you can attach your item, which resulting others will see item
Here is how i use hotbar, and spawn an equippable item.
The picture called on server.
It already works and is implement, quite decent I think, it's just a conceptual question.
What are the best practices when it comes to things like that.
Also I'm in C++, but currently I see a few options:
Option 1
Implement the EquipItem function, so that it checks for authority and if not automatically call the Server function.
Option 2
Just have EquipItem and ServerEquipItem separate and ServerEquipItem calls EquipItem (like in option 1), but EquipItem does not call the Server automatically.
Option 3
Make the EquipItem function be a Server function in the first place.
In option 1 and option 3 you basically can call EquipItem everywhere, possibly avoiding mistakes, where you oversee authority checks, having the EquipItem function deal with when to call on server when not itself. While option 3 might be the simplest/cleanest, you won't be able to have custom logic that is run on the client immediately, when equipping an item. Option 3 would require to call the appropriate server function dependent on the context, but might avoid a additional a additional HasAuthority check.
I feel like option 2 is just the thing one gravitates to while implementing first, while option 1 and option 3 might be better to use implementation wise, where option 1 might be the the best?
Besides that, the question is, do I maybe extract the logic for equipping the item into it's own function, separating it from the client/server calls completely, but that might be a bit extreme and only if one really needs it.
So basically I'm just asking, if there is some common patterns, of how to implement this calls, or if you just take it how it comes, if someone knows any pitfalls here which I may regret later on.
Hey guys, I’m having a weird issue with server travel via Steam.
I have both the listen server and a client in the lobby. When the server initiates a server travel, the client joins the session but doesn't have an assigned player controller.
However, if the client closes the game and rejoins the session, they do get a controller 😄 Any idea what might be causing this?
While using server side rewind to confirm hits, how do you choose which actors to rewind?
Only rewinding the target the client suggested, feels like a bad idea, because a teammate might have moved in the way blocking the shot, but when client took the shot, the teammate was not there
Anyone know how to replicate FloatingPawnMovement? I'm using it in my vehicle, when the Server enters the vehicle and increases the Throttle (Float), that Throttle variable is being sent into a AddMovementInput and it looks fine for both the client and the Server. However when the Client enters the vehicle (either pilot or passenger seat) the Vehicle jitters for the Client but not the server. I assume it's just an incorrect replication setup but everything I've tried so far has had the same result (still jittering). Not sure if the FloatingPawnMovement requires additional setup. I've replcated all related variables and components.
what this log want to be fixed?
Warning: (navmesh: RecastNavMesh_UAID_544BFE8D4231BC5B08-Default) Added an oversized dirty area | Tiles marked: 2 | Source object = SphereComponent /Memory/1DYT2RL8VAWC8N7U98M2Q9ACC.Playmap:PersistentLevel.BP_Bullet_C_281.BulletSphere | Potential comp owner = BP_Bullet_C /Memory/1DYT2RL8VAWC8N7U98M2Q9ACC.Playmap:PersistentLevel.BP_Bullet_C_281 | Bounds size = X=190.400 Y=190.400 | Threshold: -1
setting bAllowJoinInProgress = false will actually not allow any new player to join?
i call this function when max player limit is reached.
void AARMAGameStateBase::CloseJoiningAbility()
{
//Restrict player join if match is already started or max player join limit reach
if (const UARMAGameInstanceBase* GameInstance = Cast<UARMAGameInstanceBase>(GetGameInstance()))
{
IOnlineSessionPtr SessionInterface = GameInstance->GetSessionInterface();
if (SessionInterface.IsValid())
{
FNamedOnlineSession* Session = SessionInterface->GetNamedSession(NAME_GameSession);
if (Session)
{
if (Session->SessionSettings.bAllowJoinInProgress == true)
{
Session->SessionSettings.bAllowJoinInProgress = false;
SessionInterface->UpdateSession(NAME_GameSession, Session->SessionSettings, true);
}
}
}
}
}
never tried this, but if you want to stop players from joining you could probably destroy their controller on "initNewPlayer()" in the game mode(i havent tested this), theres probably something better that you can do on "Login()" or "PreLogin()" in the GameMode.
Thanks i will try them
I have an event on game mode. I also have a custom notifacation function that creates notifacation for the player controller I input I want the notifacation to show up after the event on every client not just the server how can i go about doing this?
this works perfectly
void AARMAGameModeBase::PostLogin(APlayerController* NewPlayer)
{
Super::PostLogin(NewPlayer);
if (!NewPlayer)
return;
if (CurrentJoinedPlayers >= 2)
{
UE_LOG(LogTemp, Warning, TEXT("Logout :: Reason :: Steam Session is Full on a private app ID, try later to join!"));
KickPlayer(NewPlayer, TEXT("Session Full"));
return;
}
AARMAGameStateBase* CurrentGameState = Cast<AARMAGameStateBase>(GameState);
if (!CurrentGameState || CurrentGameState->GetIsMatchStarted())
{
UE_LOG(LogTemp, Warning, TEXT("Logout :: Reason :: You can't join an ongoing match. Try later!"));
KickPlayer(NewPlayer, TEXT("Match Already Started"));
return;
}
CurrentJoinedPlayers++;
CurrentGameState->Execute_NotifyPlayerJoined(CurrentGameState, NewPlayer);
}
void AARMAGameModeBase::KickPlayer(APlayerController* PlayerController, const FString& Reason)
{
if (!PlayerController) return;
FString KickURL = FString::Printf(TEXT("?KickReason=%s"), *Reason);
PlayerController->ClientTravel(KickURL, ETravelType::TRAVEL_Absolute);
}
how did u figured this line "PlayerController->ClientTravel(KickURL, ETravelType::TRAVEL_Absolute);" would kick the player?
yes i tried it and it works 😄
it travels me to the default editor map
also, you might wanna move this var "CurrentJoinedPlayers++;" to the game state, i did the same in my game and eventualy needed to move it
in the gamestate i have one which is replicated, but in game mode i want a non replicated
replicated one to use for updating player count on UI
but why would you have 2?
you can just use the one from the gameState
just fetch it in the game mode
yeah but i don't want to access gamestate for this property check
im sure you have your logic for not acessing it, but regardless its super easy if you ever wanna change it for simplicity GetGameState<AArenaGameState>()->hasPlayersToStart = true;
thats how i do it in my game mode
Thanks for sharing the snippet 😄
You'd probably want to multicast it on the GameState then have whatever notification is received on clients from there.
Ohhhh yeah huh I forgot the game state existed thanks
I'd have ServerEquipItem which actually sets the state, then use a rep notify to do whatever the fact that the item is equipped should do
void ACannonBall::Launch()
{
MultiCast_Launch_Implementation();
}
void ACannonBall::MultiCast_Launch_Implementation()
{
UE_LOG(LogTemp, Warning, TEXT("Launch(%d), NetRole(%d)"), HasAuthority(), GetLocalRole())
ProjectileMovementComponent->Velocity = -GetActorForwardVector() * ProjectileSpeed;
ProjectileMovementComponent->bSimulationEnabled = true;
}
I call ACannonBall::Launch() from another class on Server. This code works on server side, however on client bSimulationEnabled would not be updated. How can I solve the issue ?
thank you for your answer, it is solved
Are you sure the Actor is replicated?
yes, actor is replicated but projectile movement component is not. Should I set the component to replicate ?
It always log Launch(1), NetRole(3), so it is not called on any non-auth actor
The function is only called on authority cause you are calling MultiCast_Launch_Implementation, so you are just running the function, not calling the rpc.
Just call MultiCast_Launch
ohhh, thats valid point. I am checking right now. Thank you
that solve the issue. thank you for your time
Hey! Could anybody point me in the right direction on how to create/join lobby WHILE remaining on the same level .
I can create a session and then WITHOUT changing levels , I can turn the current level into a listen server, which then enables players to join me and that works perfectly fine. BUT when a client uses the join session node , it changes the level to whatever the server level is. If my client is already on that level prior to joining , how can I get a client to join the session without reloading the level?
I’m using blueprints but can add any cpp if the functionality is exclusive to cpp
I'm a bit surprised you can start listening without re-opening the level. In theory, both, listening and connecting (as well as disconnecting) are HardTravels and will load the level. I don't think connecting can be done without the client loading the level
In standard UE that is
There are c++ beacons but they aren't meant for gameplay
Thanks for the reply!
Took me a lil bit to figure out lol , but I’ve been using this UGameInstance::EnableListenServer . And this allows me to change to listen server during runtime . And so far it’s been working fine without needing to load to another level . I’m not sure if there’s something I’m missing but its working how I figure it would and how I want it to lol
But yah I’ve been trying to find any documentation or forums on how to join without level change but coming up empty like your suggesting
I have seen/played some indie games (unity) where they create and join lobbies while still remaining on the same level ( or atleast as a player it looks like no new level was loaded ) and I’m curious how this is done
I’m ultimately trying to create a player lobby screen where users can host and join a lobby while still having that lobby screen stay Persistent (akin to Fortnite , COD) . Maybe this is done via level streaming?
using the latest tool chain, i'm getting this error
error : non-portable path to file '"WeaponActor.h"'; specified path differs in case from file name on disk [-Werror,-Wnonportable-include-path]
this only happen if i build for linux
it tells you what's going on
and I remember this being an error with cross-compiling even in UE4
I used UE4 for this before and don't have any errors.
I know it is telling me the file name not matches which is incorrect
it tells you the casing doesn't match
because the file name is correct and for windows it build correctly
windows is not case sensitive, linux is
the file name WeaponActor.h in the folder directory
same as in the header file
the folder name is Weapon/WeaponActor.h
this is the issue?
I would be worried that some actors don't have the right net roles and similar if you don't reload the map
That's done via Beacons
Lightweight connection that supports replication but doesn't actively load the map
Check #online-subsystems pins. There should be some info. Needs C++ or course.
Awesome , will look into beacons and this thread . Ty 🤙
Hello all,
I need to test whether a host of a listen server is connected to the internet during play. We have a potential issue where the host could unplug their internet during play and get a bunch of kills and a rank up once everyone else disconnects, so we want to terminate the game session.
The problem is, I'm unsure how to get whether the listen server host is able to reach the internet. Is there something I can poll to test this?
solved:
changing the disk drive name from Local Disk to Localdisk
no idea why this is case sensitive issue
im going nuts. My boolean returns the proper value when playing as client only. if i set it to replicated then it stops working on client aswell. So right now, it only works when playing as client, not standalone
Hmm I can't figure out how to stop correction for this case.
So the server disable the capsule collision to a pawn channel. But the client won't do the same instantly as ther is delay.
There will be a buffer where the collision is disabled on server but enabled on client.
This will cause correction when the client tries to walk over the dead body.
Any idea on how to tackle this?
why isnt this rep notify working in the animation bp?
anim blueprint is not replicated
Anim blueprint job is to read from it's owner.
never do any game logic in anim blueprint.
yeh this is why i am switch over to using a interface to update the animbp
Does the server request the client to disable it or the client does it predictively?
https://youtu.be/R3mPtalY4o4?feature=shared&t=251 ( i was following this tuto)
Project Files: https://www.patreon.com/posts/99635410 .
In this unreal engine tutorial, I am going to show you how to replicated variables in animation blueprint variables. Here what i do is, Using a variable in the character blueprint with "RepNotify" replication settings and then using the OnReplicate function for that variable to restore and...
Death happend on server, so the server sets the collision first on it's machine.
Then tell client to do the same via repnotify.
interface or not has nothing to do with the role of Anim bp and how it is not replicated.
The repnotify is for death and collision disabling?
just for the collision
Well i am not doing any game logic in the animBP .. part of the reason i switched to a interface is also to give the code something to replicate because it was at the end of the graph... it was orginally just reading it in from a refference to bp that held it .. but this would give you rep notify node that could do nothing except set the value again which becomes a loop ..
// Allow for being pushed for a moment.
if (HasAuthority())
{
Mobility = EAGMobility::CanBePushed;
FTimerDelegate TimerCallback;
TimerCallback.BindWeakLambda(this, [=]()->void
{
// Remove collision with other pawn after a short while.
Mobility = EAGMobility::IgnorePawn;
GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
});
FTimerHandle Handle;
GetWorld()->GetTimerManager().SetTimer(Handle, TimerCallback, FMath::RandRange(0.2f,1.5f), false);
}
Then the rep notify for client
void AAGCharacterBase::OnRep_Mobility(EAGMobility OldMobility)
{
if (Mobility != OldMobility)
{
switch (Mobility)
{
case EAGMobility::NotMoveAble:
break;
case EAGMobility::CanBePushed:
break;
case EAGMobility::IgnorePawn:
GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
}
}
}
Assuming death is also replicated, Why not disable the collision on client aswell when the actor dies?
but in any event the kneck rotation (modify bone transfor) isnt and wasnt replicated on clients in either scenario .. just puzzled as to why this is then if it im not doing any thing wrong
death is only called on server
since damage is server only
if damage fatal -> Death is called
then server do what it has to do. Then server will replicate w/e client need (e.g capsule collision)
actually with 50 ms, seems allright
corrections are more evident in 100 ms environment
Nvm still getting correction, especially when the player sprint.
Does the server still have to replicate the dead character? If not then you can just disable replication so it doesn't keep correcting
the correction happend because in the server, the player can walk over the dead boy where
the client have some window before it disable the collision in the machine.
yeah but the server shouldn't correct the client if replication is disabled no?
so correction will happend, lets not focus on the death part but the fact that there will be disagreement in a certain window on the capsule collition.
The one that being corrected is the player that is still alive.
right my bad
@blazing bear actually gave me an idea with disabling the replication
if I set it to false, will the client assert Authority?
I think the video is grossly mistitled, had a quick look
Yeah, I saw the video. The title doesn't do justice.
he is setting the variable in the character
abp just read that replicatied variable.
deffinitly a very bad title.
Yeah lol
Vaei, got a question. If I turn off replication, does the client will assert authority over the not replicated anymore actor?
If you tear off the actor then it won't get any updates from the authority (server)
But I haven't checked if it then becomes authority and returns true for auth checks
What about using bIgnoreClientMovementErrorChecksAndCorrection
/**
* If true, we should ignore server location difference checks for client error on this movement component.
* This can be useful when character is moving at extreme speeds for a duration and you need it to look
* smooth on clients without the server correcting the client. Make sure to disable when done, as this would
* break this character's server-client movement correction.
* @see bServerAcceptClientAuthoritativePosition, ServerCheckClientError()
*/
i think what your kind of missing is if you SET a variable at the end of the graph there is nothing else you can do... this is why i brought up that i switched the system so that it could have something to replicate, eg the final step now is set the value inside the animation BP using the interface and thats the bit of code to replicate
any way i figured out what was causing the problem I hadnt ticked replicates 🫣
Yeah but I can't toogle that on the player that is alive as I need authorative movement.
Trying to see if I can push things simply just checking overlap on tick now as opposed to Capsule Hit event.
cheers guys.
What is the original issue you're trying to solve? I read up but there's a lot of discussion @dark parcel
it only prevents the server from checking the clients for errors, have you tried it?
It prevents the server sending any information whatsoever as well, not just positional either; everything
well basically ServerCheckClientError doesn't run if the property is true
maybe have the client predict the enemy's death
otherwise
Im pushing the capsule component for a few moment before disabling the collision.
^ Above is single player listen server, I haven't got time to take a video of the problem in multiplayer.
But hopefully it can be understood.
right now, just gonna try to push without the Hit event and just check for overlap on tick on server.
that may do the trick 🤷♂️
having NetworkMaxSmoothUpdateDistance set to a higher value may make the corrections seem less bad if they're actually tping in your case
does that apply to Autonomous or just proxies?
i think any sort of smoothing only apply to Proxies
actor controlled by player got snap correction.
should apply to autonomous as well
the locally controlled player can slowly but smoothly interp to the correct pos
ARK for example does it in some cases, the cost is that the local player feels sluggish and slow during that moment
no doubt, but I am not sure if there's something in built for autonomous to be smoothly interp.
with my skill I can't fight CMC yet.
Damage and death are server events
Whatever they apply should be updating along with the sim proxy, i.e. without any delay
For the local player themselves, when they get damaged/killed, because its from a server event any knockback, movement speed/etc. modification, stun, disabling collision, etc. will result in a de-sync
I still don't quite clearly understand the specifics of your issue but does it fall into that area?
yea, to be specific the part to disable the collision.
server disable collision then tell the client to do the same.
Presumably you also stop movement?
but that will create a window where server already have the collision disabled where as the client still have the collision enabled.
I stop the movement on the dead character.
Right, yeah, and it's also the same problem with walking into another character in MP, whether its AI or player controlled, you de-sync like crazy because they're in different places on the server, even when the local clients don't see themselves touching
Yup 😦
So right now, just disabling the collision without pushing is fine.
With that in mind, I can just apply the push without depending on the capsule collision but an overlap event on tick in server only.
So in the end, I think this could work since server alone will dictate where the dead body get pushed.
im not good at explaining so this may sound confusing.
Yeah I'm not 100% following with your specific use-case
I do have a solution for granting partial client authority solely for location, its useful for applying snare, knockback, stun, etc. without any de-sync (up to a point)
But if its affecting the local client colliding with simulated proxies when the server has already disabled their collision causing a correction it might not help you, because generally you wouldn't grant client auth just for killing someone, but you could
@grand kestrel would love to go through some of your github stuff one day. Trying to accumulate the basic to understand this monsterous CMC atm.
Its in the PredictedMovement repo, you can search the CMC on there for ClientAuth and copy those parts out
Not to sidetrack your question, but why is there a concern for the host ranking up quickly? If you use listen servers, then cheating should be expected anyway.
Your host can just kick everyone or kill them without pulling the Internet after all.
I just have a job to do and the question was asked of me, unfortunately.
Right
The person who asked should probably be informed that using a listen server will allow the host to do whatever they want anyway.
They have been informed
Pulling the cord is the smallest issue. The project should use dedicated servers. I will see, once I'm awake and walked the dog, if there is a callback or sorts for the disconnect.
Thank you. And yes I understand we should be using dedicated servers
Must be something on platform level as there is nothing internet wise that would check any connection
@pale yew Haven't found anything yet, but you could add this functionality yourself, as long as you have some webserver that you could create a SocketConnection to fwiw.
#include "Sockets.h"
#include "SocketSubsystem.h"
#include "Interfaces/IPv4/IPv4Address.h"
void USomeTickableWorldSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
ISocketSubsystem* const SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
if (SocketSubsystem == nullptr)
{
/// Might want to actively handle this cacse.
return;
}
/// You can define this in some Developer Settings for example.
const FString Address = TEXT("123.456.789.012");
constexpr int32 Port = 8912;
/// Create new FSocket.
Socket = SocketSubsystem->CreateSocket(/** SocketType = */ NAME_Stream, /** Description = */ TEXT("Internet Connection Tester"));
/// Parse the Address, this can be useful to ensure the IP isn't malformed.
FIPv4Address IP;
if (!FIPv4Address::Parse(Address, IP))
{
/// Might want to actively handle this cacse.
return;
}
/// Create a "proper" InternetAddress, needed for the FSocket::Connect function.
const TSharedRef<FInternetAddr> InternetAddress = SocketSubsystem->CreateInternetAddr();
/// Fill in IP and Port.
InternetAddress->SetIp(IP.Value);
InternetAddress->SetPort(Port);
/// Try to connect. Return value tells you if it worked or not.
const bool bConnected = Socket->Connect(*InternetAddress);
}
void USomeTickableWorldSubsystem::Tick(float DeltaTime)
{
/// Check if the Socket is valid and the connection state is correct.
/// Not sure if you want to count the Socket being invalid as not being connect.
if (Socket != nullptr && Socket->GetConnectionState() != SCS_Connected)
{
/// Handle not being connected.
}
}
The FSocket can provide you with information if the connection is active or not iirc.
do macros work differently when networked / not? i just pulled some logic out of my animation handler and it started working. But it wouldnt when i called the whole macro. Weird asf
Blueprint Macros?
Yes
Pretty sure Blueprint Macros are just wrappers for code to make it re-useable of sorts. Bit more fancy than Functions and Events, due to being able to have Latent nodes and multiple Exec pins in them, but lacking features like being able to be marked as an RPC.
So in other words, they shouldn't have anything to do with networking.
hmm..good to know. it must have failed somewhere then which i wil have to debug..
which will be intresting as you cannot put breakpoints inside macros afak 💀
Yeah I never really use Macros, like at all, despite the built in ones.
Cheers, thanks
I just had a look at UNetDriver, which would be the closest to what handles all the connections.
The biggest thing to take away is that the Server not being able to "connect" to the Internet isn't really UE's problem I guess.
Do you know what happens if you play as a ListenServer and you disconnect the internet? Does it put the Server back into the MainMenu after a while?
No the server can continue. It's the client that gets punted back to the main menu.
At least as far as I could tell.
Might there be a way to poll EOS in some way?
Hey I'm currently making stamina logic in blueprint. With my current setup, when player presses sprint, server rpc is called that runs a timeline and from timeline update, sets Stamina(float RepNotify) variable. Inside OnRep function, I set the progress bar percent inside player widget. I know this setup may not be ideal but is it very bad? If yes, then what solution should I use?
is your sprinting done in bp as well? Does it lag if you enable network emulation?
No it's in c++
Ideally you better update the UI by having the HUD class or the widget itself bind to an "Update Stamina Bar" delegate that is executed whenever stamina is changed
You should then calculate stamina inside the PerformMovement function in the CMC
Well I'm using timeline only because I want the progress bar to progress smoothly.
Oh I thought you were using it to update the stamina itself
Stamina is best calculated in the CMC, while the UI is like I said, using a delegate
So with what you suggest will the progress bar UI able to move smoothly?
having stamina done in the cmc will allow for client side prediction and server reconciliation in case of lag
Yes, given that stamina is set on tick when sprinting
I also tested it with network emulation and it does not cause any lag. I mean it would be ideal if it would be possible to do it just in blueprints because I don't have much experience in c++
Basically PerformMovement is a ticking function, you calculate stamina inside it, and if stamina has changed, then send a delegate
you're talking about updating the actual stamina or the progress bar?
Both would be ideal because player could only for example sprint when stamina is greater than 0.
what's wrong with the player only able to sprint when stamina is greater than 0? what do you want it to be like?
No I meant that player Should only be able to sprint when stamina is greater than 0. Currently I have stamina float that updates the progress bar in UI.
oh so you don't have a stamina system currently? just UI?
Here is the setup I have.
where is Drain Stamina called?
When player starts sprinting, a timer is set on the server that runs this function each 0.1 seconds
as for having the player only sprint when stamina is greater than 0, that's obvious how, it'll be just a branch
not sure how it'd be done in BP honestly... is there nothing about a networked stamina system online?
The setup I had before had a timeline that updates the stamina variable on each timeline update. I was worried that that would be sending too many informations over the network in a short time, thats why I switched to timer but now the progress bar isnt smooth since I'm directly setting the value.
what would be ideal is to have both the client and server set stamina inside a ticking function, and if there is a mismatch between client and server, then fix it
if the client sets stamina on its own, without an rpc, then updating the stamina UI becomes easy
But shouldn't the stamina be set on the server though?
Well it's not smooth because the client is waiting for Stamina to be replicated every single time, to update the bar
It's not really about mismatch. It's not smooth because in Drain stamina function, I subtract 0.01 from stamina. If I wanted it to be smoother, I should subtract less, but then the draining process would take longer. In that case it's best to use some sort of interpolation but that would end up setting the variable and calling on rep function every frame or so...
I mean, I'm speaking Ideally, which is doing it inside a custom CMC class, thus no, Stamina isn't a replicated variable, it's updated both in the server and client at the same time, but when there is a mismatch, the server is favored because they're the authority
Does anybody know how i would make a ragdoll replicate? ragdoll works on owning client but does not seem to update on the others
You're doing a client rpc. That will only go to the owning client. Use an onrep variable and inside the onrep, do your death logic.
That isn't multicast
Multicast would still be incorrect anyway.
still alot better xD
Unless you're destroying the actor after some time from dying I guess.
thats handled in my respawn event
Then multicast would be fine depending on how your game plays out.
would there be a way to make him not stiff as a board ?
That depends on your settings and all that. Not really multiplayer related.
ok
is it possible to use world partition in multiplayer?
I have a problem where, when the client teleports to another part of the map and then returns, all actors with physics have fallen through the landscape. My guess is that it's because that part of the landscape was unloaded
check the physics asset, there you can configure how the mesh will ragdoll
it works perfeclty on the owning client just not for the others
sorry if i pinged
you're not replicating ragdoll physics right? is the Replicate Movement property enabled?
yes
each machine should set simulate physics to true
ill check real quick
also disable any sort of collision on the dead actor
and set the collision profile to ragdoll
simulate physics to true should be done after disabling collision just in case
where would i find these
machine as in the abp
Ok I Got it Thank You
im trying to do the exact same thing
the ragdoll replicates, just desyncs
physics dont sync, and ive heard too many ppl say not to replicate physics
but i need the ragdoll physics to be replicated here 😭 idk how to go abt it
have u come up with a solution
What I did was Make custom events in the player bp SVR_Sim , In My Controller I Call It From My Bound DIspatcher From My Component OnRep_Dead, And My Death Event
and this is my end result
alr I'll take a look
just a question, if you were to move your ragdoll around, would it sync across all clients?
dont know thats not a feature planned for
ah
the ragdoll for me works, but like when the player kicks it around n such, it'll always desync
might need to constantly set the bone rotation and position in tick with a repnotify
what would your solution be?
Unless, for whatever reason, it is actually gameplay critical that dead bodies be in the exact same location and pose for everyone.
true it isnt critical
To just not do it. No one actually cares.
It is purely cosmetic.
my linux server is crashing repeatedly, what can cause this?
Signal 11 caught.
Malloc Size=262146 LargeMemoryPoolOffset=262162
CommonUnixCrashHandler: Signal=11
Failed to find symbol file, expected location:
"/mnt/d/ARMAServer/LinuxServer/ARMA/Binaries/Linux/ARMAServer-Linux-Shipping.sym"
[2025.05.06-19.45.56:739][265]LogCore: === Critical error: ===
Unhandled Exception: SIGSEGV: invalid attempt to read memory at address 0x00000001b71d1660
[2025.04.06-19.45.56:747][265]LogCore: Fatal error!
0x0000000006d49392 ARMAServer-Linux-Shipping!UnknownFunction(0x6b49392)
0x0000000008245716 ARMAServer-Linux-Shipping!UnknownFunction(0x8045715)
0x000000000747d11c ARMAServer-Linux-Shipping!UnknownFunction(0x727d11b)
0x0000000006efbe05 ARMAServer-Linux-Shipping!UnknownFunction(0x6cfbe04)
0x0000000006d03470 ARMAServer-Linux-Shipping!UnknownFunction(0x6b0346f)
0x00000000079012de ARMAServer-Linux-Shipping!UnknownFunction(0x77012dd)
0x000000000790226a ARMAServer-Linux-Shipping!UnknownFunction(0x7702269)
0x00000000078f536b ARMAServer-Linux-Shipping!UnknownFunction(0x76f536a)
0x00007fc8cc61a1ca libc.so.6!UnknownFunction(0x2a1c9)
0x00007fc8cc61a28b libc.so.6!__libc_start_main(+0x8a)
0x000000000380c029 ARMAServer-Linux-Shipping!UnknownFunction(0x360c028)
[2025.04.05-19.45.56:771][265]LogExit: Executing StaticShutdownAfterError
Engine crash handling finished; re-raising signal 11 for the default handler. Good bye.
Segmentation fault (core dumped)
Segmentation fault (core dumped)
well you don't have symbols, so who knows
i am testing it on wsl, no idea how to attach debugger to it
can i launch the linux server from visual studio?
you can attach to WSL sessions, but either way you need the symbol file
what i am doing now is compiling in vs and launching in wsl
i have the symbol files for non packaged
which should also crash
gotta enable that in project settings -> Packaging
^
if i build in developement server for linux, it never crash
seems like there is something not supported in shipping
but than it should not package if there is some not supported things exists
is there a function to get all player characters ?
i would just disable collision with it tbh
the PlayerArray of the gamestate
and then get each of their pawns
but you can just iterate over the actors as well, depending on timing the playerstates might not see their pawns quite yet if its inside of network reading
<@&213101288538374145>
guards, arrest this man at once
xD
How Would I Replicate An Aim Offset ? Bc This Get BaseAim Roation Aint Working For me when i look down i get a positive num for some reason it works fine when ran in standalone but not as clients
the pitch should be replicated in RemoteViewPitch
this looks like you are replicating your own rotation though
you may need to override pawn functions to get the new rotation
i got it thanks
How might a world subsystem check for authority? Is GetWorld()->GetNetMode() < NM_Client the way to go, or is there a better way?
Yes, if you read the comment on the ENetMode enum it should say anything < NM_Client is some form of a Server.
The implication of that being "authority".
yeah that's just what I was looking at. 😄
In my head I'm like "great, it's a server. Does that mean it has authority?" Which, I've never seen a scenario in UE where the server doesn't have authority. But that enum doesn't mention authority, so I thought I'd double check.
Client spawned actors - server won't have authority unless you link them up and give the server authority.
Will client-spawned actors even exist on the server to know about them?
No. Which is why I said the other parts of the message.
Continuing with this world subsystem: I'm making an RPC that can be called via said subsystem. Is there a way to find out what client called the RPC on the server? I'm guessing I can get other info from that like the player controller, character, etc.
Hi, I have an ability on my pawn class that when enabled/disabled I need a load of other actors to react to it and do some shit, I'm using an interface to do this but most of the stuff I need done on other actors only needs to happen for the player that's activated the ability, so for example, one of the things that happen when the ability is activated is the ambient sounds will fade out.. once IsUsingAbility is true it calls GetAllActorsWithInterface and calls the event on the interface passing in IsUsingAbility, my BP_Ambience class implements the interface so it can call an input on the Metasound to fade the sound out and back in again when the ability is disabled.
To make that sound fade out only for the player activating the ability I can pass the pawn through the interface and do a IsLocallyController check beforehand however once I add the pawn class reference to the interface it creates a dependency. Is it possible to make it so I can have it run only for the player activating the ability without passing the pawn class through the interface to avoid the dependency it would create or do i have just have to pass the pawn class through to be able to do what I want?
Subsystems arent replicated
So they dont support RPCs
shit.
if you want a singleton that is replicated the simple thing is to either use a manager actor or a component on some other replicated actor
replicating subsystems is not impossible but not really simple
I think I'd rather just create the actor. But this feels very much like a Unity engine thing to do 😄
Thank You Everyone That Helped Me I Now How Fully Replicated Physics Interaction System
why is the IsMoving check being replicated even tho it's not a replicated variable 😭
for example, if any client moves, it's set to true for all clients
@rugged oriole Because Velocity is affected by replicated data.
IsMoving is not being replicated.
It is just changing as a result of data that is replicated, but is abstracted away.
wdym
In the same way Velocity is.
how can I prevent that
What do you mean? Movement of a Character is something you typically will always want replicated.
velocity is being replicated?
im confused
the velocity of the character movement component is affected by actor transform replication from the owning character afaik
If this confuses you, you probably need to focus on SinglePlayer for a bit.
^
A Characters movement is replicated by default.
Therefore, it will update its Velocity based on any movement.
how would I go about doing an only local isMoving check then
And since you are querying the Velocity for setting IsMoving, this means its value is derived from something else that is replicated.
without using velocity
doesnt rlly make any sense, im trying to do a camera shake but it plays for all users, and the only way it could do that is if both the IsMoving check and IsSprinting check is true on all users, ok if velocity is being replicated and IsMoving is being set to true bcuz of that, that doesn't explain why IsSprinting is being set to true when it has nothing to do with character movement component and isnt a replicated variable
either that or im a complete idiot and it's client start camera shake plays that plays all clients
fixed it, forgot i can use Run on owning Client for custom event 👍
Get Local Role also saved my life
Why is that an RPC though?
I haven't read through all of it, but aren't you just playing some ScreenShackes or so based on the Character moving?
If that's all you want, you'd simply use a branch with "IsLocallyControlled" inside your Pawn/Character.
That will be True for the local instance of each player.
The LocalRole stuff above is somewhat redundant, as you arleady have the IsLocalController check there.
The Controller wouldn't even be valid on SimulatedProxy
Got a question on the net cull distance squared. The default is 225000000.0, and the square root 15000. Is that 15000 unreal engine units (150m), or 15000 meters?
UE units, 150 meters
Thank you. Does this mean that a client "forgets" an actor exists, or it just sits there not really recieving any updated information?
Client destroys the actor completely, if you enter relevancy range again a new one is spawned
Well, for an actor spawned at runtime anyway. For actors that are part of the map, they just sit there and get no updates
So the server keeps track of these actors that go out of range of relevancy? What happens in Listen Server architecture?
I'm fairly confident with a lot of multiplayer concepts, but relevancy in these cases has always been a bit unclear to me
Every frame the server evaluates whether an actor is relevant for a connection or not, and closes/opens the channel for that actor if it needs to.
Relevancy is per-client. Server of course doesn't have any relevancy concept, the actors always exist server side.
I assume that the check is skipped for actors that are always relevant
yee
and there is a timeout (default 5 seconds IIRC) to stop actors flitting in/out of relevancy frequently if you are right on the border - since opening/closing channels and spawning/despawning actors relatively speaking is costly.
yeah makes sense
I have no clue but when i added a pin off of simulated proxy it, it played on both screens
I’ve tried using the Is Local Controller check and got the same result
This, is excellent information to know. If you wanted the client to keep a copy but not necessarily destroy it, what would be the best method?
Don't think you can
OK thank you
I am trying to use max draw distance settings of bps
but cant to it
it is not even working on server
Didn't want to spam, but my problem seems like a multiplayer issue as much as a GAS one
edit: apparently the forward button in discord spams for you
And my follow-up comment:
Actually going through the debugger, one of two things happen:
- Attached to PIE: local role is sim proxy inside UE source ASC code (handle gameplay event)
- Attached to server: rider let's me know that the breakpoint won't be hit, and sure enough it isn't.
I would have thought that PIE local role would be auto proxy
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_CurrentStackCount, Category = "Item")
int32 CurrentStackCount = 1;
UFUNCTION()
virtual void OnRep_CurrentStackCount() {};``` Will it work when I will override this virtual method in the child class? What be called in the child class when CurrentStackCount will be replicated, CurrentStackCount will call this class function or child class function?
UPROPERTY(ReplicatedUsing = OnRep_MousePositionVector, BlueprintReadWrite, Category = "Movement")
FVector2D MousePositionVector;
UFUNCTION()
void OnRep_MousePositionVector(); // OnRep function for MousePositionVector
virtual bool UpdateHeadRotationPure() override;
^this works well assuming your OnRep function fires 😄
Hello!
What's a good checklist to go down to figure out why my materials are not replicating, but the meshes are?
Looks like this:
show your code
a material doesn't replicate, a reference to a material asset can
Ahh, okay which.. code specifically? My code is pretty.. I'm doing async loading, I have lots of interfaces, logic is pretty split
why does the right one have the black and white squares, where does that data come from?
is it just a texture or is it some runtime stuff
Its runtime, its being set here:
void AZBlock::UpdateDisplay()
{
UMaterialInstance* BlockMaterial = DisplayData->BlockMaterial.Get();
ensureAlways(BlockMaterial);
// TODO: Dunno if we should be creating the DIM every time.
UMaterialInstanceDynamic* NewMID = UMaterialInstanceDynamic::Create(
BlockMaterial,this);
if (NewMID)
{
BaseMesh->SetStaticMesh(DisplayData->BlockMesh.Get());
BaseMesh->SetMaterial(0, NewMID);
}
}
ok so what's DisplayData
where is the array of bools or whatever represents that state
UCLASS()
// TODO: This is used for Blocks in general and should be named as such. Not just elementals.
class ZONECONTROL_API UZBlockDisplayData : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
// "AssetType:GameplayIdentityTag"
virtual FPrimaryAssetId GetPrimaryAssetId() const override;
// Returns the GameplayIdentityTag.
FGameplayTag GetBlockTypeTag() const
{
return BlockTypeTag;
}
static FPrimaryAssetId GetFPrimaryAssetIdFromBlockTypeTag(const FGameplayTag& BlockTypeTag);
public:
// Primary material for the block.
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals", AssetRegistrySearchable)
TSoftObjectPtr<UMaterialInstance> BlockMaterial;
// Primary mesh for the block.
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Visuals", AssetRegistrySearchable)
TSoftObjectPtr<UStaticMesh> BlockMesh;
// GameplayIdentityTag. Describes what this block is trying to be.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tags")
FGameplayTag BlockTypeTag;
};
And that gets loaded asynchronously before the board is spawned
is a board one block or many blocks?
many blocks. I make sure its all loaded first here:
void AZGameMode::NotifyGameBoardDependenciesReady() const
{
bool bIsDependenciesReady = true;
bIsDependenciesReady &= bIsGameBoardDataReady;
bIsDependenciesReady &= bIsBlockBlueprintReady;
bIsDependenciesReady &= bIsElementalDataReady;
if (bIsDependenciesReady)
{
OnGameBoardDependenciesReadyDelegate.Broadcast();
}
}
What is the fundamental data a client needs to draw the same board
I'm guessing it's the BlockTypeTag right?
that indicates if it should be black or white?
Yeah it comes from my BlockState object
class ZONECONTROL_API UZBlockState : public UObject, public IZBlockStateView
which looks like this:
*/
UCLASS()
class ZONECONTROL_API UZBlockState : public UObject, public IZBlockStateView
{
GENERATED_BODY()
public:
// ~IZBlockStateView impl
UFUNCTION(BlueprintCallable)
virtual FGameplayTag GetBlockTypeTag() const override;
UFUNCTION(BlueprintCallable)
virtual int32 GetBlockId() const override { return BlockId; }
virtual FOnBlockStateChanged& GetOnBlockStateChangedDelegate() override { return OnBlockStateChangedDelegate; }
// ~End IZGameAssetProvider interface.
UFUNCTION(BlueprintCallable)
void SetBlockTypeTag(const FGameplayTag& NewBlockTypeTag);
UFUNCTION(BlueprintCallable)
void SetBlockId(int32 NewBlockId) { BlockId = NewBlockId; }
UPROPERTY(BlueprintAssignable)
FOnBlockStateChanged OnBlockStateChangedDelegate;
protected:
// Set on construction and never changed. Used to reference the owning player.
UPROPERTY(BlueprintReadOnly, Category = "Info")
int32 OwningPlayerId = -1;
// Set on construction and never changed. Use this if a handle is needed.
UPROPERTY(BlueprintReadOnly, Category = "Info")
int32 BlockId = 0;
// Use EBlockSide to position these values.
UPROPERTY(EditDefaultsOnly, Category = "Gameplay")
TArray<int32> PowerValues;
// GameplayTags for various mechanics.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
FGameplayTagContainer GameplayTags;
// Can be BlockType.Elemental.* or BlockType.Tile.*. Used to identify the type of block.
UPROPERTY(ReplicatedUsing = OnRep_BlockTypeTag, EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
FGameplayTag BlockTypeTag;
private:
// Replication
UFUNCTION()
void OnRep_BlockTypeTag();
// End Replication
};
yeah you're right this is a mess.
Anyways, you need to have some replicated state somewhere.
Somehow, somewhere, there needs to be 81 bools or tags or whatever that represents the state of the board
you could have a block be a replicated actor with a replicated tag, you could have a map of block ref to tag, you could have an array of tags, whatever.
but you need that data to be replicated, then everything can run the same from there
ohhh!! that's probably what it is, my ZGameState has the block states
private:
UPROPERTY(Replicated)
// TODO: Put this in docs somewhere:
TArray<TObjectPtr<UZBlockState>> GameBoardState;
but I don't think I'm implementing DOREPLIFETIME
OnRep_BlockTypeTag is where you should apply that, unless that's some leftover code
do you want a bunch of replicated blocks with replicated data, or just some single replicated aggregate?
Assuming this worked, and is correctly called when the tag is changed, this should be what triggers the block to change material LOCALLY
Well the idea is that the array of block states that GameState has is the source of truth. Its the only place that block states can be modified, and then the UI simply updates when its state updates
why even have the tags on the individual blocks then
choose one
either way, that's how you should do it.
OnRep_SomeState -> do what needs to happen when that state changes (swap material, set parameter, whatever)
that's a good point yeah, no need to cache the tag in two places. The blocks have a view into their data anyway
yeah all that gives you is the possibility to have a conflict, with no real benefits
yeah agree (i think that was leftover from an older design I had and I just hadn't relooked at that). So really all I need to do is make sure that the states are replicated properly in GameState, and remove the tag from the block object
At a certain point you might not need block objects at all.
Gamestate:
TArray<staticmeshcomponent> BlockMeshes
TArray<int32> BlockIDs
etc. Might end up going that way
but if you don't have thousands of them no real reason to go down that road IMO
Yeah I ended up splitting that out into a ZGameBoardManager which is a UWorldSubsystem. Just to kind of keep GameState as sort of a data only management thing, and the board manager is more of a "frontend" type object for lack of a better word
yeah i wish subsystems could replicate, that'd be dope
I'll need to tackle it eventually for my project, I have many subsystems, one per domain (mechanical, electrical, fluids, signals) and one per device type (engine, cockpit, wheel, propeller, gearbox, etc), each of which maintains an array of their things
Anyone know things about COND_Custom? I set a property to use that and I implemented PreReplication and call DOREPLIFETIME_ACTIVE_OVERRIDEit is always replicated.
Documentation here is pretty straightforward. https://dev.epicgames.com/documentation/en-us/unreal-engine/replicate-actor-properties-in-unreal-engine?application_version=5.5#custompropertyreplication
hehe, i did not know they didn't replicate! I don't think that changes anything for me but that's good to know.
BTW is this design like.. I know its a lot of plumbing but feels clean in terms of responsibility? Blocks are gonna have abilities and can there's gonna be a lot of logic for capturing and using those abilties. So I figured having the GameBoardManager be the thing that takes UI reqeusts and authoritatively checks if they're allowed, modifies the state, and then UI updates just work because its connected to the view via a onChanged delegate seemed clean?
Does anyone have any suggestions on how I can optimize these 10k+ actors for networking? I've implemented distance relevancy and made them not replicated until interacted with but I still spend a ton of performance on networking
The current implementation is probably not very performant by itself, but at rest a lot of time is still spent sending networking data that I don't quite understand
uh.. actually I think alot of my issues are coming from learning how UE replicates things.
This:
TScriptInterface<IZBlockStateView> BlockStateView = nullptr;
Is supposed to be just a lightweight view into the ZBlockState. It simply has getters. So the idea was to do this:
UCLASS()
class ZONECONTROL_API AZBlock : public AActor
{
GENERATED_BODY()
public:
AZBlock();
public:
UFUNCTION(BlueprintCallable)
void Init(TScriptInterface<IZBlockStateView> InBlockStateView,
TScriptInterface<IZBlockGameplayInterface> InGameplayInterface);
And pass it NewBlock->Init(BlockState, GameState); those objects. And then it can simply update its own UI by asking questions through the view.
But uh.. basically all of my interfaces are nullptr on the client. Does unreal just not support this kind of paradigm? Like.. maybe interfaces aren't allowed on clients or something?
why i'm getting this error when joining the session?
Client log
[2025.02.07-18.56.57:809][236]LogNet: Error: UEngine::BroadcastNetworkFailure: FailureType = ConnectionLost, ErrorString = Your connection to the host has been lost., Driver = Name:GameNetDriver Def:GameNetDriver IpNetDriver_0
[2025.02.07-18.56.57:813][237]LogNet: Error: UEngine::BroadcastNetworkFailure: FailureType = ConnectionLost, ErrorString = Your connection to the host has been lost., Driver = Name:GameNetDriver Def:GameNetDriver IpNetDriver_0
Server Log:
[2025.02.07-18.56.47:046][199]LogNet: UNetConnection::Close: [UNetConnection] RemoteAddr: 127.0.0.1:50720, Name: IpConnection_2147474725, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_2147482471, IsServer: YES, PC: BP_PlayerController_C_2147474719, Owner: BP_PlayerController_C_2147474719, UniqueId: NULL:DESKTOP-164L35-CBF269C49A7AE146D61D3456BC606496, Channels: 34, Time: 2025.04.07-18.56.47
[2025.02.07-18.56.47:049][199]LogNet: UNetConnection::SendCloseReason:
[2025.02.07-18.56.47:055][199]LogNet: - Result=MissingLevelPackage, ErrorContext="/Memory/ZCXHBH5BHUVE8BAYIGC9SJYIV,/Memory/ZCXHBH5BHUVE8BAYIGC9SJYIV"
[2025.02.07-18.56.47:059][199]LogNet: UChannel::Close: Sending CloseBunch. ChIndex == 0. Name: [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr: 127.0.0.1:50720, Name: IpConnection_2147474725, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_2147482471, IsServer: YES, PC: BP_PlayerController_C_2147474719, Owner: BP_PlayerController_C_2147474719, UniqueId: NULL:DESKTOP-164L35-CBF269C49A7AE146D61D3456BC606496
[2025.02.07-18.56.47:068][200]LogNet: NotifyAcceptingConnection accepted from: 127.0.0.1:50720
[2025.02.07-18.56.47:074][200]LogNet: NotifyAcceptingConnection accepted from: 127.0.0.1:50720
[2025.02.07-18.56.47:101][201]LogNet: NotifyAcceptingConnection accepted from: 127.0.0.1:50720
when joining a session hosted using small map works fine
session with a big open world map don't works
with big map i am getting this error as well
UNetDriver::TickDispatch: Very long time between ticks. DeltaTime: 21.22, Realtime: 21.22. IpNetDriver_2147482471
Would a low framerate on listen server (mostly from CPU) increase ping for connected clients?
yes
since whatever you're sending is taking more time to process, and more time for the results to get back to you
Thank you. Might be worth trying to cut down CPU fram time before delving into ping compensation and all the fun stuff
is it easier to do replication *In c++ Or Blueprints
hey im having some kind of issue with my multiplayer spawning, for some reason when additional players spawn in other players get their pawns unpossesed and i dont know why. i am very new to multiplayer/netcode stuff so i dont really have a clue as to why it has started to do this, it was working fine about 30 minutes ago
so like in this example you can see that after the second player in the smaller window loads in the first player to join gets their pawn unpossessed
is this allowed?
UPROPERTY(ReplicatedUsing = OnRep_BlockStateView, BlueprintReadOnly, Category = "Gameplay")
TScriptInterface<IZBlockStateView> BlockStateView = nullptr;
I've gone through every instance of my players being possessed and unpossessed and I think this intial spawning code from my game mode might be causing it, but I dont see why it would be doing it, it should just run through the list of connected player and spawn pawns for them
could it be my play settings? like whether im using standalone or listen server?
Welp I figured it out. Whether this actually reacts to changes properly remains to be seen but.. I just needed:
void AZBlock::OnRep_BlockStateView()
{
UpdateDisplay();
}
bool AZBlock::ReplicateSubobjects(UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags)
{
bool bWroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
if (BlockStateView.GetObject())
{
bWroteSomething |= Channel->ReplicateSubobject(BlockStateView.GetObject(), *Bunch, *RepFlags);
}
return bWroteSomething;
}
As well as I needed to guard UpdateDisplay to early out if BlockStateView was nullptr because that function apparently can get called before the view is fully replicated
Ok I believe I figured it out, i wasn't check if the player controller already had a pawn so it would get overriden
you can get by with some basic stuff in bp but its really best done in c++
replicating a property in c++ though is several steps whereas you just tick a box in bp
So far its going quite well replicating in cpp to me it feels easier and some i might need to do it in c++ just because im replicating some physics
ah yeah c++ lets you override functions that run after replication which is needed for physics stuff afaik
ok another issue, im having an issue where my client players are not considered to be locally controlled? how do i change this
Pawns should only be considered locally controlled if they're possessed by the local player's controller. Any other pawns would not be considered locally controlled.
But like when I have the player Pawns print their own locally controlled status they say its false
Why do you use plural? A player can only possess a pawn.
If I'm playing with 6 players where each person have their own pawn.
My pawn will return IsLocallyControlled true.
Rest are false.
So does islocallycontrolled only apply to the player connected to/hosting the server?
?
Ohhh I see what you mean
Can you reword your question.
What does player connect to / hosting the server even mean.
You just describe both client and server.
Not that locallycontrolled have anything to do with it.
Everyone is running their own instance.
You run your unreal.exe
I run mine.exe
We both execute codes
They don't happend in one instance. I hope this give you perspective.
It does to an extent, yeah
So if you run is locally controlled check in your machine.
You will get your possessed pawn return true
While the rest of the pawn to be false
And the same thing when I run the same function.
I will have my possessed pawn return true
While the pawn that belong to you in my world return false.
You can test this easily
Create a text component.
On tick, write true if is locally controlled is true and false otherwise.
Then just play the game with 3 players.
Yeah I think I understand, at least somewhat
Just do the above exercise and you won't have to guess anymore.
Understanding roles and locally controlled actor is very important to split codes
I literally started doing multiplayer stuff like a week ago so I guess I still haven't wrapped my head around the framework of it all
How can i pass the string as FUniqueNetIdRepl ?
void AARMAGameModeBase::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
{
Super::PreLogin(Options, Address, GameplayStatics::ParseOption(Options, "480"), ErrorMessage);
}
error C2664: 'void AGameModeBase::PreLogin(const FString &,const FString &,const FUniqueNetIdRepl &,FString &)': cannot convert argument 3 from 'const FString' to 'const FUniqueNetIdRepl &'
FString UGameplayStatics::ParseOption( FString Options, const FString& Key )
{
FString ReturnValue;
FString Pair, PairKey, PairValue;
while( GrabOption( Options, Pair ) )
{
GetKeyValue( Pair, PairKey, PairValue );
if (Key == PairKey)
{
ReturnValue = MoveTemp(PairValue);
break;
}
}
return ReturnValue;
}
FUniqueNetIdRepl::UniqueIdFromString()
UniqueIdFromString ( FName Type, const FString& Contents)
?
testing it now thanks
this is a protected method, is there any public accessor to it?
If the code is short. Can't just copy paste to a new function?
linked in many headers
void FUniqueNetIdRepl::UniqueIdFromString(FName Type, const FString& Contents)
{
// Don't need to distinguish OSS interfaces here with world because we just want the create function below
FUniqueNetIdWrapper UniqueNetIdWrapper = UOnlineEngineInterface::Get()->CreateUniquePlayerIdWrapper(Contents, Type);
SetUniqueNetId(UniqueNetIdWrapper.GetUniqueNetId());
}
im still experiencing a discrepancy between players with regards to the locally controlled player thing, I have this multicast event begin play node where if the controller is a local controller it will add a hud to the player's viewport, whereas if not it just prints out some text. When I run the game in listen server mode the first player that joins (I assume they are the "host") gets their hud no problem, but the second player does not and prints the text (in the 2nd screenshot the right window is the "server")
Player Controllers don't replicate to all clients. Only to the owning client. This also means it's kind of pointless to multicast on them.
huh ok, hooking it into the normal begin play seems to at least paritally fix it
Checking if it's a local controller on begin play should be enough to ensure that local players only create the hud. Ideally you would probably use the HUD class to create and add your widget which is created for locally controlled player controllers, so then you don't even need to do a local check at all.
Are you talking about the default hud class in the game mode?
Yep
ended with this. 😄
void AARMAGameModeBase::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
{
ErrorMessage = GameSession->ApproveLogin(Options);
FGameModeEvents::GameModePreLoginEvent.Broadcast(this, UniqueId, ErrorMessage);
}
How can I make the Collision Profile of a collider replicate? For a Character's capsule.
Multicast is server telling everyone that have a copy of the actor to run the function.
I think you need to read the pinned material first. Get to know what's replicated or not.
All controllers exist on server but clients only know their own controller.
You need to have a sync value that dictate the profile.
I used enum to describe the character mobility
OnRep->
Switch (mobility)
If pushable
Set collision profile to pawn, etc.
Or i guess you can replicate a struct that contain all the info that you need to replicate.
yeah you would want something specific to the game imo that describes either being default or the pushable mode
each thing can define what the default is (or even from the cdo)
So right now my dedicated server (Dasv4- 2 cores) craps out with 200 NPCs in play.
The NPCs are replicated characters with an AI controller, State Tree, and a GAS component.
Game has an isometric camera and I can really shrink the net cull. So far I've kept what I believe to be "heavy" logic away from tick. I could add more cores to the hardware, but I'd prefer not to. What are my options to get this up to the 1000 range?
I'm considering maybe Mass, or perhaps moving away from "Character" - but I think I'd need my own movement system, right?
so have you profiled it?
also no more cores will not save you here unfortunately as the cmc is entirely single threaded
there is an experimental async one that I have not seen used
I would say with such a low count you should be able to just manually tick them round-robin style and see heavy gains
I have not profiled it against the prod environment. I'm hosting in PlayFab and I haven't quite figured out how to remote profile.
you could even profile locally and see roughly similar numbers? why even ask about performance if you haven't clicked the insights button?
it's very easy to profile in modern unreal, you do not need to use the awful csv profiler
insights also works remotely but I'm not sure how that works with playfab
Just re-pinging this because it's been a bit, looking for some help with improving networking performance with lots of actors
step #1 is to not represent these as replicated actors... this should be sent in a compressed way
I think you could keep the "distance based" property of net cull distance by having like one actor represent a set of these squares rather than 1 per square
I have 0 info on how these change either, I have no idea what you are trying to do
also would help to enable push model networking as just polling these will be insanely costly
purely academic question: in theory you could simply replace all the networking in the CMC with RPCs as opposed to the saved moves that it does and now you have lockstep movement, yeah?
how do you think saved moves are sent?
saved moves are confusing but they really are just rpcs sent over
changing WHAT they do and how they are read back is something though I guess
and how they work on sim proxies is mostly just the actor transform+ velocity onrep and some other properties (which can come in at random frame times btw lol)
so there is absolutely a world where you send the inputs to sim proxies as well to get a "rollback" setup
Hmm yeah that definitely makes sense, currently like you said each square is its own actor (technically the mesh itself is a child actor component which is intentional but is probably less performant, this is why I'm trying to get a base test without any sort of interaction)
I'll look into push model networking, I've never heard of that, so thank you!
one actor represent a set of these squares rather than 1 per square
Is there another method of doing this, outside of refactoring these actors to basically combine them into one? That's the only thing I can think of initially, outside of an engine system that I don't know about
"Is there another method of doing this" you still haven't described what "this" is
How do I prevent this from happing. I tired changing my collision setting and that didn't seem to fix it.
Sorry that was meant to be a quote, formatting got messed up when I copy/pasted it - I was referring to your suggestion:
one actor represent a set of these squares rather than 1 per square
So I'm asking if there's another way of combining these actors for networking/replication outside of just actually making them one actor
I am asking about what the squares are supposed to be replicating for the game
Honestly I'm just worried about improving the standing performance of all these actors, I'd like the static existence of all these actors to not sacrifice 20ms of CPU time every frame, and then I'll see if I can optimize their actual function
Sorry if that's unhelpful but ultimately I'm just trying to understand why these actors themselves are sending so much data without doing anything / being relevant
okay if this is just a proof of concept to see what happens I don't think I can say anything about how to make it better without knowing what the cubes are supposed to do
turns out having 10k actor channels that neat to check for dirty properties is expensive :U
Let's just say the cubes are supposed to be static then and not do anything if that helps
if they are static then they should just be part of the level itself
I didn't know that's what it was checking / sending data for, that makes sense
you may need to turn on more profiling events like named events to see more detailed info
Ohhh didn't know that was there, thank you!
you did profile at least so you are headed in the right direction
a lot of people underestimate how you can see what is slow in your game by pressing 2 buttons lol
Let me see what that says, hopefully that will point me in the right direction and then I'll try to see if I can group the actors like you said as well
(not everything is represented well in insights but it's going to show... something)
yeah getting comfortable with profiling is super helpful lol
Honestly I work with it in my job and this is the first time I've ever thought about using it for my personal work - I like forgot I could use it
It's more than two buttons, at least for me. I've profiled non-prod and I think I've traced mine to the CMC but honestly, I have no idea what I am looking for.
I would say my dumb guess for how to send them would be to represent each cube as a bit in an array replicated down as a single struct, where it only changes when cubes have something change on them
so the client represents them as meshes but they are not really network objects, but local only things that react to onreps from a manager actor
neither do I because I can't see anything
in general when profiling in the editor things will be a lot slower than a shipping build
you can make local builds just for profiling too, test builds are useful for this as they are mostly optimized in comparison to a debug build
basically you are looking for why the frame took a long time
if something is huge, you figure out why and if it needs to be
Oh yeah this is much more helpful, I'd seen people use stat named events but honestly didn't know what it did lol, thanks again
stat named events makes things run tad slower but they emit events that the old CSV profiler would read, but insights can see them too
this is why it makes a giant "hey, stat named events are on" warning to tell you it will be slow
it actually makes blueprint assets show up as their names in the graph as well
as a rule of thumb 60fps is about 16.67777ms
so this netbroadcast tick time is taking... the entire frame
Is that helpful?
actually yes... I am not sure if these are okay to share though as it might reveal some info about where it is stored on your pc
probably just file addresses though
I see that, not concerned.
the one thing I would add to this trace would be tasks
but this is good because it covers the bases of cpu stuff
I am using a .bat file to start the server with -trace=log,bookmark,frame,cpu,gpu,loadtime,file,net
Would I just add "tasks"? What does that give me visibility in to?
ps. In that trace, I spawn 200 NPCs around frame 2556. Prior is ~100 NPCs
yep that's a lot of cmc ticks lol
Does Mass solve the CMC issue?
it is a for loop
How the heck did you figure that out?
an ECS library ultimately is just querying for similar things and executing stuff in parallel
yes it makes stuff fast
but you have to give it stuff to do
and it cannot magically solve things that are inter-dependant without some help
one reason the cmc must run on the main thread is that is modifies things that the main thread reads
like physics bodies and actor transforms, things it hits
did they remove widgets staying in seamless server travel or is my own stuff just bugged
what you have here in this trace at a surface level
- general cmc traces to check floor that you kind of can assume is there with navwalking
- moving kinematic bones you might not need to move
- updating all animations every single frame
I appreciate this. I'm very curious to learn how you pulled this from the trace.
I don’t mean to interrupt anything but I’m so frustrated and confused that I know I’m missing something important. I’m trying to keep my clients and server very separated(I just need my server to run an occasional RPC) but it feels like Unreal is fighting me every step of the way. Like I’m trying to get my client’s controller to possess another pawn, but for some reason the possess node only runs on the server. Why does my server, who just processes data storage, need to know what pawn the client is controlling? Is there actually no way to possess a pawn locally?
I zoomed in and read the function names
this is a single cmc
the sweeps are quite cheep but updating the kinematic bone collision bodies is 2x the cost for... I don't know
if you aren't actively using the physics body every frame why update it I guess
it's a commonly used optimization strategy to just not udpate these unless needed
this is the physics bodies bound the the skeleton which I don't know if you use
I only use them on death, when I enable ragdoll.
Yeah - you lack the understanding of UE's entire networking architecture it seems. It is server authoritative. Meaning the server is the one true version of the game.
The server needs to know because it is the ultimate authority for the game.
It shouldn’t matter what the true version of the game is. I’m able to spawn actors only on the client, and I’m able to call rpcs from things that exist on the client but not the server(I think). So why is player character possession any different?
Because in the eyes of the server, the player controller is the player. So they need to have network authority over what they possess. If it just blindly lets anyone have network authority of anyone else, it would be a disaster.
there is one case of something being locally posessed (spectating) but it is a unique case
I get that player controllers are special, but it still doesn’t make sense to me why the server needs the character. And in my case other characters aren’t even spawned into clients. But assuming that the server does need to know about a client possessing something, what would be the cheapest way to show replicate that possession back to the client? I haven’t had a need to use conventional replication until now. AFAIK the lowest replication rate is twice a second? Is there a way to only tell the client about the possession when it happens? (Also what do I even replicate to the client to tell them about the possession)
and it requires a lot of c++ overrides
Literally just do a server rpc to do the possession. It is that simple.
the character can be local only and you could have a dummy pawn serve as the possessed thing
you can ignore possession and just forward input + camera
but why change this for no reason
So if I call possess on the server that automatically gets replicated to the client?
Yes
Can I have something like a plain UObject as a member of an actor contain all the implementation for my RPCs? I'm looking for something lightweight, and a way to declutter my character class, and RPCs are easily the biggest eyesore there.
yep
actor components can rpc
but they must be owned by something that can rpc the same way
this is good way to cut down on rpc spaghetti
you can but I don't know why you would use uobject
use a component and then you can take advantage of GetComponentByClass
just make sure you actually mark it to replicate if using the subobject list etc
the docs do a decent job of showing how to do this iirc
Lightest weight possible was what I was thinking. Megafunk mentioned components, but don't actor components have their own transform that have to update?
(even uobjects have way more bloat than I want. It'd be nice to just throw it all in a raw c++ class)
actor components are not scene components (scene components extend actor components to have a transform)
if being heavy is an issue describe the actual performance problem and scale at hand
if you don't want to use objects you may have a difficult time in the unreal engine gameplay framework
network "manager" objects that have state for everything at once (or an area) can be a good way to gather state for multiple things in one place I guess, but you lose out on controlling them as individual things etc
if memory overhead is an actual issue from just actor components I think you are doing some serious heavy-weight stuff lol
a single art asset will instantly dwarf the memory consumed by almost any component
unreal objects have a lot of pointless stuff taped on them for legacy reasons but individual actor components are not the problem
Also - turn on Deferred Kinematic Updates, assuming this is being done in PrePhysics
tbf it's rare you don't want some kind of collision on your characters skel mesh
If you're using Mover, you have to make engine changes to make deferred kinematics work.
I get confused by all the 'CPU Stall - wait for even't entries in the profiler
IIRC that usually means that thread is stalled waiting for another to finish. If you have the "Tasks" channel enabled in the profiler you can see what it's waiting on by clicking on it, and you'll see an arrow with the dependency.
Assuming you're using insights that is and not the old profiler
UActorComponents don't. Replicated UObjects have additional networking overhead of their own.
There's a reason CharacterMovementComponent calls RPCs on the parent actor, not itself.
I use the profiler from 'Session Frontend'
after saving a log with startfile/ stopfile
That's the old one. Use insights instead.
https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-insights-in-unreal-engine
Insights is actually amazing
they should seriously just have the old csv profiler go "you probably want insights" lol
I can imagine there are still situations where it makes sense but... I do not know why you would when insights is around
So i have searched absolutely every where trying to figure out whats wrong .. but no mater what i try Bone Rotation simply will not replicate.. so i found a a odd bit of information that was talking about the variable needing to be to in GameState so i tried this dispite getting the feeling its not right .. but doing this i discovered it causes all the clients to recieve the same rotation ... now i get what replication in the game state is for .. but i just do not understand how its not replicated from my BP which deals with the controller input .. it doesnt need the controller varaiables as the variable belongs to the Fore mentioned BP.. Replicated/Replicate Movement is enabled for the BP and headrotation/mousepositionvector are set to replicate.. the Animation BP updates its own version of the varaiables from those replicated ones.. which still leaves me confused because the Bone Modify sets there own rotation.. so then i see that the varaiables can also be replicated in side the AnimBP... but does match any other guides.. as I mention (every single guide is a toggle switch 🤣) onRep Notify wont help as thats just saving the variable being fully replicated to my understanding.. if any one has any thing for me on this i would really appreciate it
I searched online but couldn't find any, does nanite work for multiplayer?
nanite is a way to render meshes
this does not affect how multiplayer works to my knowledge
oops the srv event is set to mc there but regardless even with run on server it still dosnt work
?
the possessed pawn/ player controller rule is for client -> server rpcs as they must be objects owned by the connection
Multicast RPCs work on any actor that is replicated. Client/Server RPCs work on any actor as long as there's an owner
the server can RPC any replicated network stable actor whenever
so this actor not owned?
ah wait
when i spawn the MGT_Commander BP i never gave it a instigator node
could that be causing all this?
Well the owner is the relevant one
that appears to be a server multicast rpc so if the server created it and it is replicated it should work as expected
assuming you actually call this on the server
and it is replicated
Did he said variable can be replicated inside anim bp?
Probably just misundertood
Since he paste a tutorial with incorrect title
"How to replicate variable in anim bp"
Bad title, abp don't replicate.
@dire burrow
Project Files: https://www.patreon.com/posts/99635410 .
In this unreal engine tutorial, I am going to show you how to replicated variables in animation blueprint variables. Here what i do is, Using a variable in the character blueprint with "RepNotify" replication settings and then using the OnReplicate function for that variable to restore and...
I think your onto something if you look at the Spawns owner node it states that it can be left empty but is used for replication
What ever you want to replicate need to exist outside your anim bp. And the anim bp read the replicated var
isn't this guy one of the known unreal shitposters?
quantity over quality
yeah i did try with code like mes guide that one ifirc is oriented to a animation montage
@lost inlet probably, I seen few of his stuff, kinda don't like it.
He does rpc inside GA too
hm maybe i should revist that... but yeah i dont know what to give the owner node of the bp spawn i guess giving it something would just give me peice of mind
For the record I am just warning the title of the video you watch. Not really saying you should learn from it.
what ever you need to replicate need to exist in an actor that is replicated.
yeah
i think i've watched it couple of times and dawn the same conclusion its not helping me with my issues
but yeah i just plugged in getparentactor to owner of the bp spawn
Code Like Me should absolutely be one of the channels you ignore
UAnimInstance isn't replicated in any way, so yeah, the only option is to read properties from the owning actor which is replicated
And if it's something that infrequently updates look into using delegates for that (event dispatchers for the BP term)
ok fingers cross this might be why... might be the case if you spawn and it doesnt have a owner actor it wont replicate by default
Just need to mark the actor as replicate
oh ok
As previously mentioned, client/server RPCs need an owner. Client RPCs have one intended recipient, the owner
You can only send a Server RPC as the owner of an actor
But multicasts and replicated properties have no such requirement
Can't help but to say multicasting is most likely the incorrect move for what ever you want to do there.
If you need to rotate the head bone then use replicated variable.
Client can send Server rpc then server will replicate the value to all other client.
Other clients can just set the incoming value with interpolation on tick.
As a general rule of thumb. Multicast = one shot events, property with OnRep = any persisting state changes
Though the OnRep is optional, that depends if you need to do something to react to the state change
is it normal for server gameinstance to have variables reset when using servertravel?
e.g valid pointer ref becomes invalid
/ struct becomes empty etc
depends what they are I guess
FStruct SelectedCharacterData
1.) character class reference
2.) 'get player name' fstring var
EventOnPostLogin fails to retrieve the values as it says array is empty
seamless travel is enabled
I mean nothing will just randomly get nuked, unless it's referencing an actor in a UWorld or something
think i figured it out
I dynamically swap the gamemodes thus OnPostLogin wasnt being triggered after switch
I think you're arbitrarily moving functions somewhere they probably shouldn't be in that case
We have an Actor whose only purpose is to do RPCs, but it's an RTS game so the amount of player input is very limited compared to another type of game.
I would not overcomplicate yourself and just have a nice ordered section in your actor(s) for netcode if that makes sense.
Hi guys, I have a strange replication issue. I tried so many thing but still not working.
The clients cant see the particles. Test on Client with print string: "Server: Before MCExplodeEffects" and "Server:MCEffects".
So the clients dont execute the multicast code, but the server calls the mutilcast correctly.
SR_Explode is called via this structure: CharacterBP{ Primary(Run on Server)->ActionShoot-> } GunBP {Shoot->HitTrace->} ExplosiveBP{ SR_Explode}
Without class advices:
Primary(Run on Server)->ActionShoot->Shoot->HitTrace->SR_Explode
You're saying multicast isn't even received by the clients?
yes thats right. They printing nothing. And every important actor is set to replicates
Does the server existing actor firing the multicast exist on the clients as well?
I thing so. I've put an print string on event begin play of the ExplosiveBP Actor. Server and both clients are printing. And the SR_Explode is firing later
Dumb question, but is that actor replicated?
yes thats why I am so confused
Running it on the beginplay is what's causing you the problem
The SR_Explode is not firing on begin play only the print string to check
The SR_Explode is firing after I press the left mouse button
How is the actor spawned?
In CharacterBP with the Event Primary(Run on Server) (first picture). And the use function looks like that (second picture)
Oh and the event use is not replicated(Forgot to deactivate it)
Otherwise it would be double run on server
So that LineTrace is being run on the server?
yes
and everyone sees the claymore after placing. But when I shoot it the clients dont see the particles
Is it being destroyed on the server?
yes
So
My guess is that it's getting destroyed and that replicates
And the explosion effect never plays because the actor is destroyed
Most networking is batched every frame IIRC
Can't necessarily guarantee order of anything either
Oh that was exactly the problemxD
thanks
As to how to actually fix that I'm not sure
Could just play the explosion effect when destroyed
Or the easy but bad way is to make a short delay or timerxD
Try using the OnActorDestroyed delegate
Otherwise you could: Make actor invisible --> Spawn particles --> Destroy
That would likely still result in it being destroyed before doing anything
This is probably the best way
Though how you would decide if it's destroyed because it's exploding or just normally is an issue
Someone with more experience here probably has input
Or just don't rely on the actor to spawn the particles in the first place
For something simple like this, instead of immediately destroying the actor, you could use SetLifeSpan and give a brief duration that could be slightly longer than your particle system plays back for, just ensuring that it should play and finsih on any clients as well and when the lifespan is up, it'll get destroyed as normal.
It's actually quite normal to destory after a delay.
You usually set some OnRep boolean or so that indicates that the actor is basically about to be destroyed.
In the OnRep function you turn off visibility and collision.
And the Server then destroy it after the delay or via lifespan.
If you want to be fancy and you have C++ access, use "TearOff" and "TornOff".
That cuts off replication and leaves it in the hands of the client to destroy the actor.
hey yall!
I'm running into niche situation and curious how other people dealt with this.
Player A creates a session -> Player B starts to execute join session on Player A's Session -> Player A Destroys session (While Player B is joining)-> Player B joins in on Player A's Level
This leaves the 2 players together connected in the same level replicating to each other but Player A's Session is destroyed and Player B's Session is valid.
How could I stop Player B from finishing the join session execution if Player A has already destroyed the session? Or alternately is there a different way to handle this situation?
(Btw , when player B joins I do not see any issues , all tested replication and functionality still works as expected BUT i feel like there are forsure potential issues if moving forward because one player is in session and the other is not lol , Also if player A destroyed session , the whole point is to not allow other players to join and another player joining in on a "Closed Lobby" is an issue .
Are you aware of the fact that "Session" and "Server Connection" are two separate concepts?
A Session is simply a set of information. Such as the name of the server, how many and which players are in it, how to connect to the server etc.
The Server Connection can be established without the need for a Session. And a Session can be created and joined without ever connecting to the Server.
If you want to stop a player from connecting, then you have to stop the part where the Server is listening for incoming connections. Usually done by simply performing another HardTravel to any level.
You can probably also somehow stop listening via C++ without traveling.
Destroying the Session doesn't stop a player that is already connecting from doing so.
You can, however, use PreLogin/Login/PostLogin in the GameMode to potentially check if the Server still has an active Session and if not deny the player.
So I setup a test project for this and... seems to be true, widgets don't stay anymore during seamless server travel. Would be nice if they updated the docs
And I still don’t understand the alternative solutions either. GetMoviePlayer->PlayMovie doesn’t seem to work
hey guys, this is a multiplayer question but it also involves some physics
im trying to make a system where players can push a ball around smoothly. Ive been experimenting with the predictive interpolation and resimulation settings, applying the impulse on the client first and then again on the server, however this is pretty unstable and i can see correction happenning. I really need the balls physics to be smooth for all clients so, what do?
yes! through testing i'm understanding that a Session and a Server Connection are 2 separate things. Still trying to fully understand the difference between them though and how users interact with the 2. Viewing the session as "simply a set of information" helps differentiate the 2 concepts.
Like you are saying , i need to stop the part where the Server is listening for incoming connections . I have tested and see how performing a hard travel could accomplish this. But for my scenario i need the host to stay in the same level , so im looking for a way to stop listening without traveling.
I know some devs on rolled out also needed this feature and they simply subbed in a deterministic physics engine. perhaps you could also sync the applied forces. also I've observed it to not be so bad, so in general i'm not sure
there's also ways to make it smooth itself even during correction
do you need super inmediate response?
I see there is UGameInstance::EnableListenServer , and i have been able to successfully use this during runtime to change a level into a listen server. But in a previous post you mentioned using this could lead to some issues. If there is a clean way to Stop Listening while staying in the same level , and then go back to listening when needed WHILE still staying in the same level , then i think i will be a able to get my desired outcome.
^
Hack workaround to get the seamless servertravel umg loading screen for 5.4 and 5.5 (since it was removed) for others interested:
it can also be done very easily in c++ as well, I just did in blueprint since it was faster
I just didn't wanna fuck around with MoviePlayer and Slate or Lyra loading plugin no more
Have you messed with the default correction settings?
They are very strict by default
When adding another variable that needs replicated as much as something like actor rotation, is there a preferred method of doing so?
No i havent, good shout. What settings in particular?
Error per distance, error per angle, max restored error, etc
Turn on net.showcorrections 1 to see the error and the accumulation
Thanks for the response. Kicking the player if server is not in session on PostLogin is working right now . Will continue to test it out 🙏
If they're replicated
Hello everyone. Can anyone help with advice, a tutorial, or a link to documentation on how to integrate a dedicated Steam server into a project? I want to implement a quick matchmaking system like in CS:GO or Dota 2. No matter how much I search, I can’t seem to figure this topic out.
Can i use NULL SUBSYSTEM so the clients around the globe can connect to the server?
the null subsystem has no backing online service, it's just directly connecting to other machines through an IP
this is what i want, will port forward and give them the ip address
ofcourse i have a virtually sets up teh vpn to hide my real ip and packet filter behind firewall
so i have completely disable the steam platform right?
the ID 480 is origin limited thats why i will use null if it will work
Hey guys, I’m having a weird issue with server travel via Steam.
I have both the listen server and a client in the lobby. When the server initiates a server travel, the client joins the session but doesn't have an assigned player controller.
However, if the client closes the game and rejoins the session, they do get a controller 😄 Any idea what might be causing this?
man i still remain firmly stuck with head/spine rotation
I you using the get player controller by index?
i know that can cause some weird controller assignment issues
Don't use delays in multiplayer for initialization purposes. For this one, use OnControllerChangedEvent
some usefull tips regarding how not to deal with controllers in this
https://wizardcell.com/unreal/multiplayer-tips-and-tricks/#1-get-to-know-the-game-framework-objects-online-wise
never use delay for initilization. You can't assume player's ping.
Read what Tony said
so this one instead
in short your issue may derived from the fact that the pawn isn't possesed by the client yet but your begin play is already called.
So naturally your is LocalltControlled check will fail
for the most part OnBeginPlay isn;'t the right place to init anything on multiplayer either.
ah yeah he needs the "wait for me" stuff
if you need to do something when the player already have a character then use events that are called after possession.
For blueprint, perhaps Receive Controlled Changed
if you do C++, I use AcknowledgePossession event
yeah if you have say blueprint and it wants to talk to the character for example but its not ready yet .... i have seen this used in various things
Yes
That's extremely lame
Lyra did it for player state. I don't know why, but yeah altough I don't have anything remotely like this.
Maybe okay to do as last resort.
imo repnotify does the job most of the time.
IMO it's alright doing that in places where you don't have a good hook or you're simply lazy to make one, but in base things like PC/PS/CH you have enough entry points to make it event based. I sometimes do that in UI when it's something like GS or a component that might not be replicated in time, but I never do that when it's related to some important initialization
yeah i personally switched to character manager interface so my other bps can be informed when the character initilized all its crap
but yeah i didnt know there was a specific event till recently so probably going to deprecate it in my stuff
but i feel like the C++ interface does perform faster then graphs.. it might just a be a placebo effect not sure
just hate the bitchyness of the syntax of UFUNCTION & CO + C++ bitchyness Class inhierentence layered on top of that
only made worse when you want to test replication
idk which kind of performance we're talking about but always profile if that's relevant
yeah i duno it just seems cleaner and when the multiplayer clients run.. looks kind of smoother then what i was seeing before in the animations department
I just want to change the entire animation bp to pure interfaces
no more sequence
i think the performance gain might be simply that A] my headrotation was a macro in the sequence and B] now its not perminently in the sequence being checked if is valid blabla bla .. now it just gets straight to work only when it needs to work
also i learned macros are slow
do not use them for functionality
???
That's super nice, but that's not necessarly related to performance, it's maybe just different logic
But in general the only way to assess performance is profiling and anything other than that is very subjective and likely even wrong.
yeah totally you will never know which exact functions are chewing the cpu and memory
with out doing that
something like chatbot gpt ha.. will probably sit there and do all the profiling for you in realtime in the future
but yeah just running my editor in full debug mode slows me to a crawl ... these days
which is a good enough indicator in its own right
like you know how debug mode sits there with the cpu graph/memory load etc
it'll be nice when VS's on-demand de-optimisation thingy will be more commonplace
I usually profile on a dev packaged game if I want close to real data
but yeah i am super bummed that we cant just simply (in graph/editor) replicate the animation bp's variables .. or replicate the controlling bp's variables ... its just like some bug stops this from happening with metahmans
they dont respond to the C++ replicated headrotation/mousepositionvector
its just a dead end
but yeah if these specific animation bps can be "replicated"
then why dont they? with out any thing else
why are they even there then in the animation bp?
if the anim bp cant "bReplicates"
for the 10th time, anim bluerpint don't replicate
so any variable you declare in anim bp will not replicate
doesn't matter if you mark it as replicate or not
So the variable it just doing that because it doesnt know any better but then to expose the replication properties?
This interface is also confusing, I don't even know how this get executed
its a interface another bp calls it
anyone know how to make the cloth physics work only on clients and not replicate the stuff from the server? I can see lot of issues and hitches on the client when watching serwer cloth.
your bp shouldn't even know it's anim instance
it's the other way around
anim instance read from it's owner
its totally can do that though .. it just gets the mesh from the character then gets the animation instance then casts it to ABP_MANNY then runs the implemented interface event function
My suggestion is to try and replicate pitch first, then go back to your system afterward.
just because you can, doesn't mean you should.
This is terrible practice.
Just like widget, anim instance job is to read from it's owner.
the owner shouldn't need to know about the anim instance
ok i just figured that if i want all my movement code and various systems centralized into 1 kind of portable bp with out having to worry about screwing up my mh character all the time i would try and keep every thing inside 1 commander bp
What? No
yeah in general just replicate core game logic and drive the rest of the state (anims, visual effects, widgets, etc) from the gamepaly data locally
yeah, just replicate what's needed. I would simulate the result locally if possible.
yep
some things don't even need to be replicated.
yes exactly
e.g a character head looking at the closest character.
half of every thing i am doing with out a single shot fired which is what frustrates me with this
yeah most of the time it's not very important or can just be locally calculated, saving precious kbs of internet data and your sanity
as i said if i replicated the variables in the movement component with just "Replicated" it shouldnt of not worked for the head rotation
Why would it?
marking a variable as replicated doesn't magically rotate the head.
You have to implement the logic, such as setting the head to rotate to the value every frame with interpolation (for example).
the rest of the "replicated" stuff quiet happly replicated the leg ik / rotation etc and stuff
I think you are assuming a lot of things
why would leg ik be replicated at all?
it shouldn't be and if you are using the foot ik in third person template then it's not replicated at all
except that it literally does with the MC
they are simulated locally.
no machine tell other machine what state their foot is at
its a weird one i can see there foot ik working
why wouldn't it be. They are calculated locally
0 networking
it steps on the floor when it steps on the floor
also if you are doing MC for anything stateful, that's already incorrect
head rotation deffinitly not something that involve multicasting
if you see a tutorial that does that then just run away.
UPROPERTY(ReplicatedUsing = OnRep_MousePositionVector, BlueprintReadWrite, Category = "Movement")
the only reason this is so that is so the C++ side can see the gravitycontroller and talk to BP's (only the UOBJECT you precsribe)
or IOBJECT but not had much sucess with that side of it 💦
why are you replicating mouse position at all
so that all the other clients know about the head rotation in the animation graph?
that value is already replicated
use GetBaseAimRotation
that's basically the ControlRotation iirc.
aka, where the player is looking at.
Just assuming your game is third person.
so then all i should do is bypass local logic and allow server logic or something
You don't need to replicate the head rotation.
For each of the autonomous proxy, you get the value of their control rotation. Then you just make the head face that way.
If LocallyControlled
GetControlRotation -> Rotate your head
Else
GetPawn-> Get base Aim rotation -> RotateHead with Interp
why interpolate? because there's no way you can send update fast enough to a computer with high fps. So to avoid snapping effect, you interpolate the current rotation to the target rotation.
void AAGPlayerCharacter::AimOffset(float DeltaTime)
{
if (IsLocallyControlled())
AO_Pitch = GetBaseAimRotation().Pitch;
/** Gets proxies characters in server that server don't control. */
if (GetBaseAimRotation().Pitch > 90.f && !IsLocallyControlled())
{ /** map pitch from [270, 360] to [-90, 0] because of compression */
const FVector2D InRange(270.f, 360.f);
const FVector2d OutRange(-90.f, 0.f);
float L_AO_Pitch = FMath::GetMappedRangeValueClamped(InRange, OutRange, GetBaseAimRotation().Pitch);
AO_Pitch = FMath::FInterpTo(AO_Pitch, L_AO_Pitch, DeltaTime, 15.0f);
}
else
{
AO_Pitch = FMath::FInterpTo(AO_Pitch, GetBaseAimRotation().Pitch, DeltaTime, 15.0f);
}
}
yeah not it was a thing in gravity/sphereical dynamic mesh's that made me lerp the head rotation becase the cameras attached the head sort of thing
so yeah it just made the camera some how more stable its a long story but yeah just a side not that its what makes them able to run forward head locked then return to unheadlocked then able to look any where and go back to fps mode
its kind of a little hybrid in that respect
but yeah the faster you run etc the more the 3rd person zooms out for the the tiny sphereical world