#multiplayer
1 messages Β· Page 674 of 1
You should never rely on the client to tell the server what the carried object is. The server should already know this as your client should ask the server if they can carry it. So your RPC should only be a reference to the stockpile object you want to add the carried object to.
I'm not sure what your object represents and what owns it
It's basically just a tree trunk you pick up from the floor. It deletes the actor and creates an object that contains information about it. I saw this used this way in a somewhat related tutorial and just took it, so that's that. I think the player pawn owns it.
But doing it all serverside makes sense, so I probably have to rethink the stuff around it.
yeah you have to be careful with certain tutorials
The tutorial wasn't made for multiplayer, I just cannibalized a small part of it and assumed it will work out somehow lol.
I'll try some things and see if I get it to work, thanks tho!
Just remember that for multiplayer it didnt happen unless it happens on the server.
I just need to verify that I did indeed waste some time here - Is it correctly understood, that you can in fact not use a DataTable for saving player data on a dedicated server? You know
Load data on join -> Overwrite existing data on change? 
And that to do so, you should use a SaveGame instead?
Quick question; If I am a listen server, and I change a variable that has ReplicatedUsing, will that replicatedUsing function also be called for the client on that server? Doubt it, but figured I'd ask, as I can't test it right now
yes, why wouldn't it?
Hi, I know FVector_NetQuantize can be used to optimize function replication. Is there something similar for rotators?
Compress to short and decompress from short
There should be functions similar to those
I don't know how much precision is being lost while doing that though
Maybe I haven't drink my morning coffee yet but I dont understand the question
Are you asking if every property is being sent across the network when any property changed in a struct?
If thats the question, answer is no. Only the property you changed is being sent, unless you are using Push Model system
FRotator's static functions
thanks for the info!
oh. Well I thought since the variable is technically not replicated.
well for the host player you wouldn't
Yeah, that's what I meant.
but for all other players you would
Thanks for the info
Hi guys, what approach is better and why? Having a replicated bIsEquipped bool property on my AWeapon class or having a replicated EquippedWeapon property (which is a AWeapon*) on my WeaponSystem component that manages the weapons?
The latter sounds better to me
Yop the latter.
You can of course also have a non replicated boolean on the Weapon, and set that from the OnRep of the Component's variable, just to have that extra bit of info directly available in the weapon, but might not be worth much
In the end it's easier to have a variable identifying the current weapon instead of looping over all weapons to ask which one is equipped
And you have one source of truth with the component
I guess we actually have both, our weapons have an equipped state
A bit more than that
Well to keep the reasons generic
Anyone know if advance session plugin for UE5 is working, heard there was some issues with it.
You will have to ask the owner.
Plugins and generally Marketplace Content might only become properly supported once UE5 is released. Using it in EA for production is not recommended. If you want to develop an actual project, stick to UE4 until UE5 fully releases next year.
No
Push Model doesn't change what replicates, only when it's compared.
USTRUCTS() will replicate atomically, so long as they are changed in the same frame ofc.
think of a push model as something that is mostly there to save on CPU cycles for server evaluating actors for replication
Eh, afaik push model sends the struct wholly?
And normal replication model only send the changed property of that struct?
push model just means that when considering actor for replication, the server will not go and compare all properties in rep layout to see if something changed
but will instead rely on you to mark them dirty when they need to replicate
that is all
Hmm, so turns out I misremembered the "compare" part with "sending properties" π
Pushmodel will compare all properties but just replicate the changed one
@steep abyss pinging you, so you can read this too
That's why the benefits of using it are mostly negligible
It's good with components afaik
If you have 50+ pawns with replicated health component for example
Otherwise yeah, Epic also wrote they didn't get much benefit
they saved about 1ms tho
which is huge on a listen server setup π
heard that number somewhere, no idea where
I guess could be huge for dedicated servers too if its save CPU power, since they are expensive π
yeah, Dormancy and stuff is the biggest saver
and if you change a property and just need to replicate that change one time, use FlushNetDormancy
After setting the variable on server?
Only problem with Dormancy is when you wake up the actor it sends every property, so gotta pick your poison for the situation
that is true, but for things that don't change that often
yeah
its better than it being considered for replication every frame
yeah for fortnite trees and environment stuff makes a lot of sense
we use it on a fair few things
but our biggest cost is still replication
listen server is about 7-8ms on Net tick.
which hurts.
I never used dormancy stuff yet, I have a very minimal gameplay since it's a topdown shooter
Only problem was movement and rendering stuff
Is this overhead with push model?
we are not using push model
I remember you guys were using a homemade version of it
I'm surprised you guys didn't give it a try actually π
we have our own limited version (that works only with specific actor classes) and its kinda like push model
4.25 is bad
push model is broken
Ah, I see
Tbh it's very much unbelievable FX-4350 can handle 200 CMC and their replication π
Very good job, amazing π
AI CMC is optimized
like, stripped out a lot
we also reduce tick rates for AI far away
i do prefer the home made version to the push in some aspects
it basically runs replication for about 2000 actors via 8-16 network manager actors
but having so few actors replicated in that group, lets us run network managers with hgih priority and high update frequency
making interactions and the like feel more responsive
if you have 50ms ping but your interactable actor ends up replicating every 0,2 seconds, its effectively 150ms with 100ms variance
its also responsible for replicating the actor destruction post hotjoin
as engine by default can only handle replicated static actors that way
and ours are neither of those things
I do remember that! π
yeah, but it is very very game specific and in no way generic
also not really easy to expand
what would you recommend as an implementation for an automatic weapon? should the rounds fire directly from the server to save bandwidth (but might cause some delay to stop firing) or should the client handle firing and the server would only validate every shot by itself?
Depends on your lag compensation setup really.
I haven't really touched on that yet but since the multiplayer will mostly be coop and not versus I'll most likely go with very lenient settings
Does TFastSerializerArray work with OnRep_?
UPROPERTY(Replicated)
FAcceptedMissionContainer AcceptedMissionContainer = FAcceptedMissionContainer();
In other words, can you use:
ReplicatedUsing=OnRep_OnAcceptedMissionContainerChanged()
?
Ok thanks
can i get rep notify to work on server?
@shrewd tinsel In C++ normally you just create setter functions for your stuff, and call whatever the OnRep calls when setting the value.
Hello, I'm new here, so if this isn't the right channel to ask, please let me know π I've been trying to follow multiple tutorials about using the Advanced Sessions plugin in blueprints, however, the client never travels to the level opened by the host. The success pin is fired, I can print out the session ID (which matches with the one the host opened), but the client stays in the menu screen.
I've tried adding "?listen" or "listen" to the open level options, but neither worked/changed the result. I reinstalled Unreal and the plugins, that also didn't work. I tried standalone, also didn't work. I did find that there seemed to be a timeout happening by looking at the client logs, but I have no clue how to debug this. Any help would be appreciated, thanks!
so just setup the characters to receive random materials per player, but non of them are correct, ive set the variable of the material target to replicated, im doing it wrong but how?
I am a bit flabbergasted right now with replication of the player controller - I Play-In-Editor as a Listen Server, with one additional client. Means, theres 3 Player Controller instances. Two on the listen server, one for the client. In tick, I want to send data via a "Server, Reliable" function to the server version of it.
For that, I use "IsLocalController", to determine which PC's to replicate the data with.
However, on the server (in the _Implementation function), I notice that the two PC's its called one - are the same. Now for the Listen Server, yes, since that's the server object already, it would call it on that one. However, why is the client PlayerController also calling it onto itself?
Hi! has anyone come up with a good way to notify the client to update the UI that doesn't get out of sync? i'm doing a wormhole of code just to replicate that, but it's not 100% reliable
@fluid summit What do you mean with "out of sync"?
you mean you send updates rapidly, and the events arrive out of order?
Update value on server --> Update UI on client (value is still not updated on client) so it uses the old value
yeah, something like that. the value is not updated yet so it uses the old one, when updating server values that replicate to client
no, the variable is replicated and it's changed with the rpc
Execute on server Event --> Change variable (replicated) --> (Client) Update UI --> Variable is still old one
so you have the variable marked as "Replicated", but send an RPC seperately?
i did a variable on the client that says "Ui Update pending" that i flag at the end of the server event, but it looks like madness
there's some logic on how to update the variable, that is on the RPC.
Not sure I understand. Can you send a code snippet?
To me it sounds like you could either just send the data with the RPC directly, or remove the RPC alltogether and use ```ReplicatedUsing````
oh, it's BP only
oh yeah, forgot to mention that, sorry.
Not sure if theres an equivalent of ReplicatedUsing in BP's
So "UpdateDisplayLocal" is called on the server? And internally calls a client function?
Exactly
that client function uses the values from the previous updated variable "ResourceGathererInfo" to update the UI, but it's always 1 update behind.
Can't you do it like that? Passing the data that you need to show in the UI with the RPC itself
the integer as a placeholder for whatever data you actually need
hmmm makes sense doing it that way, gonna try with that
that way it def cant get out of sync at least
@fluid summit
you can also use RepNotify's
that's the BP equivalent of ReplicatedUsing
Just set that on your data you replicate to the client, double click it and it creates that function on the right half. That function then is called automatically, every time the value is replicated, on the client
so you wouldn't need an RPC anymore at all
actually, as soon as you mark them RepNotify, a function automatically appears over there
i think i got some buggy behaviors with that when doing the inventory and updating the ui, not sure what exactly, gonna check again just in case.
okey, it works ok with rep notify, thanks!
you're welcome π
Hi all. I'm just starting to research what exists in the engine for player connection management. In a dedicated server setup is the GameSession pretty much what I want to be exploring for things like forcing a player to disconnect from the server end?
I'm working on a get-in-game loop
Does this work even if you don't use the online subsystems? I'm a bit confused by the API since it has things like "BanPlayer" which would imply it ties into something persistent like that
I have my own platform REST API so none of that is relevant for me
I did try KickPlayer from the default GameSession and it seems to be doing something... but my client is not going back to default map (main menu) or anything like that
How am I supposed to get a clean end-of-game cleanup here?
ah ok looks to be on the PlayerController under ClientWasKicked
{
}```
this is engine code... am i dumb
UFUNCTION(Reliable, Client)
void ClientWasKicked(const FText& KickReason);
how am i meant to catch this exactly? its not virtual π€
i'd expect some kind of delegate to fire here but its totally unimplemented.
Your _Implementation is correct
virtual void ClientWasKicked_Implementation(const FText& KickReason) override;
will let you override it.
ahh π€¦ββοΈ the virtual is on the implementation method
ok this part works for me now with a simpler way which is calling ClientReturnToMainMenuWithTextReason on the PlayerController. Good enough for now.
@steep abyss to ensure it packs into either a single byte (8 bits) or a short (16 bits)
The << operator will usually always serialize the full size of the type unless it's been explicitly designed not to
SerializeBits lets you set exactly how many bits are used
Well.. kinda
ShotCounter is deliberately never allowed to go over the maximum value of either 6/14 bits
But the << doesn't know that, it'll just serialize the full 16 bits every time
To send less data
tbh, I should probs update the article because i never use the large one anymore
Just remove the bCompressByte flag and use 7 bits
127 is more than enough for any sane game
Line 1 uses 1 bit, line 2 uses 1 bit - and line 3 uses either 6 or 14 bits
The result being it serializes down to either a byte or a short
But my advice tbh is get rid of the first line and the bCompressByte flag, and just use 7 bits for the counter.
And change the wrap value for ShotCounter ofc
Need to update it
Yeah, then if they do want to pack it, they serialize the byte
So it saves some data when the rotator is zero (which might be common enough to warrant that extra bit)
depends
It'll be 3 bits only if all axes are zero
But if all axes are non-zero, it would be 27 bits
It's changing how much data is sent depending on the value
Think of it like this - if you have an enum that only has four possible values, using the << operator or the engines built-in serialization means that enum will always serialize to a full byte. If, however you use SerializeBits, you can control it to only ever use 2 bits. That still represents the full range of the enum with less sent data.
yeah that struct always replicates atomically (aka all at once), so using NetSerialize to do a little extra packing can help
If you have a big Struct, and you only want to send over what is actually != NULL (whatever that means for specific type), how does one keep track of which fields need to be loaded and which need to be skipped?
Do you do this via some additional uint where each bit goes for one property and is set when the property is serialized?
If you use NetSerialize the full thing is sent everytime (well whatever you write is sent)
@thin stratus yeah usually a single bit per-prop to signify whether it was serialized or not
FHitResult does that btw
Alright, then I understood that correctly
good evening, This code runs fine with player 1 but player 2 Linetrace happens at player 1 camera
Yeah I ask because of the GameplayEffectContext
Very general struct that could hold lots of info for multiple effects, but they aren't all always important
It's because you use GetPlayerCameraManage0
yeah exactly, a lot of the fields may be empty most of the time so it's worth having those extra flags serialized too if it means more savings (on average)
you need to tell the server who is trying to call this function and get the index from there
Is there a way to get my player index to the server?
Yu need to work relative to the character you are on
No, that's also not how you should do that
I don't think PCM's exist on the Server anyway do they?
Things like GetController on the Pawn is a way of relatively reaching the Controller of the Player for example
Or at least non-local ones
But you don't always have access to teh Client version
As Jambax says
For the Location of the Camera of the Client, the Server has other functions
I think GetBaseView or something like that
Can never remember that crap
What actor is this logic on?
still helpful though i will look into that
the player after it spawns
GetPawnViewLocation() isn't exposed to BP ooof
sometimes an attached actor
That would have been my go-to
You have the camera component right there. Use it. Also do the trace clientside.
There is another function that should be xposed to blueprints though
I need it to be dynamic as some other actor could fire this code when it's just attached to a new pawn
@old hamlet Try, GetBaseAimRotation
Sometimes the implementations aren't that obvious that they're meant to be bi-directional π
Wait
That's for rotation, f
nvm, let be double checkj
(that's good node anyway though)
Stupid question, does your Character justh ave a camera component?
Cause then you could just use the location of that
lol xD
Uhhh, rephrase that. You mean u need it to be on something NOT pawn specific?
not always
I want it to get whatever camera if there is any
true I needed that node for something else
Ok back up and explain in detail exactly how you want this to work. You want to be able to shoot a trace out of the camera no matter the possessed Pawn?
Yup, as this could also just be called out of a gun actor that calls fire to whoever the owner is
BRB
Your gun actor calls fire on it's owner? This smells all sorts of fucky
Hey hey everyone, just a quick question, if an RPC is set to be unreliable and in the case of it not being sent in time and 2 get called, does the server handle the most recent one?
No the player does but the gun needs to position and rotation of the pawn anyways , the rotation i get from the get control rotation
The position needs to be the center of the screen wether it's q player or an AI
Ok it sounds like what you want has nothing to do with cameras. You want an aim direction and aim point no matter if the pawn is possessed by a player controller or AI Controller. That it?
yup
still looking π€
"Depends"
FFastArraySerializer is better IMO for large data sets
TArray is surprisingly efficient
FFastArraySerializer always sends the full item, as well as a couple of extra integers for identifying it
The other reason to use it is because it avoids property comparisons on the Server, you just mark items or the array dirty and it either sends or it doesn't
For a large TArray that CPU cost could be a lot
Yeah, every property gets compared at the NetUpdateFrequency of that actor
But custom Delta Serialize properties just call NetDeltaSerialize every time, and send data if it returns true
Since the internal implementation is what decides what is/isn't sent
FFastArray uses NetDeltaSerialize
NetDeltaSerialize basically means "I'm doing all property comparisons and deciding what to send myself"
And is called every time the actor properties are checked (aka NetUpdateFreq)
It is
When you mark it dirty, the internal implementation of FFastArraySerializer::NetDeltaSerialize writes stuff
if it hasn't been marked dirty, it can just early-out without writing anything
FFastArraySerializer in my experience uses more bandwidth but reduces CPU cost server-side. But now that we have push model, you can get the best of both worlds by using TArray's built-in delta serialization (which is pretty good) and explicitly marking it dirty to avoid comparing all the elements when they haven't changed.
But there's no one right answer
With TArray for e.g, you pay the cost of Property Handles which is an extra 2 bytes per property, then the index, the size etc.
So the only real way to know for sure which is best for a given use-case is to profile it
TArray does what it does automatically
Push Model is pretty self-explanatory, there's no difference when it comes to TArray vs any other property
For clarification NetDeltaSerialize vs the built-in UPROPERTY delta serialization are different things
It will always compare
Push Model simply tells the server when to compare
So for every actor's network tick, it will iterate the properties and compare them. If you're using push model, it only compares the property if it's been marked dirty.
Yeah
A property that uses NetDeltaSerialize does none of that, every network tick it calls NetDeltaSerialize - and the internal implementation of that decides what to do
Yeah
tbh it's probably the only valid use-case for push model
For either TArray's or large USTRUCTS
Using it on a float property or a bool for e.g. is utterly pointless IMO
Since that comparison is going to cost nothing really
possibly yeah, if the whole thing has changed
It's not a good idea IMO to try and use push model to control the frequency of properties
You could easily end up in a state on clients which never existed on server for e.g.
Which would be hard to debug
Just a property that might be expensive to compare
But otherwise, drop the NetUpdateFrequency of the actor to 1 and use calls to ForceNetUpdate for BigBrain
Can RPCs handle custom non-unreal data types, if not how do I add support?
Wrap them in a USTRUCT
This is not really possible in this case...
But TArray<uint8> can represent any type really
You can use a USTRUCT() with a custom NetSerialize() function to send exact bits if you wanted
Ok thx!
Yeah I mean tbh it takes very little effort to support push model really so it's probably worth doing it anyway, but it's quite different to how the Fast Array stuff works
Np's
But yeah in the past I've kind of blindly assumed the "fast array" stuff would always be better but it rarely is
And now I've gotta go back and refactor it all π
just that most if not all of my use-cases it ended up using much less bandwidth to use TArray over FFastArray
But take it with a pinch because it really does depend
Do you need steam multiplayer to make a online multiplayer game like fortnite etc?
Steam doesn't do multiplayer, it only allows you to find people to play with
So no
Fortnite doesn't use Steam for example
You just need some way of finding people - direct IP address like in the 90s, server browsers like in the 2000's, or sessions with Steam, GOG, EOS, whatever
Don't cross post. Ask in one channel.
Oh sorry
Is there a straight forward way to ensure that a Client loaded runtime streamed levels before doing xyz when joining?
I would love to only spawn their pawn once they are fully loaded in
Right now, from what I can tell, it's "Just" a level streaming volume the server walks into
we don't spawn Clients, or let prefab actors replicate for them before they are all done
we also don't let BeginPlay happen before all clients are done loading
Hm, yeah that's fine, I just need a callback for ongoing level streaming
Not sure if there is something build in
if it is its in FWorldDelegates
Hm let's say I have one persistent level and one streaming level that is unloaded by default. Now I load the level on the host, and the client joins afterwards, is there any info on the order of things?
Like, when the f does the client know about the level and when does it load?
One would think this gets loaded very early but I guess not
private:
/** An internal count of how many streaming levels are currently loading */
uint16 NumStreamingLevelsBeingLoaded; // Move this somewhere better
It's like, whenever I look into the engine for info, I find crap like this
what's the best way to replicate a player's view rotation? I know that ActorRotation is already replicated. but only the yaw is used for Character movement. Is there a way to hook into that and replicate the pitch as well to clients?
Or I should just replicate an additional pitch float value to the clients π€
Oh
And IIRC so is yaw for player controller
Any reason why the GetActorEyesViewPoint doesn't return that pitch value? Guessing i'm using the wrong function to get aim information
GetBaseAimRotation
(APawn)
Will use controller rotation if available, if not uses actor rotation + remote view pitch
void APawn::GetActorEyesViewPoint( FVector& out_Location, FRotator& out_Rotation ) const
{
out_Location = GetPawnViewLocation();
out_Rotation = GetViewRotation();
}
and GetViewRotation doesn't seem to do anything with the pitch here :/
GetActorEyesViewPoint is more for camera stuff tbh
Use GetBaseAimRotation()
GetViewRotation() for whatever reason doesn't use the RemoteViewPitch property
Okay, so that's for rotation. Is there one I should use for the Location?
PawnViewLoc is fine for that
Well, in the sense that it's just PawnLocation + EyeHeight anyway
The actual camera position may differ ofc
only on remote clients if i'm correct
Well it's likely server isn't perfectly accurate too
Camera animations/modifiers etc.
Or if you've disabled the PCM spamming the server with the camera location like we have
wondering why is GetPawnViewLocation not exposed to blueprints π€
PCM?
player camera manager
By default it spams the server with the camera location
We've disabled that nonsense
right, i was not aware it was sending camera animations to the server >_>
It's used to work out where the player is for network relevancy really
But since our cam is always attached to pawn.. kinda redundant
I'm checking the code and here it is bReplicates = false;
or is this the one? ServerUpdateCamera_Implementation?
yeah that
ah bUseClientSideCameraUpdates gotcha
So if you disable this how does the server know the view rotation?
For characters controller rotation is sent by the character movement component anyway
ok so you have ur own function grabbing this info
But if not it would just use actor rotation anyway, which for characters is the same really.
the CMC only sends yaw as far as i remember my memory is a bit blury
nope,just saw YawAndPitchPack
yup
I'm looking at it, but it is only a uint16 does an accurate rotation fit into this? π€
so one would use this for aiming and simulating projectiles on the server, for a long distance shot it might not be accurate i assume. Please correct me if i'm wrong
Yeah, but tbh you wouldn't use it most of the time
If you fire a projectile, you usually send the clients' local aim
Aside from anything the server only updates control rotation when it gets a character movement update
Which could easily be a lower frequency than the rate at which a weapon fires for e.g, or worse, out-of-sync
So instead of spamming camera updates, you spam projectile spawn requests? π
doesn't UE4 pack booleans into single bits?
In practice it pads out to bytes anyway IIRC
Worth checking that with net profiler though
yeah, but that would be 3 bytes then
The hidden cost is property headers
Since it's not just sending the property, but also a property header to identify that property too
Probably nowhere documented really, just based on how the replication system works
But you can see them in the network profiler too if you enable them
But it's a cost you can't really avoid so not much point worrying about it π
But when you use NetSerialize, you don't need em
The only header is the one for the parent struct
Actually this case would be 8 bytes for prop headers
2 for struct, 2 each for the structs internal UPROP's
essentially yeah
But you need to identify what specific object and property a bit of data is for, which is where the headers come in
So packets don't just contain the raw data, but also the information required to assign that data to the right vars
Serializing the data is part of the process but not the whole lot essentially
Other stuff is serialized too, but you have no control over that - that's just how it works fundamentally
it can get significantly more complex when sending an asset reference for the first time
there is no NetGUID assigned then, so it will send the path as text
the packet is send via the Actor's UActorChannel, if that channel is active for that client's connection
it will create the NetGUID
but for the first time and first time only it needs to send it as text, until NetGUID is acknowledged
what fun it is π
tbh I really like UE's implementation
makes it quite easy once you know the quirks
but also it's fundamentally core to the engine rather than some layer they just dumped on top of everything
Hi everyone! Iβm currently in the middle of getting a plugin network replicated (Dedicated server). However, Iβm having a bit of trouble replicating actor components:
- My PlayerController has actor components that I need to pass to its controlled pawn. I do this by getting their references from the PlayerController on βPossessedβ event.
- Iβve set their bReplicates to true.
The thing is, the actor components doesnβt seem to be properly in set in other clients. What am I doing wrong and how can I fix it?
They can't replicate because they belong to the controller
And controllers aren't replicated to non-local clients
So while the properties will be replicated, they won't resolve to an object
I see, as I've thought. Is there a way to pass controller's components to its controlled pawn or do I need to move them from player controller to the character?
if you want simulated proxies to have them
you need to move them
you can alternatively use player state, it doesn't have to be the pawn
Hmpf, still not really having a clue how to stop the Client from Spawning until their Streaming Levels are loaded. Tried checking if there are any "ShouldBeLoaded" levels on BeginPlay of the local PlayerController, if so I can listen to some OnLevelLoaded, which doesn't provide the level itself (:........) and then send an RPC to spawn the client, but that feels so crap
I see. Thank you very much!
@thin stratus can you detect client side that all their streaming levels are loaded?
Why does Epic not guarantee that everything that the Host has loaded is loaded on the Client before it starts spawning a pawn
Somewhat. There is a loop to go over all streaming levels, but I'm unsure if the Client knows (from the Server) that it has to load specific levels before BeginPlay of the PC calls
server can stash the list of levels in their PC or PS
if (IsLocalPlayerController() && !HasAuthority())
{
const UWorld* World = GetWorld();
NumLoadingStreamingLevels = 0;
for (ULevelStreaming* CurrentLevelStreamingObject : World->GetStreamingLevels())
{
if (IsValid(CurrentLevelStreamingObject) && CurrentLevelStreamingObject->ShouldBeLoaded() && !CurrentLevelStreamingObject->IsLevelLoaded())
{
CurrentLevelStreamingObject->OnLevelLoaded.AddDynamic(this, &ThisClass::OnStreamingLevelLoaded);
NumLoadingStreamingLevels++;
}
}
if (NumLoadingStreamingLevels == 0)
{
ServerNotifyLoadedStreamingLevels();
}
}
Trying this atm
BeginPlay of the PC
But mΓ€h
the trick is to stop HandleStartingNewPlayer to be called before they are done
I don't even know if the OnLevelLoaded is called by the initial levels or if someone loaded yet another level while I was joining
Which would break the numLoadingStreamingLevels
generally, you want AGameMode::PostSeamlessTravel not to call it on controllers that haven't reported loading done yet
It's not like that's super straight forward
you also want the AGameMode::PostSeamlessTravelPlayer not to call it if controller isn't done yet
and you want the server RPC ServerNotifyLoadingCompleted_Implementation to call it if nothing has called it yet
There is not even a proper hook in the engine that tells me that all static and dynamically loaded levels that are currently active on the host, also loaded on the client
there is not, but when you create a PC server side, you can store either in the PC or PS the list of levels that need to be loaded as replicated variables
then client can check on its own end if everything is done
and report back
well, depends if you always load all of them or not
Not sure how I would stop PostSeamlessTravel from calling ,despite overriding and not calling super
No, it's basically a Level with some Static LEvels and some dynamically loaded ones
And we have the issue atm that the Server loads a Level by running around, and the Client then joins and spawns into that loaded level (cause we spawn them next to the host) but the level isn't loaded yet on the client
And since we allow Client side movement, they fall
That's why I would love to wait with spawning that character
yeah, if you don't spawn exclusively on the player starts on persistent level, you have to delay the spawns
Yeah and that I'm trying to figure out atm
I know my way kinda around the GameMode and all those functions
Despite artificially not calling them
Just the Streaming stuff feels half as'd for multiplayer
At least in form of "information"
Hi again! One last question. Can I transfer JUST the components to the PlayerState and not the functions and whatnot? Provided that the PlayerController's functions are fully network replicated, will it produce the same result?
well, multicast from PC will fail to reach clients same way your components don't replicate to simulated proxies
client/server RPCs are only communicating with owner so they will work just fine
Thankfully, there's no multicast RPC in my PC. Thank you so much!
Yo, i have a simple question. If i replicate, in this case a rotation value from pawn to server, (and this rotation is used in anim bp after making it local variable) should i expect said rotation to SHOW on other networked clients?
i've got a switch right now that does 'if local' send to server, and if server, multicast said rotation
essentially im simply trying to replicate the rotation of a component from one controlled pawn (vehicle) to show in other clients too
the local var is in the animation blueprint only
What's with APlayerController::SendClientAdjustment()? I'm looking at UNetDriver::ServerReplicateActors, and inside it it's doing this weird Connection->PlayerController->SendClientAdjustment(); call... which works with INetworkPredictionInterface somehow?
it's getting the rotation just fine in every locally controlled pawn
but i'm having problems getting rotation from client 1 to show in client 2
(or even server for that matter)
Anim BP's don't have any network functionality
thats what i assumed
Marking a var as replicated or adding RPC's there does nothing, they don't work
i'm not
i'm ONLY feeding 'mouse rot' and 'mouse pitch' to it
from the pawn
not networked either
but derived from the networked valuies
my question is simply this
CAN i set these rotation values in my pawn (replicated to server)
and assume that every local client will pick them up for said pawn
and then drive the anim bp
No
If a client changes the value, only that client knows about it
If you want the server and all other clients to know about it, you have to send the value to the server via a Server RPC
That multicast isn't doing anything (unless you call it obvs), but you don't need it anyway - the var is replicated
yea i figured, i'm just trying out a load of stuff atm to debug it
Remove all the multicast stuff
If the client wants to call that server func, they need to be the owner of that actor too.
Is the owning client setting that "mouse" value locally as well?
If so, set it's replication condition to skip owner
You probably don't want to rep input directly
ye but one thing at a time
getting it even barebones functional
but lemme try skip owner
Problem atm is you're telling the server some value, then the server replicates it, then locally you receive it and reset it etc.
If the client is setting it, it shouldn't replicate to them
hmmmmmm
okay that makes sense, currently im doing a raycast and using the hit location for a bunch of math
and feed the last two numbers to drive everything
ie mouse pitch and mouse yaw
so i should have some 'has authority' switch in there at the very least
though for some reason whenever i possess my pawn, it doesnt have authority
they never do
Authority = actor was spawned server-side and is replicated. You have authority when you can do whatever you want to the actor essentially.
gotcha, which in multiplayer is basically always the server only
edge cases aside
okay that makes sense
Does anyone know what I can do to check if the case described here happens on my OnRep function, so that I know to ignore the replicated property? Or maybe make some call to the net driver to ask if a property updated is being NAK'd? Or maybe where to read more on this issue? This is slowly but surely killing my network model... (the link is outdated)
I just learned that OnRep functions can have a parameter to check the changes for previous values. How can i use this with arrays on the server?
eg i have the following
UPROPERTY(BlueprintReadOnly, ReplicatedUsing=OnRep_MyArray)
TArray<FName> MyArray;
UFUNCTION()
virtual void OnRep_MyArray(TArray<FName>& MyArray);
And on the server i'd do something like this:
MyArray.AddUnique(Something);
OnRep_MyArray(); // this is to trigger the same events on the server as well as they don't get called by default
How should i do something like this? Should i just use a second array to check for the changes / additions?
@unkempt tiger Where are you seeing that? Never seen that issue before.
@shy copper you'd copy it first
also the param should be const ref
right, so i'd make a copy of the old array and add to the new one
yep, just store "previous value" before you modify it
But that seems silly tbh, since you know what's changed already
TArray<FName> OldMyArray = MyArray;
MyArray.Empty();
OnRep_OldMyArray(OldMyArray);
Is that it? π€
the client's don't know
well right π
Best to avoid calling OnReps on the server IMO, just use them as calls to other shared funcs instead if you need something like that
Heyho. Anybody got some time to help me clear some things up about network roles and RPC's / Replication?
I am just getting back into it again, did it once years ago, but seems I have forgotten most things.
So, I have a simple character and PIE with 2 players on a listen server - Meaning one server+client and one client on it's own, right? Now, in each PlayerController, on Tick, I check "IsLocalController", and if so, send some data through a Server-RPC function. However, for the two PC's which are LocalControllers, the Server-Function is executed on the same objects. For the server-client it would make sense, as its the server already - But the client's PC should be calling it on the server version of it, no?
This is happening in my custom Pawn's networked state, which contains stuff like velocity, location, what weapon is being held, and each packet is associated to an explicitly indexed frame, it is very much an issue which only shows itself during packet loss
I check this by simply looking at the memory adresses of the PlayerControllers. The ServerFunc_Implementation functions are called on the same machines that return True for IsLocalController
As soon as I write my own custom net serialize function, the problem goes away entirely, however net traffic turns from this:
Hmm that seems odd. Fairly sure that UDN states that actor properties will be replicated atomically so long as they are all gathered in the same network frame. Maybe that one struct is enough to cause it to overflow. Will try to find the post.
to this
yeah figures
Another guarantee is that, on a frame when an actor is replicated, all of itβs changed properties will be sent at once, and the client should receive and apply these changes within a single frame (with the exception of unmapped properties). However, there is no guarantee made regarding the order in which properties will be received or the order in which OnReps will be called. Any order is considered an implementation detail that should not be relied upon. If the order of an actorβs property replication is important to your game, you may need to implement OnReps to track which properties have been updated on a frame. After the replicated values have been received and their OnReps called, you can handle the changes in the PostRepNotifies function. You may also need to save certain received values in their respective OnReps until theyβre ready to be used.
So according to Epic, members vars of actors should all replicate together. You shouldn't get partial updates for an actor unless as they say it's an "unmapped" property
what if it's all in a big ustruct?
Something I stumbled upon in a google search: https://ikrima.dev/ue4guide/networking/network-replication/detailed-replication-flow/
Gamedev Guide: Programming with Unreal Engine, Houdini, Math, & Graphics
I have being trying to nail this bug for months now, I examined it with every log I can think of, and I did confirm that I was seeing states that were never sent from the server
Yeah :/ And I really don't know where else to look
Yeah in two places Epic confirm that shouldn't happen
Assuming the properties are changed within the same net update, properties A and B should be received at the same time as well and the OnRep only called once. If the properties are split into partial bunches and sent across several packets, the engine will wait until all bunches are received and reassembled to process them.```
So even if the change is split into two separate packets, in theory the engine should wait
I am changing all the properties by doing ReplicatedState = WorkingState
(those two types being FMyState struct)
Maybe there is a bug there
You could hash the struct, and print on server + client to see if there are any differences to rule it out maybe?
According to Epic at least it shouldn't happen, so if it does it's likely a bug
Or some extreme case they don't handle maybe
Hash the struct to like, create a checksum?
Oh I did that
Client got stuff server never sent, this is 100% confirmed in several debugging sessions with different debugging methods
Hmm yeah may need to report that to Epic then
Do they respond to those kind of reports in a helpful way?
If you can provide them with a sample project that repros it they're usually pretty good about it
I might just do that, do I post that kind of stuff on the forums, or is there a special place?
Will DM you btw
I don't like being annoying.. perhaps anyone has any new info on that !?
I saw some weird behavior loosely related to this over the weekend. I found in certain circumstances my replicated TArray would have uninitialized elements added during my OnRep.
I suspect it is related to packet loss.
Depends, if it's UObjects then that's expected
Nah it's a TArray of a custom UStruct
A fairly small UStruct, maybe 5 or 6 floats total (across floats and vectors)
Strange... although, they do say that garauntee is only for mapped properties
I think it is related to packet loss
I had cranked it up to 50% for PIE
My uninitailzied array was just a zeroed array
So maybe in a TArray it would be possible, i.e. you receive the TArrays's size, but not the data because those internal props aren't explicitly mapped
In my case it was easy to detect when that happened
That said I do seem to remember TArray OnRep's getting called multiple times in the same frame. Once for the size change, another for when data populates.
Though I thought that was only with data containing object ptrs, as they are populated and GUID's resolve
Eventually the uninitialized element would get initialized
Strange..
So it might have been an out of order packet problem
Yeah
I was only looking for packet additions, so that's how I noticed
HOWEVER, it got really strange when I converted it to using a FFastArraySerializer
Essentially the same problem would happen
However, I would never see a PostReplicateAdd for the uninitialized element
Instead it would skip directly to a PostReplicateChange
I'm using the PostReplicate calls on the container (not the per element calls)
This only really occurs if I am simulating packet loss
I did observe it (rarely) with a very small number for packet loss
The problem is completely solved (from a defect perspective) by watching for both Add and Change events, but it is still super weird.
I can see that occurring sometimes if an element is added, removed, then changed before the add/remove events propagate
Perhaps
There is at least one issue with FFastArraySerializer in that PostReplicateChange is not called on the container if a GUID is mapped
Which is frustrating, but the OnRep is, and the per-element PostReplicateChange is too
Epic say it's an oversight but AFAIK not planning to fix it
My custom struct is also pretty small. It has a UNiagaraSystem*, a FVector, 3 floats, and a UEnum (int8).
What does it mean to have a GUID mapped?
So when an Object replicates, and it's mapped to a net GUID and replicated pointers to it are resolved/set
Since they can be mapped in any order, but when they are mapped, the OnRep's for those properties will fire again
And in FFastArraySerializer's case the PostReplicateChange should really fire too, but it does so only for the element
Hey, can I somehow check if all subojects of an Component were Replicated(Received on Client side)? (With the fullhierarchy so even if Subobjects have other Subobjects)
Or in general check, if an actor has anything pending to load from net?
I want to make an online multiplayer game, but how can i setup an subsystem
Check out the Steam page on the engine doc
Skip the DLL copy stuff
Keep the .ini changes
Get advanced sessions plugin for Blueprint / quick and easy C++ bootstrap
You're done
also #online-subsystems π
can i make a battle royale on a listen server? or i need a dedicated server?
@agile pendant You can, but you won't have any sort of cheat protection. And you'd probably be limited to like 30-40 players at most with some insane optimization. So in short, no, not really. Not seriously anyhow.
and is there any cheap dedicated server host service?
Dunno. Never cared to look. That kind of game has a massive amount of requirement. It's not really solo dev capable. Not realistically. Even if you manage to somehow pull off being a genius level art and programmer to put the game itself together, you will not have time to do that, manage servers, deal with players, handle accounting, nevermind taking five minutes to get coffee in the morning.
and lanplay how many players can handle?
@kindred widget that is assuming he talks about making the next Apex Legends. Maybe he just wants to train game dev for a personal project
I see Battle Royale, and my assumption is at least forty players on map.
yeah im just practicing game development for a personal project and i will only need to run 1 match at the same time with a max of 50 players π
Hard to say honestly. But realistically I'd say dedicated for sure. By the time you're looking at the networking and cost of 20 people on a listenserver, you're going to be incredibly limited by what you can do with your remaining performance on the server machine. Civ 5 with slow turns? Sure. Easy. Shooter with everyone spamming guns everywhere? Splat.
Hey guys! Do anyone know, is it possible to disconnect client from server without reloading client map to default? Im trying to implement seamless disconnect.
If you have to ask that question, no, you aren't gonna make a battle royale.
Start small. Very small.
I want to know it on client side. Usecase: wait for all information to be replicated like Equipment etc before I remove the loadingscreen^^
Well you can't really know what the Server is going to send, unless you send them some other information beforehand
hm ok, was hoping to have a look at the unresolved GUIDs or smth like that^^
the server sees the client's movement as fairly jittery, what do I need to do to fix this?
for now I replicated an ID + the ptr so I can check if this matches e.g. if I have to wait for an object to be replicated, I think that should work.
also I need help creating a launch node or custom movement that doesn't get corrected multiple times
Are IP addresses visible to the host on the default net driver when using Steam? If so is the only way to prevent that to use the Steam sockets plugin?
Default yes, IIRC, and yes, Steam sockets
thanks!
That is not at all related to the issue I'm having
regular movement is just jittery when watching from the server
clients stuttering on server?
we have that with listen server and PIE sometimes
fine in normal game, also animations are linked to clients sending data to server
so if client is on bad connection/bad pc
ListenServer will see them jittering/acting weird
other clients always see them smooth tho
nope
you can try adjusting some network settings
like client rates etc
as the default is really low
but a player with bad connection/bad pc with low frames, will always stutter on listenserver.
if they have good connect and good pc, then like i said, increase the client limits
by default they are super low
MaxInternetClientRate=120000``` did you set these
sure, but i think i know exactly what you are seeing
but send away
(one other thing i have seen people do, is mark there Skeletal Mesh on the player, as Replicated), this can also cause weird issues
hi guys, i need help with this. Pretty much I need the skeletal mesh to have a random material instance replicated, if anyone could help me thatd be great
Iβm having an issue like this and there were a few solutions but the last responses confused me. If attach to is replicated by the engine why is this an issue?
:triangular_flag_on_post: CptLuckyy#0107 received strike 1. As a result, they were muted for 10 minutes.
When configuring dedicated servers for unreal engine, is there much benefit to a multi-core setup? I ask because I see some threads on the web that suggest the dedicated server config is mostly single threaded, but I'm not sure if that info is up to date.
the actual server process iirc is just a single thread
When pushmodel enabled, replicated variable is comparing every Frequency time on the server? Or it is not comparing and waiting for marking property dirty only?
Waiting for dirty before comparing
Has anyone got an example for getting the friends list from IOnlineFriendsPtr in online subsystem steam?
Yeah, look up the advanced sessions source code
hey everyone. Im having a weird problem.. So.. im in a lobby with two instances. In the client one I turn off the internet so I get "kicked" from the lobby BUT the client player slot stays in the lobby because its waiting for the connection timeout to hit so the game knows it was a disconnect and remove the slot. I instantly rejoin and by code, I remove the "Disconnected" slot and add the new one. It works fine BUT when the timeout hits, it removes the new slot
whats the reason behind this ?
engine has its own way of tracking disconnected players
see AddInactivePlayer in AGameMode
you are probably in conflict with unreal about how it should be handled
@celest compass https://www.reddit.com/r/unrealengine/comments/a0n455/listen_server_host_sees_clients_jittering_fix/
reddit
8 votes and 4 comments so far on Reddit
@winged badger I checked before and the PlayerState before and after is different
if the player got disconnected
it will add the inactive player state
on Login, the PC will create a new one in its PostInitializeComponents
but then the GameMode will swap it for the old one
I dont get it, im not touching the player states at all, I just remove the old slot and add the new one
is there any way to prevent the timeout disconnect or something?
@winged badger sorry for spamming
is the issue that you're having that if your game is running at 120 FPS then the client characters are animating at about 24 FPS? they look like stop-motion?
if so then that is just due to the bOnlyAllowAutonomousTickPose
I guess since Epic doesn't support listen servers for their own products they've never taken time to fully implement their safe systems with smoothing/interpolation, they just kind of give us a "90% there" solution
turning that off may cause discrepancies between server/client animations, but most people building listen server games are building coops or adventure games and it doesn't really matter to them
What is better for shooter:
~5 weapons attached to pawn, 4 of 5 hidden in game, 1 is using by pawn. When swap weapon, changes visibility.
OR
1 current weapon exist, destroy this weapon, when need to swap to new weapon, that just spawned in hands
On the left side weapons with all time replicated variables, but hidden in game
On the right side respawn and initialization all the time
It all depends on whether the state should be saved between equipped and unequipped. If it's something we're ammo should stay consistent or whatever, I would just hide them believe the actor existing.
I know if you got a good system to convert from actor to stored struct and back, you could do that instead. It really all just depends
@celest compass post your video here, not in DMs. that's a different issue though, bOnlyAllowAutonomousTickPose won't fix that unfortunately π¦
I haven't done MP in a long time but barring someone more experienced from being around... if I had to guess that looks a bit like starved upload. have you checked stat net yet, look for... I can't remember what it's called. "Saturation" I think?
otherwise if you accidentally set your skeletal mesh component to "replicated" that is another common thing that causes weird issues maybe like this. although that shouldn't affect a default project. default project should be OK although it used to be close to hitting net saturation on its own
nobody recommends turning on replicated for the skeletal mesh, you have to make sure you didn't turn it on. (I don't think it's your issue anyway)
use stat net next anyway
if by "profiling" you mean look at or share your stat net output... π
one other dumb test you can do is to turn on t.maxfps to something low like 20 or 30 on one/each/both the client and server to see if that affects the problem
yellow text
In addition to advanced sessions, SteamBridge is a more fully featured Steamworks api interface. That's what I use to grab steam friends.
ok, next try watching stat net from the client while running. you may not be able to record/share this unless you have a screen recorder you can capture both windows at the same time, but watch that Saturated column on the client while you run around and see if it stays at 0.00, or if it wavers around while the stuttering happens on the server's view.
notice on the server how the In Rate dips when the stuttering happens? the client is suddenly dropping down its send data from ~6 KB/s to ~4 KB/s
yeah but relying on steam-specific things rather than the OSS can bite you later when you want to target other platforms. steam isn't the only thing in town
#online-subsystems , but what part are you struggling with?
anyone able to take a moment and work through why I can only see my replicated events ( probably implemented wrong ) from the clients, when executed from the server player? for example, the bow animation, the arrow firing, etc
I have it all running at the moment
Show your setup. It should go
Client -> Server
Then
Server -> Everyone
Your ServerFire is a Client event, by the way. Slightly misleading.
both are
@versed ocean you can just make one function ServerFire
make it run on server
and call it
alright cool kinda new and some tutorials are... confusing to say the least so appreciate it
when starting out, it's impossible to tell if the person giving you information via a tutorial actually knows what they're talking about or not
They usually don't. π Just find forum posts about what you're interested in knowing. Usually one of them has some angry person raging about how the correct thing is supposed to be used and enough evidence for it.
i also would not have a delay then reload on an input action
whatever tutorial that is, needs erasing from interwebs
damn alright lol
that's super bizarre, sorry I have no idea then :\ I still see the dip in bytes out/byte in but no saturation, not sure why it would be doing this
we used to have that on listen server (but mainly when playing in editor)
in packaged it was smooth
was this tested over the internet on 2 different machines?
we use listen server..
for 8 player co-op game
just wondering if they did anything that can break since 4.25
i am just wondering if its the high framrates
maybe try clamping them
to 60fps for testing
can even nuke it way down to 20-30 like I said to test. Client bytes out/server bytes in should start to reduce as framerate gets reduced. but normally I've seen Saturation show up when this is the issue, and the ini settings would normally fix it
yeah
you set it on both?
is this in PIE?
seperate machines?
that is interesting
what happens when you test locally?
mind sending your defaultgame and defaultengine.ini
the relevant part of its
no i mean i want to see all your netdriver setup
Hi, may someone direct me to resources that'll teach me how to make a multiplayer game for dedicated servers?
There is no networking difference between Dedicated and Listenserver besides the rare optimizations you can make for them. Learning networking basics will teach you both.
I've used Steam for example for listen servers. Do you have to deploy dedicated servers differently?
From what I'm understanding all I would have to do is provide the ip address of the dedicated server instead of the host's ip
Vaguely. As far as I'm personally aware, most dedicateds are just opened via a command line with properties. This starts the server application which players can then use their client application to join. The difference being that this is a separate application with no player.
ARK does this via sessions as far as I know. If you launch a server, it'll open up a steam session which players can search for, or join directly via IP.
Also a pretty good example of how a game can be both a Listenserver and a Dedicated Server.
Not such a great example of how to use assets, but their networking was pretty good. π
Thanks for the info!!
Why wont these physical animations run on other than the current client? Do I need to run the hand bone variable through the server? Running this on multicast, which is called by a servercall: https://gyazo.com/9df5953b82ad0b94b3ce790ef62a174e
:no_entry_sign: naushad#7838 was banned.
Hi everyone!
I have a problem with delegates.
I have component in my character. It have delegate:
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAmmoInTheClipChange, int, AmmoStat);
And method with UFUNCTION(NetMulticast, Reliable):
void UKT_ItemsManagerComponent::ChangeAmmoInTheClip_Implementation()
{
OnAmmoInTheClipChange.Broadcast(GetSelectedWeaponSlot()->GetAmmoInTheClip());
}
When i call this function on BeginPlay or anytime from my character:
ItemsManagerComponent->ChangeAmmoInTheClip();
programm is crash on delegate.
What i doing wrong?
Yeah, it looks like the problem was with him. Thanks!
Ok, I have one more question. How do I replicate a variable?
Example:
I have a variable that stores a pointer to a weapon. The weapon is created on the server and replicated to clients. But the pointer is only stored on the server. I need to take information about it on the client in order to transfer it to the HUD.
I tried UPROPERTY(Replicated), but this not helped me
You have to add it to the GetReplicatedLifetimeProps also.
And make sure that the actor is set to replicate. I suggest reading the second pinned message in this channel if you haven't
Ok, thanks
what is the correct way to smooth movement between the client and server? currently the client moves and the server sees it as jittery, is that a prediction or replication issue?
CMC already does that for you, unless you're doing something custom movement like sprinting and jumping etc
no, regular movement is definitely jittery
Does anybody know which function is responsible for client-side variable replication. I would like to run some code right before a variable is replicated if possible
Are you running on "Client" mode of PIE?
no this is when I package it and play online
only the server sees that the client's movement stutters
For Actor level I don't know, but if you implement custom replication for a struct you know that^^
What
I need something like a repnotify that runs before updating the variable
rep notify can give you the previous value
just pass a const ref as parameter
Okay, thankd
In my case it would be ideal if there was a central function I could override
What does call the RepNotifies anyways?
what about hooking a break point and check the callstack? π
Good idea lol
How are you applying movement to your character?
on the client
Sorry, should've been more specific... What nodes are you using? Do you have any screenshots you could provide?
And you're not manipulating the speed values at all in the character movement component?
I mean it's not default but I don't change it at runtime
Are you replicating anything on tick anywhere (could even be any other actors)?
Or calling RPCs frequently?
That movement input is fine.... You're not doing anything else that may set or modify the actor's location at all?
no, I'm not. It just looks incredibly rough from the server's pov
Can you use PreNetReceive?
Always get's called on an object prior to reading in replicated properties.
Ah possibly
Doesn't seem to carry any information though
I need the property of what is going to be replicated beforehand if possible
No way to know that unfortunately
But as suggested you could use an OnRep(void FMyValue& PreviousValue) - but this will be called after the property has been changed.
It's fine, I will just need to manually type more stuff out
Steam ppls - is there a Steam Callback you can bind to to detect when a user installs/uninstalls DLC?
I can only see such callbacks in ISteamAppsList but you can't use those unless you've been whitelisted by valve, for some reason.
Hmm doesn't seem to be one for uninstalled :/
it's been many years since I did it, but it was definitely possible in the Unity title we were working on
ah.. uninstalled I'm not sure about
but you can check if a dlc is installed
yeah installed is fine, its when they uninstall while the game is running that's a pain
Can't really figure out why you have to be whitelisted by valve to use ISteamAppsList.. so bizarre
You could literally call BIsDlcInstalled every frame and handle removal there
yeah bit gross though π
We're going through entitlements interface too so is a bit of a pain
Does anyone have some quick tips for getting Steam Advanced Sessions to work without port forwarding? I have my dedicated server working great, but co-op doesn't work without opening and forwarding ports.
I have a question.
I'm using PlayerState to spawn some things for each player based on if they are the "host" or "joined" and make a array with the information of the actors created.
Inside my "PlayerController" i access both Arrays but it says one is empty. Inside PlayerState both are filled. Anyone knows why?
I'm trying to respawn players when they die, but not having much luck. When a player dies I broadcast a delegate, and the GameMode subclass calls RestartPlayer. But this just ends up with the player controller being unposessed from the pawn.
Is there a standard way I should be doing this?
RestartPlayer should work fine so long as you have a "DefaultPawn" setup in the Game Mode (assuming you haven't overridden it in anyway)
Player state replicates to all. Player controller does not.
Hmm I've found ServerRestartPlayer in APlayerController, I wonder if I shoudl be using that instead?
Perhaps it's failing to find a suitable Player Start?
@chrome quest Yes, if PlayerState replicates to all i should get the arrays in my PlayerController
How do you access in your PC?
@chrome quest Cast to
Like what do you cast to? The player state?
yes
Oh? I think that should work. What is the array made of? Objects?
Are they set to replicate?
Yes
They should work then. Weird
I'd say it's probably how you're creating the actors. I'm assuming the array is also set to replicate?
This is how i create the array. If i check them here, both have the same length as it should be
This is in PlayerState
You're only replicating movement?
You should set the actors to replicate in their blueprint class defaults
They are, i doN#t know why i have that "Set replicate movement" in it π
I didn't touch this for a few months π
I'm not sure what could be the issue then. Sorryπ
No Problem^^^ thx anyways^^
Hey guys! How are fps/tps animation syncs solved in multiplayer games? I'm thinking of like a roadhog hook, where the hook is nicely attached to the TPS body of a roadhog (POV of another player) but when you control the character (POV Roadhog) your FPS hand model is attached to the rope accurately, and its not coming out from his waist. Is it just handled differently on server / client, so the player doesnt see the tps animation, others dont see the fps animation and it happens two times at the same time, but everyone sees the different attachments?
Has anyone experimented with alternative net relevancy systems? Specifically ones that implement room based replication? I'm trying to see if it would be viable to create large dense structures that perform net relevancy checks based on whether another actor is in a connected "zone", as opposed to standard relevancy checks, and if it could possibly even be more performant to calculate relevancy this way?
Have you messed with the replication graph?
Yes, the animation isn't synced. Just the fact that Roadhog is hooking. Each machine does with that what it will.
That's how most things should be. You don't sync like
I'm stepping my left foot
Now I'm stepping my right foot
But you sync
I'm here, facing this direction, and moving at this velocity
And each machine drives animation from that.
Is there any way to, on a client, say that a certain actor should not receive replicated data anymore?
So if I have some actor A which replicates its movement, I want to be able to locally on one of the clients disable the update through replication
My bigger problem is the following; our user/player should be able to pick up an item - Now, with high ping in mind, I dont want the pickup process to have a delay at all, so I already want to pick it up locally. But then, some data that is replicated and maybe on the way already could screw this over. Or is there some other best-practice, established method of handling stuff like that?
I'd imagine most games have to deal with that issue, for example when bringing out weapons and things like that
Essentially I am trying to do it the same way movement is handled, but it doesnt seem as frameworked into the engine
You are talking about prediction. That gets tricky really fast. I think there's a GAS project around with predicted weapon switching, I'd look at that.
@dark edge May I ask what GAS stands for?
Yeah. Or I am just making it a bigger deal than it is, maybe. it just sounds horrendeous to me, each time you do something theres a 30-120ms delay before anything actually happens on your screen
Other than movement itself
@dull lance https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/GameplayAbilitySystem/GameplayAbility/ so, this?
never even heard of that before
sounds interesting
so its like an API for common game functionality?
guess I'll just read the wiki page first
wonder if that may be overkill for what I am trying to acchieve. For the most part, we let clients be authoritive in our project (not really a project you could or would want to "cheat" in)
but with replicated actors, that exist on all clients, theres no real way around doing it on the server
https://github.com/tranek/GASDocumentation#concepts-targeting-data i'd start there @exotic spindle
predicting pickups? sounds like a recipe for disaster
what do you do if someone else picks it up?
client who thought he had it just drops it to the floor or it magically disappears from his inventory?
@exotic spindle
games normally "Predict the interaction animation/event"
but the actual picking up is always server side
thanks @winged badger and @meager spade w
Will read that, and yeah, I think I just need to test how bad it actually feels
The daly between the action and the event
We're not really concerned too much with those edge cases (regarding conflicting input from multiple players), but as a perfectionist myself, yeah I dont like that possibility (and having to somehow account for it)
Adding VFX / SFX to mask the delay can be helpful for the feel. For example, in RTS games an acknowledgment sound is played by units when you issue orders and a crosshair appears to show where you clicked, but the unit may not actually start moving until the server acknowledges the order.
Epic's advice is to predict as little as you can possibly get away with. In practice little interactions like that make no difference, but massively ramp up complexity.
Hello, small question for the voip,
I currently have an effect chain for the radio, in OSS Loopback I can hear the radio effect on the voice!
But when I test in multi the radio effect is not applied on the host player or even the client player, is there a special configuration to do on the Voice attenuation?
Hi
i spawned couple of objects at x positions on server but when client join objects are on zero position
any idea y is that behavior?
just boxes
static
WDYM
okay
let me try
same
spawned at zero positioned π¦
- I spawned box on server
- I get some data about to repositioned it on sewrver
these are two steps
i think when i repositioned it
not working
should i need to run RP for clients ?
yes
this is the object
and i am changing the position of the arrow
i think i found it
just let me confirm
Hello
i hope somebody can push me in the right direction.
Example:
We have 2 players.
One is Team Blue, one is Team Red.
We have 2 Cubes. One Blue and one Red.
Team Red should be able to move the Red Cube and Team Blue the blue Cube.
How would i do this?
I'm using a listen Server System, i tried it a way but it only works for the player who hosts the server, the player that joins can't move anything.
Disregarding teams, is your pushing mechanic working right? For client and server?
No, only the Server can move objects the way i did it.
But only the ones that he should not the ones from the other player
Get that working first before worrying about teams.
You misunderstood me, "teams" was just a word. It is a 1 vs 1 game. No teams sorry.
all i wanna do is, the game starts, player 1 spawns, player 2 spawns, each player spawns a cube that only he can control.
This can't be that hard, why can't i find anything about htis.
override GameMode::HandleStartingNewPlayer
don't call Super, Spawn the DefaultPawnForController (PC)
Spawn the Cube
set the Cube owner to the PlayerController
set references to the cube where you need it - PlayerPawn, Controller
add logic to control the cube
and all done
team logic belongs more in PlayerState, which you also have access to in that override
oh, and make the references to the cube replicated, with optional onrep if you need client side setup to run
Pushing stuff around using the CMC might get a bit tricky. I'm not sure how other people have done it but my first thought would be to break it down into a few parts. It all depends on how you're wanting the cube movement to behave (physics or kinematic)
-
Detect that you're attempting to push. I would use event hit on the character to detect when it has bumped against the cube and set a Boolean.
-
Do the actual pushing. That would involve passing the movement input into the cube or doing the movement from the character or enabling physics or even maybe just attaching the cube. You gotta experiment here.
-
Stop pushing when the movement input is AWAY from the cube direction.
@dark edge It is not about how to move, but who is allowed to move the cube
How are you moving it right now? Physics, your own movement component, just setting position, what?
@winged badger I'm using blueprints.
Why override?
My Players and cubes are spawned how they should be, but i don't know how to set a owner to the cubes. so only the owner can mov ethem
@dark edge You can come in my Twitch Stream and i can show you.
If each pawn is spawning their cube, just set the owner on the cube to the pawn owner
I'm at work on a cell phone LMAO
Ok π
Who spawns the cube?
When the players are ready, the GameState calls a an event (RPC It's called i believe).
That event sits inside Player State.
Here i look who the Host of the game is and who joined, and based on that the cubes are spawned on their locations.
Ok so if the serverside PlayerState is what's actually doing the spawning, just set owner of the cube to the owner of the PlayerState
It's as simple as
Cube.SetOwner(Self.GetOwner())
why this way is because you get to create entire object graph for a player in one spot
a spot where that logic actually belongs naturally
its also the earliest point where that can be safely executed
@dark edge You mean like "Player State > Get owner > Owner (from SpawnActor Node)
Ok now im confused even more. I tried what you said @dark edge and to check if it works, i got the owner of the cube and made a print string, it was empty. So i made a print string for the owner of the player state and it was also empty.
Try the PlayerController. It's weird to be spawning stuff from the playerstate anyway imo. Do it in GameMode would be best but it's whatever.
PlayerState has a ref to PlayerController so you can get owner or set it as owner.
Yes I think you can set the PlayerController as owner and that'll do it.
I don't knwo why i choose PlayerState but it had a reason.
I guess it was because i didn't get the replication right or something.
Using the PlayerState or PlayerController as it owner wasn't working either because ithe server somehow couldn't tell the difference between the controllers, or i just couldn't get it done right.
But i just fixed it another way, but it hink its not good in the long run.
Im spawning the cubes on specific locations,wether i am the host or i joined the host.
Now if i want to move a cube i check if i am the host if not, i check if i joined and based on that a boolean goes true and i can move the cube from the array 1 or array 2.
Since im just testing my game idea and will do it better and start over when i finished the first version this is propably fine.
But i already thought myself it would be better to spawn the cubes over something else like PlayerController. The question who is the owner would be irrelevant.
And know i remeber why i choose this way of spawning i couldn't get to replicate the spawning and movement when i tried it over the gamemode and player controller.
anybody around who has experience with FFastArraySerializer? PostReplicatedChange/Add/Remove is only being invoked on the server for me
the documentation implies that it should be called on the client, but i can't figure out why that's not happening
It should only ever be called on the Client. If it's being called on the Server somethings up.
the plot thickens π thanks all, sounds like i need to actually look at the implementation to understand what is going on
Is there a way to know when a variable replicates
what I mean is
you change a variable every frame at 100 fps
But it doesn't replicate at 100 fps
so how do you know when it did replicate?
because there is really no reason to be updating it at 100 fps, but I really should just change it after it replicates
is there any way to know when that happens?
that is only the client though right?
I think maybe it is this
Called on the actor right before replication occurs.
Whether a variable has reached the client isn't really something you can know server-side, unless you send and RPC back to it.
you would just cap the update rate on the serverside if that's a concern
but you can know you sent it
what I am doing is updating a large array
replicating
of 4000
so I want to replicate it in batches of 500-1000
but I need to know that it was sent
maybe not received
but at least sent
before I switch to the next batch of 1000
so like update elements 0-1000
make sure it sent
then update 1001-2000
etc
rpcs seem to be a lot slower than replication
in my tests
Did you look at FFastArraySerializer? Won't give you quite the level of control you are talking about, but it gives a lot more control than a straight TArray replication.
rpc's slower than replication? π€
in my tests when i used rpcs they didn't perform as well as replication
what is the purpose of FFastArraySerializer
just reduced cpu load?
because you are still talking about sending 4000 array elements over the network
Primarily, yes. But it also gives additional callbacks for when the replication occurs.
Essentially makes it more clear client side on exactly which elements are added / deleted / changed
why are you sending 4000 elements across? what is this data?
Keep in mind, the client and server are NOT guaranteed to have the same array order (goes for both TArray and FFastArraySerializer). The only guarantee is that the client will eventually receive the data.
so its initial only
well it is as they move around
then only when as they do stuff
yeah