#multiplayer
1 messages ยท Page 294 of 1
did used it but it only gives netwrok context , not whether the execution is from server or client , what i want is if execution is of client then it should execute local functionality and if server then multiplayer (my current logic works good for dedicated and clients not working good for listen server host)
you want just do
if (GetNetMode() != NM_Client)
you have 3 different situations here though
listen servers also need local visual effects
you can use... more if statements
also keep in mind HasAuthority is not a magic thing that says if it's on a server, it says if you your LOCAL ROLE is authority. A non-replicaetd actor spawned by the client will have local authority
what actual object you can that on (and IsLocallyControlled) matters
GetNetMode is more "global" to the world itself
so you need to detail what the actual object this was called on is... what is this function on?
long story short when you have 3 different situations you need to check for two different things. Listen servers need to consider being BOTH a player in the game that visualizes things and the authority so of course they can't just use one check
the function is inside subsystem though , my current setup is more contstrained to the execution flow , and the listen server host executes on server due to its setup so any replicated variable comes to its path it will be replicated
what kind of subsystem
It is absolutely crucial you do not hide information when asking for netcode help...
world subsytem
i know i do replication inside that passed in pointers for actors
that is why I asked "what the actual object this was called on" is
which actors are they?
the main logic is executed from the replicated component from actor that i pass inside subsystem
the actor and all the thigs are replicated
what actor is that?
it can be anything a generic actor though
a new actor for you game I assume? it can't be locally controlled unless it is a pawn etc
well, you can always just GetNetMode
listen servers
- do replication
- do visual stuff
clients
- do visual stuff
dedicated server
- do replication stuff
wait wait , let me be clear ,
the actor is not controlled and mainly for visual , and the visual nees to be replicated and also be local based on execution flow , if server then replicate if not then execute locally , i pass the actor i want in subsytem
why would GetNetMode not tell the execution origin?
it says which net mode the world is on
"based on execution flow" is not meaningful, what is execution flow?
if (Actor)
{
ENetMode _NetMode = UHelperFunctions::GetNetMode(Actor);
if (_NetMode == ENetMode::NM_Standalone)
{
ShowActor_Internal(Actor, bShow);
return;
}
}
if (Actor->HasAuthority()) // call multiplayer function only on server , if not server then call local functions
{
UStateComponent* _ReplicationHandler = Cast<UStateComponent>(Actor->GetComponentByClass(UStateComponent::StaticClass()));
if (!_ReplicationHandler)
{
return;
}
_ReplicationHandler->ShowActor(bShow);
}
else
{
ShowActor_Internal(Actor, bShow);
}
}
this is my current code inside subsytem
GetNetMode is from a uworld, you don't need that weird helper thing in a world subsystem
it's literally just from the network driver listed on the world...
if it's just to save time I guess
i know i create it so i can use it in bp
this function instantly fails if you pass in a locally spawned actor
also why not use
UStateComponent* ReplicationHandler = Actor->GetComponentByClass<UStateComponent>();
I don't see why you can just check for it being a client netmode and return
this returns actor component , and shows error , i have to cast it in order to use it
show the error
remember that I am not using your computer, only you can see what is on your computer screen
great, that isn't the code I showed you
look at what I posted
it is not the same
I am using a template version that does this for you
sorry , my mistake
if you are new to c++ you might want to do some c++ basics before unreal C++
(you seem to have figured out a lot on your own but it will help to know what you are looking at in case templates etc are confusing)
if (Actor)
{
ENetMode NetMode = GetWorld()->GetNetMode();
if (NetMode == NM_Client || NetMode == NM_Standalone)
{
ShowActor_Internal(Actor, bShow);
}
else if (NetMode == NM_DedicatedServer || NetMode == NM_ListenServer)
{
UStateComponent* ReplicationHandler = Actor->GetComponentByClass<UStateComponent>();
if (ensure(ReplicationHandler)
{
ReplicationHandler->ShowActor(bShow);
}
}
}
also techncially
it's not really entirely insane to run replication code in standalone, because it might be tracked for replay code
in which case you would be checking for it being less than NM_Client (the highest enum value)
I also added an ensure here because I assume it's bad if this component is missing, if it's okay if it's not there then you can remove that, I don't know what it's really for
how can I create an anchor I dont know at all
try making a physics constraint
with Iris, if i put actors in exlusion filter for a connection, then allow that connection to begin recieving the replicated actors
any actors that dont netupdate, will never get to that connection
i cant seem to find a way to force all in that group to netupdate only to that one connection
I'm not sure if there's a public per-connection dirty
thing is, we need actors to only rep at a certain point
it cant be too early or things break
client needs to be ready for them
but i dont want to force all my dormants to replicate to all connections
that is the issue, the ones that dont arrive are dormant, but the ones that are not dormant, do arrive
the dormant ones i do get, are once where there has been a netupdate
which means, its def being removed from filtering, but those actors wont be sent to that connection
which is kinda odd
what do they depend on exactly? you can't really make them have dependencies unless they are a subobject afaik
we have a bunch of actors that must rep first
and these do rep just fine
our level is procderually generated
and these actors must be happen before we recieve others
so i split them into two groups
I'm trying to see if there's a way to manually mark MustBeMappedExports
and then suspend the packet read for them
basically iris can async load packages and then actually stall the packets for later
I wonder if it can be done for another actor reference showing up
yeah
we use that
thing is, its odd that theres not a way to force actors to rep to a connection
when adjusting a group
cause thats a pretty useful feature of the group filtering, to pretty much say "dont rep these yet, till i need them"
It looks like it does dirty some things per-connection for baselines... I don't know which one is the most ideal here
baselines are certainly per-connection of course but dirty tracking seems to be per system?
hmm
I'm wondering if you can basically pretend a network root is a subobject of another
I don't know if that would break some promise the bridge makes
otherwise it's engine changes needed for the replication reader
well, to suspend an incoming packet you can basically jury rig your own conditionals on top of the pending async setup but I think this feels more like it requires something baked into the packet
iris still uses the actor channels right
I don't know what the exact indicator here that you are receiving something too early
no
i block them entirely
ill show you
if (GetWorld()->GetNetMode() < NM_Client && !IsA<ARegionPointActor>())
{
UReplicationSystem* const ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(this);
if (ReplicationSystem)
{
const UEngineReplicationBridge* const ReplicationBridge = UE::Net::FReplicationSystemUtil::GetActorReplicationBridge(this);
const UE::Net::FNetRefHandle RefHandle = ReplicationBridge->GetReplicatedRefHandle(this);
UE::Net::FNetObjectGroupHandle Handle = ReplicationSystem->FindGroup("DominanceNetworkMapActors");
ReplicationSystem->AddToGroup(Handle, RefHandle);
}
}```
unless you modify the reader directly on clients you can't really block things
we add these to this group
InitIrisFiltersWithRepSystem(UReplicationSystem* ReplicationSystem)
{
if (!bCreatedFilter)
{
/// 1. Create new Group (no name for this test).
const UE::Net::FNetObjectGroupHandle GroupHandle = ReplicationSystem->CreateGroup("DominanceRegionPoints");
const UE::Net::FNetObjectGroupHandle GroupHandleWorldMap = ReplicationSystem->CreateGroup("DominanceNetworkMapActors");
/// 2. Add as ExclusionGr0oup. Will cause all Connections to be disallowed by default.
ReplicationSystem->AddExclusionFilterGroup(GroupHandle);
ReplicationSystem->AddExclusionFilterGroup(GroupHandleWorldMap);
bCreatedFilter = true;
}
}```
we set them to excluded by default
I wonder if reliables would be a good way to just cheese this
do you just SetGroupFilterStatus to "enable" them again?
UReplicationSystem* const ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(this);
if (ReplicationSystem)
{
const UE::Net::FNetObjectGroupHandle GroupHandleWorldMap = ReplicationSystem->FindGroup("DominanceNetworkMapActors");
const uint32 ConnectionId = GetNetConnection()->GetConnectionHandle().GetParentConnectionId();
ReplicationSystem->SetGroupFilterStatus(GroupHandleWorldMap, ConnectionId, UE::Net::ENetFilterStatus::Allow);
}```
yeah
then the only ones client get are any that do a netupdate :/
I am curious about what happens if you update a net condition
hmm
im pretty sure it does nothing
just sets the bit
then wont rep if the condition is not met
SetReplicationConditionConnectionFilter calls InvalidateBaselinesForObjectHierarchy
InvalidateBaselinesForObjectHierarchy is per connection
but yeah I am mostly familiar with the reading side... I am mostly trying to find per-connection calls in the api
you already track those yourself if you have a filter
not sure if you can get handles out of a filter easily though
for (AXX* NetworkedActor : TActorRange<AXX>(GetWorld()))
{
if (NetworkedActor && NetworkedActor->GetIsReplicated() && NetworkedActor->NetDormancy > DORM_Awake)
{
GetNetConnection()->FlushDormancy(NetworkedActor);
}
}``` will see if this works
cause its on the netconnection
I'm curious if FNetRefHandleManager::GetCreationDependencies could be bodged to include the other netref
this way the actual packet would know
ah, this won't work because it NEEDS the parent to be there or breaks the packet (or does it, not sure actually... )
i just need a simple working solution for now i can circle back to this when time is less pressured
if the above code works, then its fine for now
oh shit, UObjectReplicationBridge::AddDependentObject is public and exported
no gaurantees what will happen here I guess
if you want to get something similar I guess you can maybe use a UNetObjectFactory but it would be a lot of work and idk if it lets you control the incoming packets
you can add new custom root network objects this way that aren't actors
it's not really interesting for this unless you can embed more info into the packet somehow
as it's only really used for creation/destruction
the hack above works for now
ill circle back to it in the future
can I somehow increase connection timeout time?
do you mean the net driver ConnectionTimeout?
it should be possible to modify from the ini
yeah
in UNetDriver::InitBase it also parses the url for an extra ConnectionTimeout option
thanks, let me have a look!
there's also InitialConnectTimeout which is in the same place
for example
; engine ini:
[/Script/OnlineSubsystemUtils.IpNetDriver]
InitialConnectTimeout=10.0
are you seeing people dc from having bad connections?
it's not a common issue afaik, but happened to one of our playtesters today, everything points that it was a connection drop yeah
did the server log a packet serialization issue? (or the client?)
not sure tbh, they will send all the logs later
I got the problem in mantle logic in CMC prediction, the character root motion won't mantle over the wall, it moves to the hanging position - the blue sphere on the wall but won't make in the top of the wall and keep falling on the orignial position. My assumption is
- is that try mantle replicate wrong? and keeps server back to the previous position?
- absence of the root motion in animation cause that problem? some of the montage movement won't work with out rootmotion and back to the orignal place. I asked my fren to make the root motion in the mantle animation rn.
I got everything I can do on my cmc but no result, no joy. maybe I am not smart to make that tbh.
here is the whole mantle logic code
void USJSCharacterMovementComponent::UpdateCharacterStateBeforeMovement(float DeltaSeconds)
{// Try Mantle
if (OwnerCharacter->bPressedCustomJump)
{
if (TryWallJump())
{
OwnerCharacter->Jump();
DEBUG_SLOG("WallJump")
}
else if (TryMantle()) // Mantle successful
{
OwnerCharacter->StopJumping();
}
else // Regular jump
{
OwnerCharacter->bPressedCustomJump = false;
OwnerCharacter->bPressedJump = true;
OwnerCharacter->CheckJumpInput(DeltaSeconds);
}
}
if (SafeTransitionFinished)
{
if (TransitionName == "Mantle")
{
if (IsValid(TransitionQueuedMontage))
{
auto FinalRMS = MakeShared<FRootMotionSource_MoveToForce>();
FinalRMS->AccumulateMode = ERootMotionAccumulateMode::Override;
FinalRMS->StartLocation = UpdatedComponent->GetComponentLocation();
FinalRMS->TargetLocation = MantleFinalTarget;
FinalRMS->Duration = FMath::Clamp(FVector::Dist(MantleFinalTarget, FinalRMS->StartLocation) / 500.f, 0.1f, 0.4f);
FinalRMS_ID = ApplyRootMotionSource(FinalRMS);
SetMovementMode(MOVE_Flying);
CharacterOwner->PlayAnimMontage(TransitionQueuedMontage, TransitionQueuedMontageSpeed);
TransitionQueuedMontageSpeed = 0.f;
TransitionQueuedMontage = nullptr;
}
else
{
SetMovementMode(MOVE_Walking);
}
}
TransitionName = "";
SafeTransitionFinished = false;
}
Super::UpdateCharacterStateBeforeMovement(DeltaSeconds);
}
void USJSCharacterMovementComponent::UpdateCharacterStateAfterMovement(float DeltaSeconds)
{
Super::UpdateCharacterStateAfterMovement(DeltaSeconds);
if (GetRootMotionSourceByID(TransitionRMS_ID) && GetRootMotionSourceByID(TransitionRMS_ID)->Status.HasFlag(ERootMotionSourceStatusFlags::Finished))
{
RemoveRootMotionSourceByID(TransitionRMS_ID);
SafeTransitionFinished = true;
}
if (FinalRMS_ID >= 0)
{
if (auto RMS = GetRootMotionSourceByID(FinalRMS_ID))
{
if (RMS->Status.HasFlag(ERootMotionSourceStatusFlags::Finished))
{
RemoveRootMotionSourceByID(FinalRMS_ID);
FinalRMS_ID = -1;
SetMovementMode(MOVE_Walking);
}
}
}
}
this might be the everything releated on my mantle logic but not sure it is enough.
I'm having an issue where join session seems to work, but there a Network Failure : Connection Timeout... ... UniqueId: INVALID before travel shows on screen, so the main menu gets reloaded
This happens only when I check LAN
otherwise, everything works great
Any thoughts where I could dig ?
Are you trying to connect to your internet ip through lan or something?
@fossil spoke
Hmmm .. I'm not sure that's the case
this is my code
void UMultiMayhemGameInstance::HandleJoinSessionCompleted(FName SessionName0, EOnJoinSessionCompleteResult::Type Result)
{
const IOnlineSessionPtr Session = Online::GetSessionInterface(GetWorld());
if (Result == EOnJoinSessionCompleteResult::Success)
{
UE_LOG(LogTemp, Log, TEXT("Joined session."));
FString JoinAddress;
Session->GetResolvedConnectString(NAME_GameSession, JoinAddress);
if (JoinAddress.IsEmpty()) { return; }
APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
PlayerController->ClientTravel(JoinAddress, TRAVEL_Absolute);
}
Session->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionDelegateHandle);
JoinSessionDelegateHandle.Reset();
}
I tried ClientTravel("127.0.0.1:7777", TRAVEL_Absolute);
but it didn't help ๐
Shrug. I'd check which port/ip combo it's listening on.
Alright, thanks !
I'll dig down there
Am new here
I'm 3D modeling, rendering, and some animation depending on the project.
https://www.artstation.com/freddieartist122
this is a stretch, but im setting movement values for underwater walking and falling instead of swimming, for a character that doesnt swim
ive handled most of the switchover, like checking off "can swim" for the nav agent properties, and having an underwater flag in my saved moves for the various movement value changes (as good measure even though it seems to work with or without), im still using physics volumes checked as fluid volumes and using that to discern whether to use in-water values or not
before testing, is there anywhere else I need to look at for this? also not sure about in the PhysicsVolumeChanged function, the ai tells itself if it cant swim to call OnUnableToMove
@spark pilot@keen geyser There's a no promotions rule, outside of their designated channels as well as a stay on topic rule. You're in a multiplayer channel selling yourselves as artists.
There is an #introductions channel, and an #artist-hangout #1054845177509974107 and #1054845120236757103.
Which both of you know, since you spammed nearly every other channel with your self promotion.
Noted
I think I got everything based on initial testing, but ai paths around water, I'll ask in that channel
Hello, any idea what I can do about the lag when rushing through a door being opened?
The door has a collision, which when disabled allows the player to move through it. Basically what's happening is if the player is trying to run through the door's collision while it's still enabled (the door is still not fully open), then the moment the door finishes opening and so its collision is disabled on the server, the pawn moves through the door but on the client it hasn't moved yet cause the collision is disabled later (no client side prediction) which makes the server correct the client and so cause the lag you see in the video.
Of course none of this happens if the client doesn't try to rush through the door while it's still being opened, as in waits for it to open first, then move.
I think there is nothing that can be done about it but thought I'd ask.. The project isn't PvP or anything like that.
Edit: Probably my best bet is to design interaction in a way that the player can't both rush the door and open it at the same time. Like a button on the side that opens the door, as seen in SOMA
When I use a shipping, distribution linux dedicated server. The cpu usage can sometimes start peaking at 3GHz to 6GHz and completely make the server stop working.
But when I use development, non distribution build everything works fine, no peaks and usage climes naturally when players join and leave the server.
Whyyyyy.....
I meant to just check the issue with the development build logs but it just made the whole peaking issue go away and now it seems like I have to stick with this.
you can just simulate the door being open early on the client, nothing is stopping you
or just turn off server corrections altogether
of course it's the first thing I thought of but then I need to handle the case where the server disagrees with the client and rollback, might look ugly in gameplay, also I think it'll still cause lag since on the client the pawn is moving through the door but on the server it isn't
you could significantly reduce the chances by having the idea of opening the door be sent a little bit before it actually opens on the client
idk if turning off server corrections would result in the client being permanently off the correct position in the server or not. I spent a lot of time making stuff client predicted instead of turning off server corrections
it would just be client authoratative
it's not a lockstep sim, you would just tell the server where you are
you can also turn off corrections for a temporary period
oo okay, I'll try that, might be good
going full client authoratative requires setting GameNetworkManager to have ClientAuthorativePosition = true
;game ini
[/Script/Engine.GameNetworkManager]
ClientAuthorativePosition=true
thanks a lot
for obvious reasons this means clients choose where they are
this gets used in UCharacterMovementComponent::ServerShouldUseAuthoritativePosition
note how you can make it a per-cmc field
bIgnoreClientMovementErrorChecksAndCorrection etc
this does invite the problem of the client saying they are like, inside the door which might make them depenetrate it on the server if it does a partial sim locally still
ahh I see
well I'm kinda reluctant on doing this cause I already spent a lot of time learning cmc to make stuff lag free, I think I'll leave client authority movement as a last resort
might bring more problems than it solves
well, you could try embedding the door state into saved moves somehow
I forget if you can easily send references in a saved move...
hmm I'll look more into it
https://dev.epicgames.com/community/learning/tutorials/ywD1/unreal-engine-best-practices-for-networked-movement-abilities-cmc#64:addinglenience etc might help describe how to have it be more forgiving around the doors
ah, FCharacterNetworkMoveData already includes a reference to the movement base so I imagine a door would not be a big difference
Ooh this is awesome! Thanks so much, I'll check it out and give it a good read when I get back to it, you nailed it
Seems to be all I needed
fwiw I think embedding the door into the move data is a bit zany and might get weird with characters fighting over if the door is open (you would probably need to apply it temporarilly on the server and store the known state?)
I'm not super confident on that idea I guess
yeah I agree, probably won't do that but the article you linked has some really good stuff, should help and if not, I still got some other ideas I wanna try out
Guys what's the max number when hosting using listen server in unreal engine
profile it and find out
do not use unreal for an mmo, it scales per connection
if you plan on having more than a dozen or so players running around you will need to be extremely careful with server perf depending on what it is actually doing
there are plenty of commercial unreal games with 60 or so but it is going to require not making mistakes to run at a decent tickrate
you can't really control when rpcs arrive so I would expect a listen server with a lot of remote cmcs to be a bit of a struggle
Any documentation
My target is at least 30-40 if possible
Is there a plugin required etc
what would this documentation be for? unreal multiplayer basics?
This is probably a really stupid question but given that the pedigree of UE is dozens of players running around why is the recommended connection count so low? I would expect at least 20-30 players to be optimal for UE
I had a rumor that max is 10 out of the box
see "depending on what it is actually doing"
the server has to pay the cost of serializing objects that are dirty for each connection
and receiving server rpcs
this might also mean polling for dirtiness if you are not using pushmodel
So what I'm saying is that for the small price of a data center I could use unreal engine for my MMO
Ye I need to read up on this. Sounds like a good idea
unreal is not appropriate for an actual mmo unless you keep counts really low per instance
it is designed for sending stuff to each connection
and considers them separately
Nah that was /s. I thought that was implied
oh, sorry
It's ok just don't make this mistake again||/s||
I'm on thin ice.. ๐
I just want to clarify....out of the box is there a limit...if not...is extra work needed plugins etc...if so which
There really isn't.
you are not going to find a plugin that magically makes your unreal game faster, you need to be aware of how to not make your game super slow
The limit is basically the number of player indicies, which would be like 2.something billion
So listen server is not limited to 10?
Realistically, you're not going to get anywhere close to that number
It's not a hard limit practically but the compute scales exponentially
there isn't a hard limit in regular numbers, the limit is how much you can do each frame
if you have to tick 20k things in a frame and it takes so long the game is unplayable, it's not some magic limit
Think of it like this... Imagine having 2 billion players on a server. You need to replicate a single bit.... You have to replicate a byte.... That means 2 billion bytes would have be replicated in that one frame ๐
I'm sure there's some connection limit somewhere but it's completely beside the point to think about, the actual limit is what the server can actually do with the bandwidth and cpu time constraints it has
for a listen server the client is running the game AND RENDERING IT
so they have to simulate almost everything and then send out new packets at the end of the frame
if a dedicated server runs at 30hz it's a bit sad but it's livable... a listen server running at 30hz would be very difficult to justify for example
Another dumb question but dedicated server tickrate is configurable right?
yep
the only real big weird restriction dedicateds have is that they are mostly hardcoded to run on a single thread
because generally speaking server providers give you a core
I'm not sure if that is possible to work around, I imagine it's probably a macro somewhere
I don't know if they are forced to be a ficed tickrate or not but it's generally going to be in your best interest to not waste server perf
So the lowest tick rate you can play with?
there are quite a few games that are like 10hz servers lol
for some games the server being slow as hell might not really matter much at all
for example many MMOs are mostly simulating movement locally with the server not doing a lot but checking to make sure you aren't speedhacking (and like, spells etc)
iirc the original WoW servers were... 2fps
that would be brutal with the unreal setup though
I know of one Unreal Engine MMO - TERA Online - and I think it was made back in UE3. It also had limited area of relevancy for actors.
I'm pretty sure it's actually custom netcode though, since you seem to transition to between "zones" and people will appear and disappear rather than staying with you through the transitions despite it being seemless for you, suggesting that in the background you're actually connecting to some other server and it has to re-negotiate what is around you, and the world is designed in such a way that enemies normally aren't around those transition points. There was also channels if I remember right, so your character data would belong to a shard, and you would move between different game servers for any specific zone, and if the location was busy, there would be additional channels (read: more servers) that you could switch to.
blade and soul also use UE. Ofc custom net code.
yeah I suppose it's worth noting you could roll your own
to use push model, i need to build with source? cause i need to modify the target with bWithPushModel = true; right?
Hello is there anyone here that's had success with multiplayer that would potentially be down with assisting me in a VC? I'm currently attempting to use advanced subsystems and steam p2p with no luck
Iโm having some replication problems with my Niagara system. AI has told me that a gameplay cue is the right tool to use for VFX replication.
Can anyone confirm that this is best practice when working with GAS?
OSRS
I would tend to agree with that
UE Multi replication server exists now
for games that want to have multiple servers with diff zones, etc
iirc
"Description": "Code to help facilitate connecting multiple UE server processes to each other.",
"FriendlyName": "Multi-server Replication",
plugin
so you could have diff servers for diff areas
That's what most MMOs do anyway
Single server isn't feasible for large player counts
I recently started playing ARK Ascended instead of Evolved and I noticed that Ascended now has client authoritative movement, so buggy. :/ Evolved was great in general when it came to movement. I can only imagine someone working there couldn't fix or implement something movement related and so made the whole thing client authoritative to be done with it
Seems ripe for cheating
I never seen that either version has full client movement.
For some odd reason I know it has client controlled gravity???
(I've seen like hover cheats, where they just never fall)
Evolved doesn't
Yes. Evolved was w-w-w-wonderful for mov-mov-mov-mov-ment. Specially when y-y-y-you dash or ride a wy-wy-wy-wyvern.
Maybe dashes and special abilities like the pteranodon's, but you should see how bad Ascended is compared to it. Tbf in my thousands of hours playing Evolved, movement was great ๐คทโโ๏ธ
I never had movemenet issues in either version.
At least in regards to lag.
But, just about everything else is laggy, and can get glitchy.
I'll pass. I've already resolved never to support that shithole company again, even if they made the game flawless. They can take their business practices and burn it along with their shit game code.
You also can't move when a boat is being driven anymore on Ascended, in Evolved you couldn't jump but that's about it xD
I do that all the time, on ascended, without issue
Really? Hasn't been the case for me. Playing with my friend, if I'm driving the boat, he has to stay still if he doesn't wanna get launched off
I do it all the time when spectating, while invisible.
Just walk around, and look at stuff.
Else, the boat just constantly out runs any form of camera mode.
You're talking about in multiplayer with someone else driving the boat right?
the raft at least
We are on a pretty beefy dedicated machine.
So, maybe thats how/ why it has no issues?
But, yes. Who else would I be spectating? ๐
Haha but yeah it could be the machine? The server I'm in is quite populated, about 20 online iirc
maybe the server itself is slow xD
We have like 50 on the regular.
But, we've run like 4 servers at the same time on the 1 machine, without much issue.
I should try the boat thing again maybe it's fixed maybe it was the server lagging at the time idk, if I catch it lagging again I'll clip it
The only real movement annoyance I kind of uniquely run into, is trying to board a moving raft.
But, thats cuz I need to land on the server version, and not the delayed client version I see.
How long do server saves take for you?
On the server I'm at it takes a solid minute or two
1.86 seconds.
and, we have some crazy like 500k structures placed?
am I on the slowest possible server... lol
Sounds like Nitrado. ๐
they said the server is one of the fastest unofficial servers but hey I got no idea about their specs or hosting provider I should check lol
lol
Found 304528 structures.
Found 183155 items.
Found 693 tamed dinos.
Server completely trusts the client's position after a save finishes, I could be 500 meters away from where I was and I can continue just fine heh
which comes with a huge jitter lag after a save sometimes where I'd be snapped forwards and backwards for like 30seconds until I can move again
I just tried it.
It looks like they even fixed jumping.
But, yeah, walking has no jitter/ stutter issues
Here I logged in just to play a little bit for it to occur xD. Video compressed
Oh, yeah.
Thats just a crappy ah server
this is very mild compared to what I usually get
I near seemlesly work on this boat.
either that or the server is just super cramped with stuff, idk how many objects and dinos are on the server tho
Ooh wow feels like a dream lol
I imagine it's the same with the vanilla boats?
That is a vanilla raft, just with stuff built on it
Oh the Astreos dlc?
No?
What boat is that then? As far as I know there is only a wooden raft and a motorboat, and that's not a wooden raft on the video
Yeah but I've never seen some of these structures, dunno if you're using mods or cosmetics
Oh, yeah the structures are modded.
But, that doesn't mess with like networking of walking on stuff.
Not like the net code is any different for walking on a modded floor
Oh yeah that I know for sure, I was just wondering cause it looked way off from vanilla
Oh, yeah.
Thats why.
99% of the stuff on our server is modded to heck
The only thing vanilla is the main/ primary resources and stuff. ๐ (wood, fiber, thatch)
cool cool!
You must got that server running on a Raseberry Pi or something goofy.
haha no idea it's an unofficial public serv
Hey, I need some serious help
I'm trying to access a spawned actor's owner as soon as possible
Issue is, I tried to run an initialize logic at all possible stages, even PostNetInit, and NOTHING. The Owner is always null for the client.
what's the owner?
Either a player state or a Pawn class
the owner is a reference, if the reference is not replicated to the client for whatever reason then it'll be null
THe issue is
The owner eventually IS assigned
I check the actor data and the Owner will always be correctly set up...
But not by the time I try to run initialize data.
So I'm fighting to find a place where the owner has been reliably established on all players
I think owner is a variable in unreal engine, I wonder if it has a repnotify connected to it somewhere in c++
but is there any reason you can just keep checking until the owner is valid and then do what you need to do?
I already used:
OnRep_Owner
PostNetInit
PostRepNotifies
The issue is I don't know how to just keep checking if the owner is valid in a somewhat-performant or efficient way
OnRep_Owner returns a null owner reference but then later becomes valid without the repnotify firing again?
It looks like so.
I'm not sure what you mean by this either though, Maybe a timer checking every 0.1 seconds until it's valid seems pretty performant
if that's the case then it sounds like there's some race condition you've got going on
the server might be sending a reference to the owner that doesn't exist yet on the client
That's not it
I thought it was that, but I ran some more debugging with different conditions, using an owner that already existed in client instead
The same thing happened, exactly.
So my guess is, the actor spawned on server gets its Owner data replicated at a later point for the Client
That doesn't really make sense to me, I would see if the same issue happens when you try to replicate some other test variable. Doesn't make sense that Owner would mysteriously be delayed like that. I do still double down though on what I said early. A simple timer to continuously check that Owner has been initialized is quite efficient and just fine
I'm gonna do some testing on my side too to see if the same issue happens to me
It's not uncommon to use timers to wait for something to be valid if the time it arrives can't be gauranteed (which is the case for any replicated variable)
I guess, I'm just worried because this is the weapon equipment
Weapons are to spawn and initialize when swapped to
this shouldn't be a problem, infact I doubt it'll drop your fps by a single frame even if you checked the owner was valid every frame
Yeah but it would still make the weapon inactionable for a duration
that duration should be resolve in milliseocnds, usually long before the time it would take to finish the gun swap animation
unless owner is taking an unusually long time to initialize
Can I make the timer last for a tick on logic rather than a server / client tick?
I don't think the server would ever need to do that check just the client. It sounds like you're spawning the gun every time the player swaps to the weapon
Yeah that's waht happens
if that's the case then on beginplay you just need to check every frame if the owner is valid before finishing the initialization
And yes, the server gets the owner no fail
then most likely the server will never run that loop. Don't worry so much about optimization. Get it working first and see how it feels. You can use stat fps to see if that owner check every frame is causing any problems
and if it is (which I know it won't) then you can look into better optimizations
you could do this owner check on 1,000 weapons and I bet you still wouldn't see -1 frame lost
-# assuming you're using c++
Okay, this is actually bizarre...
BeginPlay has all that data???
@short arrow It was all on begin play.
The last place I would use
I have no idea why but, it's the only one that seems reliable.
... and now it doesn't work, yeah
what I mean is to run the loop check on beginplay. Do you use blueprints or c++?
then this example should be enough
all you have to do is just keep checking until the owner is valid, and then continue with whatever you need to do
it should only take a few milliseconds
I did this instead on Initialize
if (CurrentOwner == nullptr)
{
GetWorldTimerManager().SetTimerForNextTick(this, &ADulceWeaponActor::InitializeWeapon);
return;
}
exactly that's perfect
I don't love doing it on delay when this has to be spawned each time...
Hmmm... However, outside of player spawn it seems to work
And it behaves more as a failsafe.
So in normal gameplay the weapon you swap to SHOULD get its owner cleanly.
Okay, it works...
And most importantly...
The delay is only required on loading the level for the first time.
And spawning a weapon to an already initialized actor costs no delay
So the only performance cost is a few frames on the loading screen...
@short arrow Hey, thanks for tips. It's been massively helpful and I think I figured out a lot, even managed to make a giant step.
Not guaranteed to be there though
I still have issues to iron out with the PlayerState on loading the levle though
I would just have the owner notify the weapon when it's available (i.e. beginplay)
It'll be a lot more resilient since there's no guaranteed order
So like, spawn actor deferred and run a function?
I did a different approach now though
I run the initialize on literally every OnRep and net update function that communicates to client that I thought would help
And begin play Iguess
So it just tries to initialize until all data is there
And it works like a charm for most scenarios. Problem is however, the level load side of it.
I need to find a way to make the player pawn spawn in spawning this actor, but THAT early for the client, the Player Pawn cannot be accessed from the player state...
why not just react to the owner being set instead?
if it works it works I guess, better than a single delay
that would be through repnotify but he mentioned that it was not working for him, and I don't want to play 21 questions to figure out why it isn't working for him haha
I would prefer a breakpoint on a watch window showing the onrep_owner is actually invalid
there are definitely times when a one-frame delay is just infinitely easier for sure though
I have a BP_CrackOverlay actor with 6 Decal Components (Top, Bottom, Front, Back, Left, Right). I spawn them on top of the block, but only 2 sides appear correctly; the other 4 sides show solid black lines. How should I adjust the Decal rotation values? Decal Size is 50, 50, 50, and the block is 1 cubic meter.
Or is there a better solution?
I'm showing the codes in the video.
Yeah, that just wrong rotation, cuz it just projects the decal at whatever rotation.
If its wrong, then it just draws 1 little slice of the material (thus your lines)
I suggest making the decals visible in the components tab, then just mess with the rotations.
Or, with your setup, you kinda just gotta change rotation, check, change, etc
Hi, I'm having crash with untouched TPS template project, I use cli to launch dedicated -sever, but on join request from client (-game) [UE5.7.4]
Assertion failed: CurrentApplication.IsValid() [File:Runtime/Slate/Public/Framework/Application/SlateApplication.h] [Line: 321]
can't find any infos, has someone an idea ? thanks
I have the following problem:
UE 5.7.4, EOS with OSS, basic creating/ Finding/ joining. with a listen Server!
each of those methods have their delegates, which are being fired.
in createSession I do change to a map with ?listen.
and in the logs I also get LogNet: Name:GameNetDriver Def:GameNetDriver IpNetDriver_27 IpNetDriver listening on port 7777
findSession also finds sessions. (I can also see them in the dev portal)
and Join sessions, at least online in the dev portal, I can see players join
The problem is now with the client travel after join.
I want the second client to join the host on the same map. but it only gets transferred to the default map, in the project settings.
IOnlineSubsystem* const subsystem = Online::GetSubsystem(GetWorld());
const IOnlineSessionPtr sessionInterface = subsystem->GetSessionInterface();
FString connectString;
if (sessionInterface->GetResolvedConnectString(NAME_GameSession, ConnectString))
{
playerController->ClientTravel(ConnectString, TRAVEL_Absolute);
}
I also printed out the connectionString and it always has a :0 after the IP or the EOS lobbyID.
I think this is the error, since it tries to travel to IP:0/pathToMap
Does anyone have any clues on how to resolve this issue?
edit: FIXED
I now use EOS lobbies
And apparently I used IPNetDriver instead of the EOS ones.
I found out by making the same project in 5.5 and upgrading it to 5.6 and 5.7 to find out.
Basically in DefaultEngine.ini in 5.7.4 writing the following fixes it somehow.
(which I did not had in my other copy in 5.7 which worked... but I will not question it)
[/Script/Engine.Engine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/SocketSubsystemEOS.NetDriverEOS",DriverClassNameFallback="/Script/OnlineSubsystemUtils.IpNetDriver")
+NetDriverDefinitions=(DefName="DemoNetDriver",DriverClassName="/Script/Engine.DemoNetDriver",DriverClassNameFallback="/Script/Engine.DemoNetDriver")
[/Script/Engine.GameEngine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/SocketSubsystemEOS.NetDriverEOS",DriverClassNameFallback="/Script/OnlineSubsystemUtils.IpNetDriver")
+NetDriverDefinitions=(DefName="DemoNetDriver",DriverClassName="/Script/Engine.DemoNetDriver",DriverClassNameFallback="/Script/Engine.DemoNetDriver")[/Script/OnlineSubsystemEOS.NetDriverEOS]
bIsUsingP2PSockets=true
I tried to use a physics constraint between the capsule and the mesh to stop ragdoll bodies from flying away and keep them consistent when I simulate physic in multiplayer, but itโs not working.
I found and solved the problem, but now when I perform a refraction operation on a different mesh, it's not visible. For example, let's say a lamp, it's not visible in a small block, not a square. I don't know how to solve this.
is there a way to see position diferences between the client and server when you simulate lag?
kind of... you can send debug draws across in various ways. It is honestly easier to just use something like the visual logger or chaos visual debugger
those debug draws, how do i acess the correct position to draw them
i assume i cant just do "getActorLocation"
or can i?
oh nvm, i thi i get what you mean, u just send the raw position in an rpc and draw that, but with packet lag wont that info reach only when the character is already there?
also sending every frame is probably gonna mes with the rpc buffer no?
that's not what I mean, I mean look at the definition of DrawDebugBox
when drawn on the dedicated server it sends it to the other clients
but for a listen server I guess you can use the other methods I outlined
like visual logging etc
sending as an rpc will add delay to the result, that would be no different han the current replicated location depending on how it got there
anyone use net filters for iris before? i got a really strange issue.. i'm using a custom UNetObjectFilter class to delay spawning actors per client until certain conditions are met.. and it works like its supposed to.. for awhile.. but after like 24 hours of the server running it just stops filtering and the actor spawns go through right away..
my filter function is super simple so im not sure why it stops working after awhile..
{
if (ConnectionReadyInfos[Params.ConnectionId].bIsReady)
{
Params.OutAllowedObjects.SetAllBits();
return;
}
Params.OutAllowedObjects.ClearAllBits();
}```
Im trying to make a laser that replicates through GAS. I have the line trace working great. But I canโt figure out how to actually replicate the vfx. Has anyone done this? Or have any advice?
I tried to use a physics constraint between the capsule and the mesh to stop ragdoll bodies from flying away and keep them consistent when I simulate physic in multiplayer, but itโs not working. What did I do wrong?
both works fine on client but player2 cant see the flashlight moving for player 1 what is going on in here?
Use a replicated property instead
Client RPC is only going to execute on the client that has ownership of the actor
If you're calling a server rpc that then calls a client RPC, it'll just be whoever called the server RPC
If you want others to get the RPC, you need to use a multicast. But I really want to emphasize that's the wrong thing to do here regardless
It's best to use a replicated property to communicate changes in state
So make a replicated property that is flashlight rotation, call a server RPC to change it
There's an option with replicated properties to execute something when they change
Do the rotation in that OnRep call it generates
Then it'll be like this:
- Player rotates flashlight. This calls a server RPC.
- Server changes flashlight rotation to what the player sent. This triggers the property to update and replicate to everyone relevant.
- Property updates on clients and calls an event. You make this event do the visual rotation you want.
Unrelated but I probably wouldn't do it on tick either but you can fix that later once you get the replication working
Client rpc only runs on owning client.
You want the rotation to be replicated to everyone, not just the owning client.
As mention above. Uss replicated property.
Client can interp on tick.
Actually get base aim rotation is already replicated.
Interp that value on tick.
Assuming you want to use mouse rotation yeah
does anyone know if there is anything that causes client players to get only around 4-5 FPS, while standalone and listen server players are running perfectly smooth? its a full blueprint project, and the client framerate drop happens only about 1-2 seconds after possession is completed. Its also seemingly fine on the network, its just FPS
have you taken a look at the profiler
the profiler?
#profiling via Unreal Insights.
We can't look into your project, unless one of us has a crytal ball lying around
so this?
Well I did it. I fixed the bugs with my system!
Though I'm not sure if I should make the InitializePlayableClass server only, or split it into a client only server only set of functions called back to back. What are your thoughts?
Atm it just does this
void APlayableClass::InitializePlayableClass()
{
if (bHasInitializedPlayableClass)
{
return;
}
if (GetDulcePlayerState()->GetPawn() == nullptr)
{
GetDulcePlayerState()->OnPawnSet.AddUniqueDynamic(this, &APlayableClass::CheckPlayerState);
return;
}
APawn* StatePawn = GetDulcePlayerState()->GetPawn();
bHasInitializedPlayableClass = true;
OnPlayerReady();
return;
}
CheckPlayerStare simply verifies the state is all set up, and OnPlayerReady is a blueprint implementable meant to run misc logic like granting GAs or simple stuff like that.
@cinder quartz OnRep is only called on clients.
Some of your code have incorrecr comment.
And the idea of "can i execute it server only" on the on rep.
If you want the client to inform the server on the on rep use server rpc.
APawn* StatePawn = GetDulcePlayerState()->GetPawn();
This isn't really needed and could cause problems if you're trying to use StatePawn. PlayerState has a function for returning the PlayerState's Pawn. The validity of the pawn can also shift based on whether the pawn is relevant or not to other clients, so StatePawn could go invalid on clients.
Right now I have a Server only set of logic that runs off OnPlayerRead from BP side.
Such as ok my player state is ready. Grant me my abilities.
Oh my bad that was just a random line I used for debugging. forgot about that...
@cinder quartz that "set asc on server " comment really bug me on the OnRep.
Its jsut the wrong idea sincs OnRep is called on client.
It will only set ASC on the client running the OnRep not the server.
Ohh, I get it now...
Thanks for calling it out
Is using PossessedBy with IsLocally controlled a good place to run the initialize logic?
I assumed it was the best solution to keep it somewhat consistent since the server will know instantly the state and its pawn and hand that out to every other client
You gotta understand what each do.
Sounds like you r not aware what is locally controlled do.
OnPossess and filtering with LocallyControlled will only execute on the object that the listen server owns....
It checks if the assigned controller to a pawn matches the controller that exists on the client, or controller 0 for the server?
While logically server should initialize every pawn.
Read the description. It checks if the controller is local controller.
Meaning if the controller is controlled by the local machine (not remptely controlled by other client).
It will also return true on A.I controller so be careful.
If you see the code I gave you earlier. I tell the server to initialize as a client when it recieve the player state.
I am sure I did something wrong, but I assigned to this on the BP side OnPlayerReady a set of server events
OnRep_PlayerState-> server_giveMeAbilities-> server_giveMeItems. Etc
That's functionally what I do right now
Yea its wrong. Initialization mean to be done by server. Thats the only way to replicate anyway.
InitializePlayer runs on client, then sends an RPC with grant abilities, then spawn weapon actors, etc
Well as long it send server rpc... i mean i cant read that from here.
But the idea is. As client, ok my player state is ready. Imma tell server to grant me my abilities and the like.
Well pretty much this a few times over
I just wanted to test it quickly, I should move this to c++ for cleanliness' sake
You shouldn't need the client to tell the server that the client is ready to be given an ability.
Having an RPC open like this would also potentially allow clients to call that RPC at any time, which I'm not sure how that would function with granting abilities and if that ability is already activated o_o
If player state is needed its the only reliable way though.
He tried to spawn a replicated actor(weapon) from GA and the player state is always null on client since he did it onPossess which is too early.
Well it's not that player state is null but that some important data is null on the player state
But same thing really
PlayerState would already exist on the server without the client telling the server it exists.
Yes but wont be on the client.
Last time you debug PS was null.
I checked my self and passing PS on OnPossess fail on client.
Yeah I thought I made it run using OnRep on client
Race conditions be racing.
Not sure what you made run.
But if you want PS to be valid on client, your best bet is letting server knows that your PS is set.
Honestly i never come accross such issue my seld cuz i havent need to spawn anything that early.
So i run check onPossess out of curiousity and client didnt get the PS.
Yeah all this trouble is to spawn weapons on the player's hand as the level loads...
In my opinion, it seems like bad logic. If the GA requires teh playerstate on the client to operate correctly, then there should be code that the GA utilizes to wait for the PlayerState to be valid rather than the client telling the server that its time for it to receive the ability.
It aint trouble.
OnRep PS -> server im rdy to get my stuff.
My issue with it is that you're allowing the client to dictate things it probably shouldn't be dictating. A client could potentially call it when its not ready. It ends up being extra traffic over the network for no purpose other than working around what the problem actually is, and you're having to code additional safeguards to prevent invalid execution of that RPC.
Well it's not a GA what causes trouble but just spawning a weapon actor
I'm learning as I go honestly. I genuinely have been stuck on this for a few days now and just want to sort it out
The whole set of logic I run is probably terrible in all capacity.
All I know is that the code works when the weapon is just spawned normally like when you manually equip a weapon, but if you spawn with it, it stops working
The GA spawns the actor right?
Not a GA, just a function existing on the pawn
So the GA ends up calling that function?
No, it's just a function
Like literally a function that spawns an actor, running on server
Then whats the GA here for?
Called by the pawn, when ready
It's part of the setup. The whole graph is too big to fit
At the end of that it has that weapon spawn logic.
c_c
Ok, the fact still stands, you shouldn't need the client to tell the server to do things like this.
The spawning of a replicated actor on the server should have no impact on the client being ready.
If there is something requiring the client to be ready then you should be coding it in such a way that it can check for that itself without the client telling the server it is ready to receive, otherwise the client can say they are ready to receive at any point in time before they are ready, or any time after they are ready, including after they've already said they are ready.
The part on the client where it is failing means you should have something that checks whether it has teh data needed or not, and if not, then wait and bind to the thing that will let it know on the client that it is ready and then proceed with the logic that is needed when the client is ready.
You can bind to multiple OnReps or whatever event dispatchers you need, you can validate on the client it has what it needs before proceeding with the logic on the client without it telling the server it has what it needs.
Valid take and better in practice.
@sinful tree Okay I'm trying something different now
I'm making functions to fire off delegates. If the initialize ever runs into invalid data, it will bind an event to an update of that data to check
@cinder quartz its not rocket science. If you want to do it his way. You can just broadcast an event on PlayerState OnRep.
The replicated actor checks if PS is null on spawn, if it is, listen to the player state on rep and set it when the event get broascasted. Mark the item unusable until the PS is set.
I feel I should wipe clean the code and start from scratch to see if it works...
I wanna make sure I got it right
Actually you cant do what i suggest it wouldnt know which PS.
You can do a timer and wait till PS is set by server.
I don't mean the entire thing like, just the bits responsible for replication
And initialization
So I'm going back to square 1 with my system, and I get "LogAbilitySystem: Warning: Can't activate LocalOnly or LocalPredicted ability %s when not local!" when trying to grant a passive GA to the client.
This is confusing since I followed the logic from tranek's doc to a T
void APlayableClass::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
ADulcePlayerState* PS = GetDulcePlayerState();
if (PS)
{
// Set up ASC variable.
AbilitySystemComponent = UDulceAbilitySystemGlobals::GetAbilitySystemComponentFromActor(PS, false);
// Init ASC Avatar Actor for server.
AbilitySystemComponent->InitAbilityActorInfo(PS, this);
InitializePlayableClass();
}
}
void APlayableClass::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
ADulcePlayerState* PS = GetDulcePlayerState();
// Set up ASC variable.
AbilitySystemComponent = UDulceAbilitySystemGlobals::GetAbilitySystemComponentFromActor(PS, false);
// Init ASC Avatar Actor for clients
AbilitySystemComponent->InitAbilityActorInfo(PS, this);
InitializePlayableClass();
}
In this case the InitializePlayableClass is not doing anything particular either, it's just running and doing nothing as I disabled most of it to test the foundation
I think it has to do with using GiveAbilityAndActivateOnce
Alright I found out why.... The ability was set so only the client could activate it, and I granted it server side.
I dont see a problem with that. Abilities should be granted server side.
Yeah, but this is granting an ability and activating it immediately after, so that's the gotcha I found
I accidentally left the ability as only activable client side
Hi does anyone know how to handle replicating 100+ ISM/VAT entities in multiplayer?
I am building a multiplayer horde system and need to replicate 100+ enemies simultaneously. To keep rendering cheap, I am using Instanced Static Meshes (ISM) and driving their animations with Vertex Animation Textures (VAT).
For those of you who have tackled massive entity counts in multiplayer with this setup, what does your architecture look like? How do you handle syncing movement and animation states without completely bottlenecking your network bandwidth? Not sure if my approach is the best, would like to hear yaโlls solution
at the count of only a hundred or so you are honestly still in the realm of getting away with regular replication
for truly large RTS style stuff they tend to run lockstep with a bitwise-deterministic sim but it's not universal, there are a few that just send packed down data for state (planetary annihilation)
I would suggest trying a fast array for sending their state as a first try, you should consider carefully what information actually means here and what the actual range of known states are
the main bandwidth hog will be stuff like large numerical values for floats etc
unreal has a lot of built-in ways to pack them down into quantized vectors (FVector_NetQuantize etc) which reduces the precision slightly while saving a ton of bits on the packet
as for the animation state I don't know, how many unique states are there? put them in a byte or something
Thatโs kinda what iโm thinking of doing
I'm definitely going the Fast Array route and packing the data down hard just like you mentioned. I'll use FVector_NetQuantize100 for the position, and shove the anim states and speeds into int8 bytes.
Then dropping the manager's NetUpdateFrequency to like 10-20hz. The server just updates the array on a 0.1s timer, and the client smooths it out with VInterpTo on the ISM transforms so it still looks 60fps locally.
for the VAT animations, I'm just doing time-based determinism. I only send the anim state byte and a StartTime once when a state actually changes. The client's material handles the rest (GameTime - StartTime) to drive the VAT frames, so there's no need to spam animation progress over the network.
The payload is pretty tiny (prob like 10-14 bytes per entity with the delta updates), but my main concern now is if this whole setup is going to be able to actually handle pushing 1000+ enemies at once
https://www.forrestthewoods.com/blog/tech_of_planetary_annihilation_chrono_cam/ interesting article on how planetary annihilation handled this (basically they send a curve which is extrapolated instead of constant updates)
your first message said 100, suddenly a zero has appeared
mustโve been a typo ๐ ๐ ๐
I think you seem to have a pretty strong idea of how to think about what matters in the packet already, you are probably better off just trying stuff in the editor
for starters you don't need to hook up anything, just make your fast array and spam change random elements or something and network profile it to see what happens
if your game has an idea of "being close to something" it might be possible to prioritize things based on distance if you split them up into other objects
Yeah good point, iโm spending too much time theory crafting
thanks for the sanity check
asking for direction is 100% fair, I think you have a strong idea of what to do I guess
I guess a couple things... first of all the default bandwidth cap might be unrealistic if you need to raise it so I guess don't see it as an iron law... I'm frankly not 100% clear on what realistic bandwidth is for users these days as I mostly just kind of... deal with it
generally speaking I have worked on games where we can reduce bandwidth via prioritizing things or custom serializers/filters etc
the advantage being that when you split things up per-object unreal gives you more control over how they get sent. For example an object the player is nowhere near isn't interesting to send etc
so I guess one thing I was going to ask is if you can kind of get away with sending information that is visible more frequently but tbh I think that's going to change super rapidly in your average rts
https://vorixo.github.io/devtricks/network-managers/ a somewhat older now (this is using the old network serializers, if you use Iris (newer much more cpu-friendly netcode backend) you might need to use an iris serializer instead, which this site also has a great guide for)
Oh sweet, that Vorixo link is a goldmine, thanks! I was actually just looking into Iris, so that's perfect.
Thanks again for all the help! Gives me a super solid roadmap to actually start building and testing this out.
I would say don't bother with a custom serializer until you are certain it will actually help... they are quite tedious (in iris)
regular struct serialization is really good already
for example if you want you can just write in a uint8 and write a one-liner function to "unpack" it on the other side, that way you save having to write dozens of macros of boilerplate for a serializer
obviously there is less control etc but I find it's pretty simple to do that when it fits
Iris also supports delta serialization even for TArrays (but it doesn't have callbacks for them, fast arrays are still meaningful)
Hello
I have a multiplayer game and when I test in the editor the fps is solid 60+ fps but when I take a multiplayer build and host it on AWS the fps drops to 15 to 20 does anyone know why that happens. Is there anything I have to change in the project settings, This a VR multiplayer gam
profile it
if I had to guess my assumption would be your dedicated server is on one thread but you are not going to find a magic project setting without at least trying to reason about what is slow first
I need some adivce on how to handle a specific scenario:
I have an Engine Subsystem that communicates with some backend. This Subsystem will do some save managmenet and may load a new world.
The Engine Subsystem also has some data (uobjects) and a struct referencing those uobjects from the backend, that i want to replicated to clients connecting to the dedicated server.
For this my current idea was to haven an addtional AActor that acts as onther kind of Subsystem that can be replicated.
When the Actor BeginPlay's, i rename the uobjects that first have the engine subsystem as outer, to now have the actor as outer.
The Actor will register the objects as replicated subobjects.
When the world unloads, i rename them back to have the Engine Subsystem as outer.
The Actor has uproperties that replicated and equivalent with the ones from the engine subsystem.
The Engine Subsystem and Actor communicate with each other on the server and client to copy data around (like Actor has an OnReplicate function that copies the replicated props to the Engine Subsystem on the client side).
The Problem,
the Engine Subsystem also has another value it cares about, its an struct that has an array with pointers to the uobjects.
The problem is that it seems like the UObjects get replicated to late, so when the Struct gets replicated, it cannot find the UObjects and fills the array with nullptrs.
Occasional it seems to be in order and work, but most of the time not.
Debugging shows that after some time, the UObjects are there, but the array is still filled with nulltptr.
We also have a private lobby which runs on 90 fps, this only happens when we create a room and join it
what does "create a room" mean in this context
what changes?
It's kind of complicated lol, Basically there are categories of players that can join Host, co host , Av support and attendees we basically create a private room using a python script in AWS and the registered emails get room id and password and join the room using that
none of those words describe if it's a listen server, dedicated, etc
We take a build of a Linux server and host it on AWS and the client build joins it
onreps do not care about order when you have different objects. If you want atomicity put the data into a single struct or have each onrep check the others for being ready, and only induce change when the actual set of needed objects is there
replication order between distinct properties is not going to arrive in order, it can be in completely different packets depending on the situation
How am i supposed to delay the change via onrep?
Like... to me it seems like it does replicated with the correct data, but the objects are not ready yet.
So under this assumption, why would the server trigger another replication since it thinks it already has been replicated properly?
I would suggest just running insights on a test build of the server and looking at the result... you might find it is fighting for time on the vps etc but you need to profile
there is no magic project setting here, you need to see what is actually happening
you already said the data eventually arrives, what did you mean?
oh, you mean it's still showing them as null even after?
I wonder if the rename is mangling them somehow
the Uobjects, yes... bu the pointers to those objects have been replicated before...
if you forcibly mark the object with the pointers net dirty do they still not show up while the actual network object arrives on the client? if they are received as an object they are network addressable afaik
If you have multiple clients do all of them see the same result, or only a subset?
multiple clients is not really possible in my setup (without great difficulty)
The thing is that all replicated stuff originates from the same Actor.
That actor has the subobjects, and the properties
yeah, just call ForceNetUpdate on it
not sure what was unclear about that
I guess I should have just said that
i guess the problem is more... when does the server know when to ForceNetUpdate
does ForceNetUpdate force all properties to replicate?
Or does it force all properties to check if something changed?
the latter which induces the former
it marks it dirty in case nothing else does
if you are somehow not using pushmodel correctly
and even with sometimes it is still helpful...
I'll admit I am a bit wary of the whole rename fun setup, I would probably prefer to copy the data out to avoid fun issues with internals breaking from being kept from the old world
If it works it works I guess... I would need to debug to see the actual state they are in between
I honestly dislike how unreal will just silently accept replicating pointers that can't ever arrive (not necessarily what is happening here, but in general)
I assume the idea was that it's possible for the object to suddenly become capable of network addressing so they don't want that to assert
Ah figured it out
Depending on the amount of data, and how often it changes, this feels like something where I'd blob all of the data and just make the client recreate it in their own subsystem, using the actor as just an RPC channel.
it does in fact do the replication of all props again, once the uobjects are up to date.
Optimizer did some weird code shenaniganins, combined with some business logic that is not ready for the first set of nullptr
sry for wasting your time
thx any way on the adivces ^^
I could see it being a fairly unique set of information that is annoying to just put in an rpc but with instanced structs I'm not sure
I'll admit my caveman "scary thing bad" alarm with the renaming thing but arguably that's kind of how seamless works in some respects
You can just serialize it all into a byte array, compress it, and unpack it back into the client's side. It's literally just serializing the subsystem itself, and then each subobject. Put each subobject into an array of structs that has FName/ByteArray. Then on the other side, you look up or create the subobject with the name and seralize the data into it. And serializing the subsystem itself puts your pointers to those objects back.
Also on the Rename. Care with that. It'll break if you rename from ActorA to ActorB when both replicate, and then destroy ActorA. Client will lose their objects in ActorB and server won't.
Not really an issue in this case, the subsystem isn't the initial replicator. But something to note.
spamming a bunch of reliables with zipped data is totally valid, yeah
How can I artifically worsen my connection quality? Ping, packet loss, etc?
Better if I can keep this effect for local PC only, so I would prefer not to do huge downloads in background :d
(not in editor)
programs like clumsy
or take a commercial airline flight and pay for the on-board wifi
clumsy seems promising, thanks ๐
I had asked this about spamming variable setting before. (such as changing a float on tick to the same value)
What happens with stuff like MARK_PROPERTY_DIRTY_FROM_NAME for PushBased?
I did the Unreal trace, and saw no evidence of direct networking occuring, but does it still put strain by checking every individual client or something?
MARK_PROPERTY_DIRTY_FROM_NAME only mark property ready to check for the next network tick, does not actually send any networking data (If I remember correctly). In the meanwhile your variable can continue to change.
I was wonder if I constantly send it on the same value, does it do anything.
Like, I just spam it on tick on a variable that doesn't change.
Does it know that the value didn't change, or just constantly does checks, and tries no matter what?
(essentially, should I check if previous == current in my code for every change, or will the internals of the engine handle it for me.)
You don't need to check if previous == current engine handle it internal, and it will update to client if data is changed.
Ok, cool.
Thanks.
You kind of defeat pushed base advantages if you spam mark it dirty every frame
How functional are chaos vehicles with the network physics component?
AFAIK they're not. Only modular vehicles works with that system currently, and you must use async physics too.

it's annoying
because I'd make my own implementation, but enabling physics prediction makes the chaos vehicle component create and setup a network physics component
bleh
tbh almost everywhere I've been has their own vehicle implementation
I guess I can just make my own outside of that yeah
Shame though, the networked physics component looked cool
Pretty much the kind of system I was going for
tbf network physics component isn't bound to anything in particular, it's kind of a catch-all component. Maybe it would work okay with chaos vehicles but AFAIK the only deep integration currently is with modular vehicles (which are better, but have their own problems)
I'll do some testing
see how good it is because there's defo some integration in chaos vehicles
just unsure of how well it performs or if it's even finalized
i was able to use normal chaos vehicles in resim mode and it worked ok.. not perfect but better than not using it
I still haven't messed with any of the new networked physics stuff at all
Just using the same good old unpredicted system from 2014
What issues have you encountered?
Also, through which mechanism does a locally controlled pawn get the ROLE_AutonomousProxy local role?
Trying to find the path
Because I need to set it manually on vehicles when the local player is driving it (the player doesn't possess the vehicle)
although
I might not need to, seems like predictive interpolation works best on actors that are ROLE_SimulatedProxy
Hah nvm I forgot we're on 5.6 at work so now I look like an idiot
Guess I'll make my own solution
Does destroying a replicated component on server, automatically destroys it on clients ?
yes
it just rubberbands a bit.. but i think thats just chaos not being fully 100% deterministic
still 10000x better than having inputs delayed lol
thank you !
<@&213101288538374145>
For whatever reason epic sends the movement updates on their chaos vehicles as reliable rpcs on tick
quick question on optimization
is it a bad idea for a multiplayer game to look through a datatable to find a row for an attack during run time on each character?
given the datatable has around 100 ish rows
Data tables are TMap internally.
So, I don't believe so.
TMaps are hashed, so there getting is like near instant.
yeah most likely the least of your performance problems
@pure lynx quick question, do you have hard reference in your data table?
Also networking is irrelevant because accessing the DT is per machine.
Theres no actual data to be transfered accrpsd thr network. Maybe only the ptr to the DT at best.
yeah I hard reference it in the bp
If the DT contain hard ref, all of those will be loaded.
I hope that doesnt cause issues
also,
is using a timeline better than a delay for multiplayer?
Any hard ref will be loaded to memory. You need to make use of soft object otherwise everything in the DT is loaded.
Example if you place all inventory info in a dt. Referencing that DT will end up you loading all the entire item in the game when in practice you only need to load the items in your backpack.
Soo yeah hard red in DT is red flag but if your project is small scale, you may pay the overhead.
Thats honestly the only use case I've found for soft references, that and icons anyways The issue is have is you still end up needing to to do a hard reference cast to access any of its properties ๐
Best advice i can give people on that topic is to get in the habit of base classes
With empty asset references
For me its texture 2d so i just cast to texture 2d class.
But yeah if cast is needed, cast to native class or class that doesnt have assets in it.
Yeah if it's small scale just load the sucker, then no waiting for anything ever.
im trying to find a good way to store collision position data for lag compensation, i tried by accessing the physics asset comp but getting proper data from there is not being easy, so i figured i might try just moving the skeletal mesh itself and setting it in a previous pose, so is that possible at all? position is easy to save but can you even save a pose and set it to the skeletal mesh in runtime?
bone transforms are just a simple tarray but the difficult part is determining when you can safely write them... they use a simple swap chain setup to rotate out the evaluation task array and the gamethread-readable array
if you tie your callback to apply when the actual arrays are used in post evaluate or similar it should actually use the transforms
what would happen if i just write them unsafely?
it depends on when you do so
generally speaking the api hides the task-relevant array
for example GetEditableComponentSpaceTransforms vs GetComponentSpaceTransforms
I'm honestly not sure exactly what will occur when it is written to at a bad time, I am mostly familiar with replacing how this works entirely for speed reasons
what I can say though is that everything you do will be replaced if you write before the parallel eval task completes and just paves it over, so you ideally want to write around that
thats probably a bit too complicated for me, i will see if i can find a simpler solution
it might be possible to make an anim node that asks for the pose from the component, as network reads will be far before anim task evaluation work
I'm checking out the Mover Examples plugin, and was wondering:
The way input handling for actions seems to be as follows: IA sets variable -> On Produce Input triggers, setting (and passing through collection) a Mover Input Command Context struct -> OnPresimulationTick Event (bound to Mover Event of same name), uses Mover Input Cmd Context from collection-> Checks that struct for each input, handling it if so. -> Finally does the Queue Layered Move
WHY? Is this really necessary for getting best multiplayer interpolation/rollback? Is there a simpler option than this logic flow, something like just calling Queue Layered Move in IA? For context, I have tons of things in my game that need to Queue Layered Move (not through IAs, but through combinations of IAs that then spawn actors, that I had just running "Add Impulse" and "Play Montage" on owner). Setting a bool in this struct for 50 moves seems like definitely not the correct choice.
Scene graph already a thing?
Hi everyone, I'm using Unreal 5.5. Would it be wise to upgrade to 5.7 as a source code?
Not for us peasants.
Entirely up to you. No one can answer this but yourself.
5.8 or go home.
When I downloaded it and it showed a size of 500 GB, is that normal? It's 300 GB more than the other one.
Not preview. I sync to UE5-Main.
If dedicated server is a req then source version is needed. Wat ver depend on feature thay you need. Read the patch note.
Your current plugins may not support the latest version.
all look plugins support
Wat does that mean
In short, it supports plugins.
Bro double down?
They all support plugins.
Yeah but your current plugins may break in latest version if they use deprecated stuff.
You may have compilation error etc.
And its not just deprecated stuff sometime epic move properties around and boom some plugin break.
Surprisingly, none of my plugins complained about 5.8 so far.
I had to do manual labour on one of the plugin when moving to 5.6.
Probably an exclusive experience.
I'm currently running the project in version 5.7, but it's not giving any errors because I downloaded the plugins from version 5.7 and placed them in the source folder.
Quick question about the CMC's saved moves, it appears that it doesn't send the moves over and over again, only once, correct?
Removes them when ack'd, but if the server doesn't agree somehow it replays them, which makes the client resend them?
A little confused reading through the code
Like, what happens if SavedMoves contains multiple unack'd moves
Where are those unack'd moves resent to the server?
It looks like ReplicateMoveToServer sends the oldest unack'd move, the pending move and the new move. Wouldn't there be multiple moves between the oldest unack'd and the pending one in that scenario?
Looks like in the event of packet loss, or misordering of the move data, it would just wipe out the oldest move data
Like it never happened
Am I correct?
i.e. if the latest ack'd move by the server is newer than the oldest unack'd move, it'd just get removed even if the server never received it
But I suppose movement updates are frequent enough that it wouldn't matter much, maybe? idk
I think it only resends the oldest unacknowledged move along with the newest/current move to give the server additional context and recovery in case packets were dropped. The saved moves are generally not continuously resent one by one. Instead, SavedMoves mainly exist so the client can locally replay/resimulate movement after receiving a server correction, until those moves are acknowledged and cleared
Yeah that's what I thought. But wouldn't that cause issues? What if the oldest unack'd move has a jump input, and the server never receives it & then the client wipes it out locally due to a newer ack'd move
Would the client just never have jumped?
Hello, small bug when teleporting objects from one place to another (Pac man style) clients see the objects breifly interpolate through the middle of the screen. how do I stop that from happening? Tried using Teleport node and set actor location with teleport ticked
How are the things being moved, and what's the replication strategy? You just replicating movement on the root component?
Yeah just replicate movement is on, plus predictive interpolation, moving root component, litterally just if X > value set actor location Value with teleport ticked
Tried turning off interpolation for a frame and then turning it back on but just made it worse.
Yes, that can happen if the packet containing the jump is lost The client would predict and show the jump locally at first, then later receive a server correction and get snapped/replayed back to a state where the jump never happened
I believe the CMC treats jump and other important input/state transitions specially, so they are less likely to be combined away or dropped
Decided to try Iris in 5.8, and I'm hitting this first ensure when a client joins:
ensureMsgf(bSuppressCreateInstanceFailedEnsure, TEXT("Failed to instantiate Handle: %s"), *WantedNetHandle.ToString());
Error LogIris UNetSubObjectFactory::InstantiateReplicatedObjectFromHeader NetRefHandle (Id=140):(RepSystemId=?): Failed to find static or stable name object referenced by SubObject: [NetRefHandle (Id=140):(RepSystemId=?)](NOT_IN_CACHE), Owner: RootObject BP_Ram_C_0 (InternalIndex: 2) (NetRefHandle (Id=84):(RepSystemId=1)) Protocol: (BP_Ram_C), RootObject: /Temp/UEDPIE_1_Untitled_1.Untitled_1:PersistentLevel.BP_Ram_C_0
Warning LogIris RepBridge(1)::CreateNetRefHandleFromRemote: Failed to instantiate SubObject NetHandle: NetRefHandle (Id=140):(RepSystemId=?) of RootObject BP_Ram_C_0 (InternalIndex: 2) (NetRefHandle (Id=84):(RepSystemId=1)) Protocol: (BP_Ram_C) using header:
Warning LogIris FNetStaticSubObjectCreationHeader (ProtocolId:0x997ff41d):
Warning LogIris ObjectReference=NetRefHandle (Id=140):(RepSystemId=?)
Warning LogIris
Its hard to decipher what is actually causing this.
My first thought was that I might be missing AddReplicatedSubObject for actor components I create with NewObject at runtime, but it did not seem to help.
Any ideas? 
if its NOT_IN_CACHE, does it mean its not added via AddReplicatedSubObject?
My QuestLogComponent is not found on a receiving end (client), not sure why, probably ordering issues
UObject* SubObject = Bridge->ResolveObjectReference(SubObjectHeader->ObjectReference, Context.ResolveContext); resolves to NULL causing the error
I'm creating it on Pawn::OnPlayerStateChanged()
So that only player pawns have it:
void ACCPawn::OnPlayerStateChanged(APlayerState* NewPlayerState, APlayerState* OldPlayerState)
{
Super::OnPlayerStateChanged(NewPlayerState, OldPlayerState);
if (NewPlayerState)
{
if (!QuestLogComponent)
{
QuestLogComponent = NewObject<USSQuestLogComponent>(this, TEXT("QuestLogComponent"));
// Setting to be NetAddressable allows to pair server version of this component with client's
// Otherwise clients won't see quests accepted by server or other clients
QuestLogComponent->SetNetAddressable();
QuestLogComponent->RegisterComponent();
}
This setup worked before I enabled Iris, but now it seems client fails to create its own component before replication of subobject happens
The only workaround that seems to work right now is removing QuestLogComponent->SetNetAddressable(); and creating component via NewObject on server-side only
Which then automatically replicates to client
well isn't that how every replicated properties should be created? Only by the server which will then replicate on client.
at least with the one spawned at run time.
The most likely issue is that it's trying to write replicated properties into the clients' version of that component before it exists client side.
Which you can't do, it will just error normally.
For NetAddressable to work like that you must garauntee the component exists client side before writing to it
That is what seems to happen, yes
OnPlayerStateChanged is now called later than it was before Iris
There's no garauntees even in the old system, you probably just got lucky
The OnPlayerStateChanged is called via other replicated properties updating IIRC, so it's really a mixed bag when you'll get updates
If you add lag/packet loss sim to the non-iris version, you may encounter a similar issue 1/20 times etc.
Need to change the approach to make it more reliable
Simplest way is to replicate the component
Seems like it is the way, but it complicates delegate registration a little
I will need to make a broadcast into blueprints when OnSubObjectCreatedFromReplication happens so that umg widgets have a chance to re-register everything ๐ค ?
Thanks for the help! It looks like I can take it from here
weird now I have a level itself causing issues with Iris, its a level from an asset pack https://www.fab.com/listings/b3d214c2-50fa-4a0e-a780-bee56c1baf8f
LogIris: Warning: FReplicationProtocolManager::CreateReplicationProtocol Id mismatch when creating protocol named LI_chapel_01_C with in ProtocolId:0x3f31d20e Calculated ProtocolId:0xbda7597
LogIris: Warning: Fragments:
index 0/2 named LI_chapel_01_C_LifetimeConditionals identifier (0xc57c3961f011fbd8, 0x535cfd3fdcba02cb) Pointer: 0000024CEEF48C00
index 1/2 named LI_chapel_01_C_State identifier (0xf605a794e6edbd4, 0x9d708325d932622) Pointer: 0000024C8E938400
LogIris: Error: RepBridge(1)::Protocol mismatch prevents binding NetRefHandle (Id=19):(RepSystemId=?) to instanced object Lvl_chapel_01_C_0 (Template: /Temp/Game/Necropolis/Placeables/Structures/LevelInstances/UEDPIE_1_LI_chapel_01_LevelInstance_3d589937988e4cd9_1.Default__LI_chapel_01_C).
LogIris: Error: Printing replication state of CDO Default__LI_chapel_01_C used for Lvl_chapel_01_C_0:
Sorry to ping you, but did you figure out the cause by any chance?
level instance LI_chapel_01 had level instance inside of it, but hierarchy of level instances does not seem to cause an issue, could not replicate the problem by creating hierarchy manually
we just disabled replicating WorldSettings
@chilly blaze
we didnt need it replicating anyway
err sorry
levelscript actor also
[/Script/IrisCore.ObjectReplicationBridgeConfig]
RequiredNetDriverChannelClassName=/Script/Engine.DataStreamChannel
+PollConfigs=(ClassName=/Script/DominanceGameplay.WorldMapAvatar, PollFrequency=0, bIncludeSubclasses=true)
+PollConfigs=(ClassName=/Script/DominanceGameplay.WorldMapPlayerState, PollFrequency=0, bIncludeSubclasses=true)
DefaultSpatialFilterName=Spatial
!FilterConfigs=ClearArray
+FilterConfigs=(ClassName=/Script/Engine.LevelScriptActor, DynamicFilterName=NotRouted) ; Not needed in DOM
+FilterConfigs=(ClassName=/Script/Engine.Actor, DynamicFilterName=None)
+FilterConfigs=(ClassName=/Script/Engine.Info, DynamicFilterName=None)
+FilterConfigs=(ClassName=/Script/Engine.PlayerState, DynamicFilterName=None)```
i think at least haha, was a while bakc
Disabling routing just for LevelScriptActor seems enough, thanks!
[/Script/IrisCore.ObjectReplicationBridgeConfig]
!FilterConfigs=ClearArray
+FilterConfigs=(ClassName=/Script/Engine.LevelScriptActor, DynamicFilterName=NotRouted) ; NotRouted means that this type will not be replicated
Still weird that it happens, and there is no mention of this problem existing ๐ค
and in the BaseEngine.ini config this filtering line is commented out
yeah
maybe epic also has it disabled internally
but yeah adding that line fixed it for us
Hi!
im having this weird issue, my clients cant linetrace without my host(listen server) is looking at them
cant even draw debug on clients
but if the server/host is looking at the client then it works
Ideas! :/?
ive checked always releventand turned of f net dormancy
its like my clients are not registering on the server if not visible correctly
Show your linetrace code.
ok sec
dont think its that tho, my projectile spawn from an arrow component and its not also updating when host is not looking at him, spawning way of
kinda hard to show, since im tracing via montage
playing the montage via Rpc then tracing
This the best way i can show u is
https://gyazo.com/97c99b72552fb600df04833b6bd49762 : Client only
https://gyazo.com/2c7b05f0945e6e159c587f29b9ad9148 : Listen server only
https://gyazo.com/97c99b72552fb600df04833b6bd49762 : listen server + 1 client in when listen server ses client
Not sure what I'm supposed to be seeing in those videos. All I can recognize is that there are traces happening in all 3 of those videos.
ah wait i sent the wrong one sec
That said... If what you're trying to say is that it doesn't appear that the trace is happening and it's being called during the montage in some way (again seeing the actual line trace code would help), then there is a setting on the mesh that is performing the montage you may want to check.
It shouldn't be set to "only tick pose when rendered"
client only
hmmmm
Yeah, thats what it is.
The anim tick mode.
Ran into the same issue with my code
Question about LocalPlayerSubsystem in editor testing scenarios.
If I'm testing with 2 players, is it making a separate local player subsystem for each player? Or is it just handling one for both client players?
A ULocalPlayerSubsystem should be getting created for each ULocalPlayer.
For multiple client stuff names I'm used to seeing index numbering like "LocalPlayer"_0, "LocalPlayer"_1, etc.
For the Subsystem I'm seeing "MyLocalPlayerSubsystem"_0 for the local variables in both the first and the second init breakpoint.
I'm assuming that numbering is because for each Local Player, it is the only MyLocalPlayerSubsystem that local player knows about, so its indexing at 0 right?
cause its local
there is only 1 and it wont be on the server
and you will only see 1 unless your doing splitscreen
hello, im doing a team vs team game online multiplayer and i'd like for the players of a same team to see each others as blue and of the enemy team as red, i have an overlay material that i apply on the character begin play by getting its player state and the player state 0, i compare their team variable (replicated) and apply the blue or red overlay depending if it's equal or not
however it doesn't work properly, some even don't get the overlay at all on the other players (i did a server set overlay -> multicast set overlay in the character BP at begin play)
do you have any idea why ?
possibly the characters player state replicated variable hasnt been replicated yet when beginplay is called on the character.. i know in c++ you can just override virtual void OnRep_PlayerState() but im not sure how that works in blueprints
i can't find how to override in BP it but i'll try to work my way around, thanks for the tip :)
Repnotify/OnRep is what you want. You color each character based on that characters team vs the LOCAL players team.
Using multicast is already a mistake to begin with.
Use OnRep as others suggest.
OnRep Team-> if Team == My Team -> create blue color else red color
is there a way to delay client player's server travel on a full blueprint project? i just want to wait until the level has been fully loaded by the host player before clients travel to that level
No you cannot do that in Blueprint.
Clients wont fully load in the world until the Host has anyway.
I have a problem with server corrections on the client. I have disabled all tick events but the client will always be moved when I have 30 to 60 ping. Movement uses default movement component.
Whats tick event got to do? Show how you handle your movement.
This is my movement. I have also tested it with the last one where I use a fixed vector and ther still is server correction
Imo this alone shpuldnt cause cprrection, you are just sending input to the server. Perhaps theres something else you r not showing?
Is this happend on flat ground as opposed to moving platform? Do you change any state such as sprinting?
How did the correction happend? Simply by doing add movement input in flat ground?
Thats what I try to figure out. I have disabled basically everything (all tick events, all widgets, set all variables to not replicated etc.)
When I walk. Either normal or sprint and if I jump
You cant do sprinting in blueprint.
As for jumping you have to use the existing jump function.
So when I increase max walk spead
Yup you will get correction.
I do. I use all the methods from the movement component
But why. Isnt it the normal way for sprinting
Its not, movement are predicted. Client need to pack data in the movement struct.
Changint movement speed outside the cmc framework will just do it on the client it self, in the server the walk speed isnt in sync hence correction.
Tldr you need to pack that info in the movement struct. Its not possible to do server auth movement with bp.
Moreover I just tried moving without changing the max walk speed and there are still corrections
Not sure what you r not showing but running add movement input alone isnt gonna give you correction.
But changing the walk speed is sure way to get correction.
Is cpp an option theres a video you can follow.
Going pure bp in mp is like having your hand tied.
Otherwise just turn off prediction alltogether.
I try to find the thing making problems.
Are you spawning the ground in some way on the client?
Not server auth anymore, client can cheat and movememt can be desync but at least you dont have to deal with prediction.
Well changing the walk speed is surely at least one of the prpb.
No. Its an empty field
So just placed in the level?
But without simulated ping it works. I set the values in the editor settings like this, to test ping.
Without it also changing max walk speed works perfectly fine
Yes because thats fake network test. Theres no such thing as 0 ping.
Modt youtube mp tutorial is a scam. The moment you add ping shits r broken.
Yup again because theres no latency.
1% packet loss is a lot of packet loss. You will always get corrections with that
Even 1 ms already give correction if they fighting cmc framework.
Its the average preset from epic games
Well if you dont trust me ask others.
It's expected that if you have packet loss, you're going to have corrections.
Packet Loss = data isn't being transmitted = server doesn't know where the client is supposed to be = client gets moved back to where server thinks it should be.
I disabled package loss and still get corrections
But its not only about the packet lost, he is going bp route for changing walk speed.
ya, there is that too, but he said he's not changing it now.
I disabled the logic to change the max walk speed and still have corrections
Honestly it wasnt even shown, i have my doubt. Simply adding input shouldnt give correction.
Hi guys! I would like to make a voice chat for my multiplayer listen server game. When the players arrived to the lobby, they can hear each other, but after the seamless travel, the clients can not hear the host, but they can hear each other, except only the host not. Anybody has a solution for the host? Thank you the reply.
Unless its on rotsting or moving platform.
Regardless, you have 2 option.
If you want server auth, you gotta use the movement struct. I gave you the video above.
2nd option is to disable correction entirely and pay the price for clients cheating and desync.
I will take a look at it, but I don't understand why there i still correction when I basically don't change anything in runtime
I can only see what you show so ๐โโ๏ธ
Well. The problem seems to be only in one child class as I just found out. So I have to see there what the problem is
Just remember, regardless what it was. You will get correction for fighting cmc. E.g applying max walk speed in anyway via bp.
I would suggest to actually decide wether you want to go with some cpp code or just turn off correction entirely.
I think I will add some cpp code to be on the save side because it is a cpp project because of subsystem. For now it also works with max walk speed and I only get some corrections. But I also get them when having a blank project
With latency on, the momebt you change walk speed you will get correction its unplayable. I dont know what test condition you set but i refused to believe your game dont break when changint max walk speed predictively.
I change max walk speed and it works with the above conditions
Blank project with default tps doesnt result in any correction. Dont add any packet loss btw, even 1% is brutal.
You prpbably didnt apply any latency.
Im not arguing btw you can ask others if its possible to change walk speed client side w.o getting correction. Your project is cooked if you fight cmc.
Wait a second. I will test it again
It only has correction the moment I change the speed
But to be on the save side I will take a look at your article
Thats what i been saying 10000x times though.
Adding input shouldnt be an issue
Changing speed without the movement struct is impossible.
I mean you can but your game break and literary unplayable no one gonna touch it.
And why is the emulation target server only?
In real scenario thered latency between client and server.
I know. I thought you mean, that the server constantly tries to push the player back when using max walk speed. Not the small correction you see in the video
It will, you probably dont apply the correct emulation.
Try to emulate the client too.
Also i dont see the code for changing the ms.
If you add server rpc to change the max walk speed then it may sync at some point after correction but in real scenario even with 10 ms its unplayable.
The way character movement component works is:
The client presses an input that adds movement to their character
The client's CMC passes along its intended movement to the server based on the values it has in its CMC.
The server validates where the client should be based on the values it knows about in its own copy of the CMC and ensures that is where the cilent is supposed to be.
If all good, no correction. If it doesn't match, then the server tells the client to move back to its last known good location.
The issue lies in that even sending an RPC to update the move speed it's not going to be in sync with the moves being performed and validated by the server. In other words, the RPC will arrive whenever, and the server won't know when you wanted to increase that movement speed in relation to where the character is moving.
The C++ method of creating sprint introduces a flag that gets sent with the most recent move by the client, and that flag can be used to adjust the CMC move speed on the server, so that when the server validates the move, it knows the player should be moving a bit faster or slower and can accommodate the speed change because it was sent with the movement currently being made.
A few other reasons for corrections is if there's something in the way on the server that may not appear on the client's screen (eg. an object that the player may be bumping into slowing them down on either the server or client) or if you're walking on something that isn't necessarily present on either side (eg. spawning an object on the client only and trying to stand on it, or walking through an object that was only spawned on the server) or a moving platform that may not be properly synchronized between the server and client.
I understand. I searched for an article, because I prefer to read it instead of watching videos. Is it basically this tutorial?
https://unrealcommunity.wiki/authoritative-networked-character-movement-ss8pvvmn
Original Author: () Implementing proper authoritative character movement is a very complex, yet under documented task. This tutorial serves as an introduction to implementing networked movement fea...
Yep
Alright. It seems to be very straight forward so I gonna try it out
theres something artistic about lag compensation
kaleidoscopey
has anyone ever done networked physics in a VR game with unreal engine? i wonder if NPP would work.. though I assume it doesn't handle things getting attached/detached to players hands very well
Hi, I'm migrating from UE 5.5 source build to UE 5.7.4 source build. In 5.5, dedicated server packaging included all necessary Steam DLLs automatically. In 5.7, the packaged dedicated server fails to initialize Steam API with Assertion Failed: Failed to load SDL3.dll and [AppId: 0] Game Server API initialized 0.
I have UE_PROJECT_STEAMSHIPPINGID, UE_PROJECT_STEAMPRODUCTNAME, UE_PROJECT_STEAMGAMEDIR, UE_PROJECT_STEAMGAMEDESC defined in my Server Target.cs. DefaultEngine.ini has correct Steam settings with SteamDevAppId=(mygameno).
Is SDL3.dll supposed to be auto-included in server packages? What's the correct way to handle this in 5.7?
I currently work on a multiplayer game in unreal 5.7.4 with EOS, I already got EOS lobbies working and want to integrate voice chat.
I got it working to the state that I can get a VoiceChatUser and retrieve information like
num of input/output devices
channel name etc.
But I have problems getting the audio to work.
So that other player can hear me.
The game currently has no audio source, and I couldn't find any information if an audio source is needed.
Its the same in PIE with 2 players, or on 2 different Devices and connecting to the lobby/same map.
I also ensured, that that no one is muted. by iterating over all channels, all players and SetPlayerMuted(name, false)
in the windows settings, the input and output are all enabled as well.
any ideas whats missing or misconfigured?
once again found my issue:
the problem was that even if I call methods to unmute someone, or transmitallchannel
the playervolume was never set.
so VoiceChatUser-> SetPlayerVolume(name,1); and it works
I am implementing drop item from inventory, where players mesh item gets simulated and launched. This works smooth as long as running dedicated server for 2 players, but if I select only one player the movement is jittery. Any hint what I should be looking at?
if an item drop is being shown on a client and it has latency it will lag, im not sure if ur seeing the lag on the client or the server, but if its the server then something is wrong, if its the client its probably just lag.
As far as i know, unreal doenst have interpolated movement for for actors that simulate physics, u need to run things through the character movement component or the projectile movement component to have interpolated movement and for things to look smooht
is the ping the time it takes to send and receive a message or just to send?
im trying to figure it out if i should divide it by 2 for lag compensation
Ping is round trip time.
Hi, is there any tutorials about how to create a lobby with private invites using steam friend list ? I only found tutorials about opening a server and people join it, or using plugins
Advanced session steam pluging maybe?
Yeah i opened the c++ code fromt this plugin and i am trying to learn from it, i just wanted to know if there is a better approach to it or at least a better explanation
Is there a function that's called before a component/actor is replicated from the server to clients?
i.e. I want to compute a replicated property only right before it's going to be sent
nvm it's called PreReplication
You mean like a party?
im doing lag compensation and its almost working perfectly, the only issue is that when i do "GetServerWorldTimeSeconds()" to get the server time at the shooting time and use my hitboxes are slightly off, is it because the clocks are not in sync? do i have to add/subtract the latency somewhere?
@meager spade Hello Kaos, we talked about this issue before but because of the language barrier I couldnโt fully explain it.
Today I noticed something: Iโm using Gaspโs animation project, and when the character runs I get ServerMove and HISM replication warning messages. Also when jumping, the character gets pushed back.
I think Gaspโs replication system is causing issues. How can we fix this problem?
Are you using a procgen system of some kind for the terrain?
Hullo, I'm building a dedicated server type game and I'm wondering what's the industry standard or best practices for saving.
My preferred database is MSSQL or maybe mongo. But I've seen some recommendations towards Postgres SQL or mysql. Can anyone direct me to some industry standard resources so I can get as close to doing this intelligently the first time? I wanna minimize refactoring this part of the system if possible. Save load is somehow so boring to code, yk?
imo unless you are making a mmorpg or something thats gonna have to serve tons of queries, a sql database backend seems a bit overkill.. i'd just use sqlite since UE already has it built in
yes, I use hism
hsims are not replicated
and they are spawned in at runtime, and its trying to replicate the movement base
and it fails cause its not possible
and the server names for the hism's dont match the clients names for the hisms
so it just doesnt find it
you have a lot of replication issues there
does the server and client clocks desync in the editor?
hmm thanks i will look ๐ฅฐ
Are you expecting 0 margin of error or something?
Pretty sure the algo just finds the average between RTT. So any spike or delta in latency would produce slightly different time.
im not, im just trying to figure out how much error i should have
and if that error can screw up my lag compensation
Did you ever find the root cause of this?
Does Epic Online Services really work with sessions? Does it have NAT punchthrough and all the same stuff for making it easy to host a server like Steam has?
Yes
The package difference between 5.5.4 and 5.7.4 is causing me Steam-related issues. What settings do I need to change in 5.7.4 so I can package it properly?
https://dev.epicgames.com/documentation/unreal-engine/enable-and-configure-online-services-eos-in-unreal-engine?lang=en-US Is this the best tutorial for setting up EOS
Anyone ever run into an issue where clients canโt move when the build is packaged up on Steam? Works totally fine in the editor (including running a standalone process) but once itโs on Steam the server prevents clients from moving. Inputs are being processed and itโs properly possessed, I can crouch and stuff for instance
ฤฑ use steam online subsystems
I understand, I wasn't asking about using Steam.
I'm at present working on a free game and don't plan to publish it on Steam, but Epic should work for MP still.
Fabda has free plugins; I recommend you search for them on YouTube.
ฤฑf use bluperint
The Advanced Sessions Plugin? You mean FAB?
we did nothing special, worked fine
guys has someone already worked with Recipes and KnownRecipes for crafting ? => Discover an item => Unlock a recipe for the player
Can we all agree that it is client side only ? every instance has specific known recipes right ?
Depends on the game - one and done (rogue like) then sure client only if you dont care otherwise, it should 100% be server unlocked and validated
Why client only? Should be a simple tag container replicated that the player has unlocked. Client can read the same thing server reads and it can still be server verified.
So why are there missing files? Others have experienced the same problem, but they've been fixing it manually by constantly copying and pasting. (What I researched on the internet)
when breakpointing in rider/VS, how do you tell if the line was hit on the server or client? Is there some easier way im missing?
talking about PIE
GPlayInEditorContextString
{,,UnrealEditor-Engine.dll}::GPlayInEditorContextString if you need to specifiy the dll
what do i do with that to determine it?
add it to the watches
you are going to need debug symbols, do not ignore downloading those if you have not done that yet
you can also obtain this value in code with GetDebugStringForWorld(WorldPtr) (which is not the same memory, but the GPlayInEditorContextString uses this to update what it says)
keep in mind client indexes don't always start at 0 in some windows I guess
interesting, im not too aware of what expressions can be put in there. It (the .dll one) accurately describes the process when in PIE, thanks! What other useful things could go into the watches area? I've always relied upon what auto-fills there and mouse-hovering any variables in the breakpoint's context.
the DLL thing is a prefix to tell the debugger the variable is in a specific dll (which in the editor are made for each separate unreal module) here
other useful things are like printing the bp callstack which Rider already tries to do for you in the callstack (PrintScriptCallStack)
I personally like to put the outer of the current object in there but I am sure there are more
Will p.NetPktLag 200 when using this setup? I think all 3 windows will be single process?
single process is defined in "advanced settings"
thanks got it, is there way to make all 3 processes docked to single window that would also prevent low fps on background editor?
in a dedicated multiplayer server enviroment our clients were calling a function that was supposed to be called on server with a if (!HasAuthority()) return; and this somehow passing that check and executing on client? is that possible?
you can prevent the editor from reducing performance while tabbed out with a setting iirc but I don't think that applies when you are in one fo the PIE instances
HasAuthority does not check for if it is a server
it checks if it has local authority
you might want to read the pins on what roles actually mean
The main reason I hate has authority. ๐
an actor created locally on the client will be local authority
so many pins
if you aren't sure it's a replicated actor that has a meaningful local role for this case you can ask the world what the netmode is
so what do i want to use instead
it depends on where and when this is
its an actor in the level that just handles spawning AI so it should be only invoked on the server
what kind of actor is being asked about authority?
ah, it's on the level... I am not even sure what role those have on clients then if they are net load on client
I forget
either way getnetmode will work there I suppose
GetNetMode() != NM_client ?
yep
you can also check creater than/ lesser than
for example you might want to consider listen servers/standalone/dedicates differently
i just wanne spawn some AI and make sure it doesn't spawn on clients ๐ญ
GetNetMode() != NM_client is perfectly reasonable here then
what is role for listen server? ROLE_Authority and ROLE_AutonomousProxy is ignored?
No? The listen Server will be ROLE_Authority.
i am wondering what purpose ROLE_AutonomousProxy is, since it is ignored on listen server
i can use IsLocallyControlled instead
ROLE_AutonomousProxy isn't "ignored", its context specific. It refers to the control that a local machine has over an Actor.
For character in the server instance that is controllee remotely by a client. In that server instance the role would be autnomous proxy not authority.
i guess it could have advantage so prediction + server code wont run together (twice) on listen server? that is only use case that i can think of
0o is that the case? I thought it would be autonomous on server too for actor that is remotely controlled.
Oh wait i got it mixed up with simulated proxy
On the server, all local roles would be authority.
If you checked the remote role of any replicated actor, it should be Authority as you're checking what role the server has over the actor. If you checked the local role of any replicated actors on a client, the only one that should be autonomous are the ones you have control of and everything else simulated. Any locally spawned actors would have a local role of authority.
I wonder what is the backstory behind the () on the nick
Many people are using the phrase P2P (peer to peer) when they mean listen server. There is no peer to peer networking in Unreal. Why people adopted calling listen servers P2P when it's a completely different networking paradigm is beyond me, and I think it just can create confusion for people because they'll end up trying to search for P2P networking in Unreal and could end up getting completely wrong information.
Probably some marketing stooge from decades ago got it wrong one time and because its easier to type/say, it stuck to just meaning anything that isn't Dedicated Server.
It is an important thing to get wrong though.
I mean, there's no dedicated server, only me and my buddy's pc. So it's P2P
Like bitcoin!
/s
Someone tried to make that argument with me before <_<;
Sounds like a nightmare setup
if there's no authoritative entity, it's all up for grab
I mean many games used to work like that back in the day