#multiplayer
1 messages Β· Page 21 of 1
with bad network emulation btw
What approach does Unreal use, just hard syncs every time or something?
i think so
no accounting for rtt?
I suppose that makes sense because you often DON'T want a real sync, you want to know what your view of the server's time is
I don't have the code in front of me sorry :c
yes that also makes sense, that's why I call mine non-destructive
it's explained in the article
I might just give this a go, ping jitters are refusing to let my rolling average stabilize
i'll send u the technique employed in PMs
I've linked the article several times now βΉοΈ
nvm I can't
We understand what you're doing, just saying it's not a great idea. You need an averaged RTT.
But if what you have is close enough just roll with it
well I'd say that it's not the best solution!
but it can work
I think I'm going to take a look now at the averaged solution
and add it as a post mortem
keeping shortest rtt
What about
OnRecieveServerTime
Error = Clamp(ServerTime - ClientTime, SomeRange)
Offset += Error
ClientTime = ServerTime + Offset
That's like a shitty PID right
I term only
I'm a fan of SomeRange
aka magic numbers
but really a PID like shifting might work
but honestly I think that the next step is going to be directly the moving average
gonna give this a go
oh no
quite literally min 3 max 7
π
what about building this with unreal's rpc π
btw what do you mean by.... repeated all over the place Laura?
I think I did
how much time between ping collections
between 2 consecutive measurements I mean
aight so i get that as fast as possible
right so... I'm going to do something to see if I bump those numbers
I'll send it back in here
thank you all, very valuable lesson learned!!
π
Interesting, wonder how choosing the fastest 3 might have contributed to the performance of the solution
Less prone to interruptions maybe?
the fastests 3 were averaged?
right its similar to what you described
i thought about doing a moving window with inbound packets capturing metrics every second
and computing average over that every second
my sample size would be the size of the window
right? XD
so not a moving avg but the average over the last 10 seconds
right but
this means u never stop updating the client clock
thats desirable
I just realized I started this network clock sync discussion 6 hours ago jfc
ikr
right but in a window its easier to get rid of outliers, right? XD
yes
the sliding window i like
but i need 100 measurements before i do the average
kekw
the global outliers would need to be based on magic numbers
:/
kekw
so the 10 moving window idea can work just good
and its the easiest
what i dont like is the magic numbers
reeee
ill think about it as the universal constant
JUST WORKSβ’οΈ
if you want it bad enough, every number can be your personal universal constant
magic numbers: size of the window and threshold for outliers
Still on the clock stuff?
Tune them to taste
Think "How much could I expect the actual ping to vary from average" and then clamp variance to that.
mh
I would clamp pretty tight honestly. It's ok if sync updates fairly slowly, it's far more important that it's smooth and constant
Or instead of a clamp do some power based thing to rescale
same as audio compression
I'm trying now Laura's method, the approach I'm going for is... 10 recordings over a full second and once sliding window is full I average it excluding outliders (max and min from window)
and I repeat this every 10 seconds
what do you think?
then I'll go for the more intricate solution
but I want to try these ones out
Server sends time once a second
Event ServerTimeRecieved
Remove oldest RTT, add new RTT
RTT_Average = Average 8 middle RTT of the 10
ClientTime = ServerTime + RTT_Average
Done
ah so u suggest to correct every second
instead of... correct every 10 seconds
i suppose that doing 10 recordings over a second would generate a somewhat homogeneous set of samples
You're better off spreading samples out rather than clustering them
ye
i figured
I wanted to see if I could correct less often to.... avoid seeing too many jumps in the clocko
If your RMS window is big enough your corrections should pretty much be super tiny
but you need a fairly high rate to be able to notice if network conditions change
neighbor starts torrenting and all of a sudden your average RTT goes from 20 to 120, you want to be able to notice it quickly
I'mma try it tonight with the PI approach, I think that might be very good because it'd capture the long term drift without being upset by short term changes in average RTT
the PI approach is the pseudocode you just sent, right?
just gotta figure the rate at which it happens
Nah like a PID but no D term
the faster the rate, the better, but the more network you use up. It's up to you
ah with the clamping ~
oki, and... what do I do before the window is full
just use the new incoming rtt?
Fill with 0 or first data point I'd say
Hey! general multiplayer question.
I've been researching about methods to pass client data to a server in the moment you join a session, i.e character selection in your local machine and retrieve that data once you join the multiplayer session.
Apparently game instance is the place to keep that data before/after joining session, and that is my specific problem. How to call the client game instance after I joined a session and avoid to call the server game instance instead?
Use the Options string that can be passed when you load a level. If you are a Client joining a Server, this string gets sent to the Server.
You can then parse the options out of that string, its custom so you can define whatever data you like in the following format.
Option1=Value1?Option2=Value2?Option3=Value3....
Thanks for that!
I'm using however Join Session from advance sessions, and that automatically travels to the server level.
once this happens all gamestates, ps, instances, controllers, etc are overridden
I reduced it to 0.02 π₯³ -> 1 second per recording, 10 recordings to compute average
void ARBPlayerController::NewClientUpdateWorldTime_Implementation(float ClientTimestamp, float ServerTimestamp)
{
const float RoundTripTime = GetWorld()->GetTimeSeconds() - ClientTimestamp;
RTTSlidingWindow.Add(RoundTripTime);
RTTSlidingWindow.RemoveAt(0);
TArray<float> tmp = RTTSlidingWindow;
tmp.Sort();
float rttavg = 0;
for (int i = 10; i < 90; ++i)
{
rttavg += tmp[i];
}
rttavg /= 80;
ServerWorldTimeDelta = ServerTimestamp - ClientTimestamp - rttavg / 2.f;
}
^ I reduced it to 0.01 by simply increasing the rate and the window ^
Never used that, sorry.
One thing I meant to point out earlier, but when executing RPC's on the receiving end, the TimeSeconds value hasn't updated yet since that is done after the TickDispatch (check out UWorld::Tick()), so if you want to use the World time for the current frame (a.k.a the time you would get when ticking the frame where the RPC was received) you'll want to find some way to delay your timestamping to later in the tick or add in the global frame delta seconds (which won't get dilated so if you're using dilation beware)
right
Hello, i'd appreciate if someone is willing to help me understand how server world is meaning full
Is there any reason to run functions at the server other than to multicast?
yes, you can run whatever you want at the server, and update replicated variables
@pallid mesa btw I was able to get hard travels being seamless working. The majority of the work was dealing with loading. And yea the key difference between seamless travel and hard travels in UE is that's the only way UE can enforce stable names/ids for objects. Using our own custom stable naming system we are able to not have to hard reload a level.
Does the client host(in a listen server) runs "twice" every frame? once as a client and once as a server?
YES!!
that's fantastic news @barren surge don't let this die and write something about it! β¨
Haha so many articles I'd like to write, hoping I find some time.
this one is specially.... key there's nothing done like that ever before ZabirH, I'll keep encouraging you to do it!
it's such an achievement, and I'm glad it worked out
Thanks!
Is that possible to be connected to two servers at the same time?
Like a constant connection with a master server
hi Khen take a look at Cedric's networking compendium, it'll clear things up in that end
really appreciate it!!
Basically take a look at the resources pinned in this channel
Thank you for the directions
any time, if you have any specific question after revising basics, we are here :)
But I will say it's far from production ready. My test levels are pretty small. It looks like there is a bunch of loading work I still have to do and I've done a lot of this via engine changes.
After all the time i've used discord i didn't knew that was a thing π
hey it's a start, you think it's achiveable through overrides and such?
Not ATM, I had to hack out a lot of the level loading flow.
btw, I will probably release an article about data streaming checking against the reliable buffer, if that helps
Basically I'm running all the connection establishment code but not triggering level loading cause I know everything will be named/ID stably. That's a big assumption for UE.
WizardCell will love hearing this, he's on vacation now XD
And then we use our custom protocol to tell the server of client state and server verifies or sends corrections.
that's nice! I wonder if this new article will help you at all
its to avoid filling the reliable buffer when sending big chunks of data
Well it's always great to read your stuff regardless of this specific work!
oh no, just wondering if it would, to hurry up a bit π
in all honesty, I'm lazy ~
but if there's a drive, I jump into stuff
basically it all started changing ReplicateStreamingStatus, different use case but if you have a case in which you are required to send corrections
and specially tons of them....
it might be problematic
but you said you got a protocol, right?
Yea, it collects all objects on a client and client assigned ID and asks the server for the real Names/IDs. Server uses type and few other properties to assume what actor the client is referring to.
The other thing we do is for client predicted spawned objects, we tell the server what the client spawned ID is and server will spawn using that ID (of course we use top bits to partition client specific ID so no two clients can generate same ID.)
I have an actor placed in the level and it is replicated. It can't RPC from server -> client, how come? I wouldn't expect it to need to be owned by a client to RPC that direction
It has to be
On my way back π
So if I get it right, seamless travels don't keep actors that were forced to be stably named, stably named?
iirc Rename is called at some point when a (seamless) travel occurs, but yeah I haven't looked much at that part yet. I can see this be a problem for dynamic actors with stable names
If it's Multicast then I might have had same issues, don't know wjat that's about
If it's Owning client, then the word "Owning" is not for no reason here
You need to call SetOwner on that actor with some actor that, directly or indirectly, owned by a player controller
How do i set an actor as autonomous proxy on blueprints?
Multicast would work fine. client and server rpcs need an owning client. You need to perform the rpc in the character already if you are trying to interact via key press.
I usually call that the door problem when teaching some of the fundamentals
Opening a door in the level as a client needs a lot of the basics being applied. RPCs, OnReps, Ownership etc
In this case itβs server to client not client to server so I wouldnβt expect it to be an ownership or net authority issue.
Further testing makes me think the client simply didnβt exist yet to receive the RPC, since I was doing this on game start on a listen sever. Delaying the rpc as a test causes it to work, so bit of a false alarm. Thanks everyone!
Is it possible to set up online multiplayer using only blueprint? i have advanced sessions plugin but im getting join session problem
@dark edge @whole grove https://vorixo.github.io/devtricks/non-destructive-synced-net-clock/#based-on-a-moving-window-discarding-outliers
I've implemented avg rtt discarding outliers, and I've collected some new results. Thank you two for the help, got it integrated in the blog ^:
add newest at the end
remove the oldest at the front
like a cyclical buffer
@whole grove
also btw same algorithm but instead the for loop doing from 1 to 9, doing from 0 to 3?
Hello! quick question.
In multiplayer, calling to the game instance will always return the local machine game instance instead of the server one? Is this the correct way to retrieve persistent data after travelling?
The game instance is indeed only available locally, so you could use it for that purpose yeah π
Hey. Out of curiosity is this how the seamless travel between levels works that Unreal currently already does when the server switches maps or is it truly "seamless" as in the way that the client stays in a world and then loads all objects etc. given from the server? π
Last one would definitely be very interesting π
Interesting in general though, don't get me wrong.
The goal for me was to build something like Destiny or Division where matching make could happen and a different set of clients would connect to a new server without having a blocking load of a map. Out of the box, connection to new servers must be what UE calls "non-seamless travel". My guess was that UE requires non-seamless travel for new server connection to ensure object names/ids are stable. This is also why once connected to a server subsequent travels can be non-seamless. I had already come up with a way to spawn client side predicted objects that was consistently named (client actually tells the server of the event + spawned ids) that I was able to reuse for making new connections to server work with objects the client had already spawned but now connected to a new server.
So if I understand you correctly, same client world but different servers you can seamlessly connect to if needed?
No the opposite - seamless travel works in UE because the server can rely on the fact the client loaded object will have the same name on server and clients. Maybe I'm miss-understanding your question?
yes.
That's awesome, well done π
Does anyone know how the server tells the client to destroy a component that was destroyed on server ?
Its very rudimentary atm. Very far from actually being like Destiny or Division.
@whole grove avg error went up by picking the 3 fastests, with 4 fastests is kinda comparable with the middle-section method
On the server the component ptr is nulled out, thus the "null reference" is serialized into a FBunch and sent to the clients. The clients then set the component ptr to null and GC actually cleans up the component some time later. Best of my recollection. If you want to confirm, put a OnRep on your component pointer and watch for when it fires and look at what was read from the FBunch to trigger your OnRep.
what about default objects created in constructors without the replication flag
addressable just by the path
If no replication flag than, it will not replicate from server to client.
would defaultsuboject created in constructor of the actor won't destroy on the client if actor is replicated but not the component itself
Yep, that is my understanding.
If a prop is not marked replicated, then no syncing between server client.
something about that tells me that it need more cleanup than just nulling it out , like the destroy callbacks , I think it'll be more fruitful to do a debug break on destroy for teh client
Yep, that is def the ground truth! OnRep + UActorComponent::Unregister() are how components are removed from active play.
I'm guessing there is logic that if the UPROP is a UActorComponent, before it is reset (right before OnRep is called). it will unregister it.
20% culled, isn't so bad
culling the 40% of the samples is more aggresive :v
okay let's try to cull the 40% of the samples just for the shake of numbers
π
I'll report back
Thank you!
Stream question.
Is there any risk of losing sync when using a stream under the same function. i.e the scale being set before a rotation and viceversa between server and local machines?
I noticed after around 100 world generations, there is an small chance 5% of having a different result in that instance generation between server/client, wondering why since there is no branching logic
I'd maybe set the output from the random functions into variables and then use them. Could maybe help just in case there's something strange going on with how its getting interpreted.
How are you actually getting your data? How do you do the snapshot
I don't know a lot about streams but don't they advance their state every time they're called?
so race condition?
on tick querying the value every frame
This might be an engine bug but If I rejoin after component is destroyed on the server the component returns on the newly joining client and ticks like it always existed.
This is valid for components created in the constructor
maybe I need to set the constructor created pointer to replicate as well
Edit: Didn't change anything , so yeah the component will be recreated on join and tick again, Gonna try Dynamically created component
Edit2 : so it works if the component was created at runtime, gonna try on blueprint added component next, Same result
So for a component to be die clean on replication it has to be created at runtime and should be a replicated component, those are the two absolute requirement
Endgame is the GUID for the object going null on client causes it to be destoryed
UPROPERTY(ReplicatedUsing=OnRep_something)
He's talkin' about one that is already replicated by the engine. Not a custom one.
At least, that's how I interpreted it π
ah
Yeah - so which one did you mean @dark edge? One that is being replicated by the engine already, or a custom one you created?
you see my ghetto Onrep in that BP lol
I don't think you can do that without changing the source code for that variable
however
you can use something like PostNetReceive on a derived CPP class
which should get called when properties get replicated from server
so its kind of on rep , but for everything
Yeah this was just a quick and dirty prototype to join the network clock shenanigans
@pallid mesa
you could also just create a second variable in your derived class and replicate that with onrep and disable the first one with DOREPLIFETIME_ACTIVE_OVERRIDE
Yeah, it was a race condition, not in that very function, where the chain of position, rotation, scale will be always in this order, but a race from server to client replicating the integer that defines the seed, rep notify fix it.
I posted the code. Just a simple smoothing on ping using exponential running average
ah I cannot see the code, where did you post it? π
I'll try a proper PID next, I feel lik that would lock in faster.
Also haveing a repnotify on ping would be great, I just did that nearly equal test on tick to detect when it replicated, quick and dirty
mhm, yep, it'd be nice
also I had a chance to look at the gamestate implementation of their replicated clock
and it's odd
posting in here for you to see
If it's overridable that'd be the best approach to improve the accuracy
then anything can just Get Server Game Time as if nothing changed
i preffer non destructive, because it seems that servertimne is latent
but.... they are trying to do something...
look at this
what does non destructive mean?
void AGameStateBase::OnRep_ReplicatedWorldTimeSeconds()
{
UWorld* World = GetWorld();
if (World)
{
const float ServerWorldTimeDelta = ReplicatedWorldTimeSeconds - World->GetTimeSeconds();
// Accumulate the computed server world delta
SumServerWorldTimeSecondsDelta += ServerWorldTimeDelta;
NumServerWorldTimeSecondsDeltas += 1.0;
// Reset the accumulated values to ensure that we remain representative of the current delta
if (NumServerWorldTimeSecondsDeltas > 250)
{
SumServerWorldTimeSecondsDelta /= NumServerWorldTimeSecondsDeltas;
NumServerWorldTimeSecondsDeltas = 1;
}
double TargetWorldTimeSecondsDelta = SumServerWorldTimeSecondsDelta / NumServerWorldTimeSecondsDeltas;
// Smoothly interpolate towards the new delta if we've already got one to avoid significant spikes
if (ServerWorldTimeSecondsDelta == 0.0)
{
ServerWorldTimeSecondsDelta = TargetWorldTimeSecondsDelta;
}
else
{
ServerWorldTimeSecondsDelta += (TargetWorldTimeSecondsDelta - ServerWorldTimeSecondsDelta) * 0.5;
}
}
}
keeping the vanilla functionality intact
I mean if you look at this... it looks like they are trying to.... compensate something
serverside polls at a fixed frequency of 0.1f
configurable in the CDO
That kinda looks like a PID
with P term only
but with no latency compensation
is it should be accurate but always BEHIND by RTT/2
So you probably can just do something like
ClientGameTime = ServerGameTime + RTT/2 and get something fairly accurate
although RTT changes all the time so you wanna filter/smooth it.
sn't ServerWorldTimeDelta their RTT in their onrep?
You basically have 2 values you're trying to calculate.
- An accurate and representative RTT
- Static time offset.
I think that's the delta between recieved time and local time
ah yes!
They're doing static time offset calculations only. Nothing with RTT to try to get an accurate non-delayed synced clock.
yes xD got myself confused there
I'm going to try the method I got for computing RTT
with the averages discarding outliers with this
Guys please send help. I just spend a total of an hour being confused how an AddActorLocalOffset was being triggered for the 2 other pawns out of 3. Turned out I'm an absolute idiot and didn't put anything in the level to compare the movement with, so it looked as if the other pawns were moving while in reality my controls were inverted.. So if I moved up it looked like the other 2 pawns were moving π€£
Was adding checks everywhere, commenting out code, looking through engine code only to just make this dumb of a mistake LOL.
@dark edge tried adding the RTT/2 to the return of the vanilla clock and.... didn't work
It's not as accurate as what I made but it's pretty close on my end.
That's just GetServerGameTime + SmoothedPing/2
so it might be that your smooth ping is OP
or I don't really understand what is going on here XD
You should start with trying to get a nice smooth ping value
Show how you're doing your 10 window average
void ARBPlayerController::NewClientUpdateWorldTime_Implementation(float ClientTimestamp, float ServerTimestamp)
{
const float RoundTripTime = GetWorld()->GetTimeSeconds() - ClientTimestamp;
RTTSlidingWindow.Add(RoundTripTime);
float AdjustedRTT = 0;
if (RTTSlidingWindow.Num() == 10)
{
TArray<float> tmp = RTTSlidingWindow;
tmp.Sort();
for (int i = 2; i < 8; ++i)
{
AdjustedRTT += tmp[i];
}
AdjustedRTT /= 6;
RTTSlidingWindow.RemoveAt(0);
}
else
{
AdjustedRTT = RoundTripTime;
}
ServerWorldTimeDelta = AdjustedRTT;
}
Why aren't you getting Ping
You can't derive ping, you need to get it
unless you're calculating it by sending stuff from client to server but you already have a replicated Ping in Playerstate
You could do a sort of pingpong thing where you go like
Client->Server send Time
Server->Client return that time and server time
Client Do Math
that would bake in an implied ping from the timestamps
mhm, that's what I'm doing here, the whole algorithm is here: https://vorixo.github.io/devtricks/non-destructive-synced-net-clock/#based-on-a-moving-window-discarding-outliers
click and you can see it
scroll a bit until you reach the cpp part, based on => client -> server -> client
if (GetLocalRole() != ROLE_Authority)
{
RequestWorldTime_Internal();
if (NetworkClockUpdateFrequency > 0.f)
{
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &ThisClass::RequestWorldTime_Internal, NetworkClockUpdateFrequency, true);
}
}
now, brb
Now multicasts do drain performance, but is there another way to show a particle effect on all clients without it?
using the spawn niagara system node
is that the only way?
no, but it's the best way as vfx are usually one-off events unless it's a stateful VFX
If something else triggers it you can do it through that, imagine you open a door you likely already have something telling the client to open that door. If there's nothing in place for being able to know that particles should play somewhere then you need a RPC I suppose.
correct if you are already on a multicast execution context for whatever reason, you can reuse that
there are a couple of use cases that are convenient
event destroyed executes everywhere so you an play particles at actor destruction without need of extra logic
You either multicast or you spawn the particle effect based on some already replicated state
Like you wouldn't multicast a bullet hit effect. You would spawn the hit effect on machines locally whenever the local bullet hits something
lmao
i mean i think it's one of the most important topics that rarely gets spoken out
Yeah your answer to Thom cleared it up. Hard travel ensures objects are stably named, while seamless doesn't. That's a big achievement till this becomes a thing:
That is one way π
More ways here: https://wizardcell.com/unreal/persistent-data/
Hello, I have a problem, I made my hotbar work with multiplayer, its functional, but visually it isnt, Im having trouble with setting brush from texture, I will provide pictures of the blueprint, it only seems to change the brush in single player/standalone, not client, I wqas thinking about using interfacs for this but figured it wont work, am I casting incorrectly? Im having no errors, any help would be appreciated, Thank You!
I assume that second image is your HUD widget construction, what's the value of Get Player Character when that is running? My first guess is that runs before you spawn your replicated character in multiplayer scenarios
Oh that is in the widget aswell, its just on begin play I cast to my main character and make that a variable, I need that as a variable because in my main character I have a hud reference which I need to pull in order to get a reference to the slotsd
Ah gotcha, didn't read your full question, what does your brush texture setting look like?
one sec will provide image
First picture is how im setting the image second is the data table which I pull the image from, (not sure if the DT is relevant but oh well)
The individual slot is just a blank image and a button, and I need that image to be switched to the jutsu image, it works in single player not multi tho
here is the hud, as you can see im casting there because that where the slots are
just providing as much info as possible
if you put a breakpoint on the SetBrush, is your texture a valid reference? How about the Slot and Image?
let me test this one sec, I will put breakpoint
yep validated get printed as succesful for slot 1 and the slot works, before I had it so that you could change your ability I just had some crappy system that was in the slot that updates the ability after some delay, not sure if that is relevant, so in summary, the slot has no problems, and the brush didnt give any errors
Do you think perhaps I cant edit widgets in different widgets for multiplayer? cause if so couldnt I just use an interface to communicate between the two widgets, not to good at multiplayer but just thinking of some ideas
Also the actual ability works just not the image, not sure if I mentioned that
You can definitely edit widgets in multiplayer, when you debug in editor, is there only one instance of your HUD widget? If your calls to set brush are succeeding, then my next guess would be maybe you're somehow creating multiple hud widgets and displaying one that you're not updating
Hmm on both clients its showing 3 different mainhuds on both clients, here is a pic
Your first picture above where you create the HUD widget, what blueprint is that in?
I create the hud reference and overall hud in my MaincharBp/ThirdPersonCharacterBp
Ah, yea so the problem is that when there's multiple characters, your creating a HUD for each of them, but you really only want to create a HUD for the local player's character. You'll either want to spawn the HUD from something like your Player Controller, or in your Character's Begin Play, only spawn the HUD if the player is controlled by the local player. I don't remember the exact blueprint nodes, but there might be a IsLocallyControlled or something similar
Oh I know its just a branch and then the condition is (IsLocallyControlled) Should I add that and test it?
Yea, I'd try that in your BeginPlay real quick just to see if that is the issue
Woah! you fixed it, Thanks Man, I cant beleive something like that would have halted my project for a while, Thank You! π
can a regular c++ array be replicated?
example:
UPROPERTY(Replicated)
AActor* Items[5];
I'd recommend moving your HUD spawning out of your character in the future. In multiplayer, the Player Controller only exists on the Server and the Owning client, so that's generally a good place to initialize HUD things
Only Unreal Types and common POD types support Replication.
Agreed, id definently consider, Thank you
You would need to use TArray to replicate an Array.
riparoonie. thnx.
If you change your setup to
UPROPERTY(Replicated)
TArray<AActor*> Items;
It would work, mostly the same, you can even initialize it to size 5
yeah i know. its just the way the existing code was set up in this project i'm working on used regular array. i'm gonna have to use rpc unless i change things in numerous areas of the code π«
So when you want to execute something on the client only character on an actor, is the best way to call an event on that playerβs character or is there a better way? Iβve been finding myself creating too many arbitrary functions for different actor interactions in the character class.
Either that or look for suitable client execution paths, for example BeginPlay client-side
That variable has already been propagated, i.e, part of the initial bunch.
It got set using the value from the CDO when the initial bunch was sent.
So the default value (probably false) is what got sent
Yes. Set that variable after you spawn that actor
Setting the variable has to happen at the same frame the actor is spawned
You can, if you do it in one of the functions that are part of the actor creation cycle
That or try doing it in BeginPlay server-side
No delays or calling other functions
Yeah I will likely do that
No worries. Checking this server search tool can be helpful too π
Is there any way to implement rollback netcode to Unreal? Has anyone done it in any game?
Obviously it sounds like a daunting task - haven't found much info material on the matter (UE related)
I've been researching what Overwatch did and it's pretty interesting
Why would a replicated TArray of structs not call an OnRep when one of it's structs replicates a property?
Full breakdown:
I have a replicated component on a replicated actor, with a ReplicatedUsing TArray of structs. The struct is just a GameplayTag and a Float. In server code I change the float. This gets replicated to the client(I'm testing this by making the client UpdateUI on a timer instead of the onrep delegate), but does not actually run the OnRep associated with the array that the struct is in when client receives that float change. This same OnRep is used for two other properties, which it runs fine for, just not this.
that's interesting
hey guys im creating a online multiplayer game and im using blueprints ( i dont know c++) the thing is i need help with online server setup. which way is the easiest way to do this i dont want a advanced version i just want 2-3 player can connect and play the game i made together
Does ue has any build in system for setting up maximum amount of players on the server, or do I need to implement it myself?
It does. Check AGameSession::ApproveLogin. The property is called AGameSession.MaxPlayers
Check advanced sessions plugin and make it a lan session probably
Is there somewhere a proper documentation for using Steam Voice Chat? Or is it as simple asi putting few lines inside DefaultEngine/DefaultGame.ini and executing ToggleSpeaking 0/1 ?
Do you know any tutorials that explain AGameSession?
Not that I know any. I would just dive through source
hey i can create LAN servers but i want to create a non-lan server (idk what is it called) like im in A city and my friend is in my B city and i want to test and play our game together
Then you want to look for a host service, for example AWS, which will cost you money, or they may offer you free lite versions.
Or use something like Hamachi to create a virtual lan
Thanks! maybe after some development I may need a server to release it. i can use AWS but i really dont know how to use it. when i buy the AWS is it easy to setup? how to set after getting a host server
also can these be done with blueprint? or do i need to know c++
Not that I have experience, but you would need to check their manuals and SDK docs. I would assume cpp is needed, unless there are plugins out there that do it for you 
Hi! Will the GameState persist if I use seamless travel? or is it only the GameMode?
Sadly that's wrong π¦
Or not explained well
Check my baby: https://wizardcell.com/unreal/persistent-data/
I will, thanks
so how would you solve a situation like this: Players join the server, they select their squads. When the game starts, the server travels to the game map. How could I access all the player squads that have been created?
So I'm thinking about making 2 sub actors for every base character in my game. One sub actor will have a high net update frequency which holds very important replicated properties, and the second sub actor will hold less important / less likely to change properties with a very low net update frequency and focus more on utilizing force net update calls. Should I do this with 2 components instead though? I feel like it's more limited if I do it on a component. I'm having a big big issue with a lot of replicated properties that don't always need to be checked for updates
I would persist an actor that handles team management. I talk about that here (example provided): https://wizardcell.com/unreal/persistent-data/#5-getseamlesstravelactorlist
@rotund cosmos
Thanks Ethan π₯³ β€οΈ
np β€οΈ
I would just have the properties reside in their logical classes and have PushModel turned on
You can also go for a similar approach to what Fortnite did, if you feel you are replicating too much data, and just replicate the bare minimum, by having a struct that entails such properties and pushing those values through some other actor
They call this "proxy"
The latter sounds kind of like what I was thinking
Thanks for that. Also push model?
Is there docs on that too?
Never heard of ot
Pretty sure there are none but what you can find in source
Hopefully I will get the time to write on that one soon
Check PushModel.h
I'm a blueprint pleb. But my biggest issue is honestly just the server checking a lot of stuff that it didn't need to check
For example I have a replicated variable named isinair. And that variable hardly ever changes right?
But its still being checked a lot
Every server update cycle
Yeah that is PushModel territory really.
Though you'll hardly notice any gains
You can go fancy by using net managers if you feel you are replicating too much actors
Probably not with that one variable but with the base character... with 10 players in the world its taking 0.1 seconds to get through all those replicated properties
https://vorixo.github.io/devtricks/network-managers/ - from this channel pins
Yeah the more players the more it's noticed. It was made for Fortnite so you get the drill
It said 153ms I believe which is a lot. So I'm assuming if I can bring that number down by a good 100ms my server performance could go up right? Correct me if I'm wrong but I figure
If the player has an update frequency of 100 and it takes 0.1 second for 10 characters
That's gotta be eating a big chunk of server performance
After I override AGameSession, where do I register new class, or what should I do with it?
PushModel will help decrease that figure but I can't quite off say how much that would be. You will have to do your tests after utilizing PushModel and if that wasn't decreased by a big margin then you'll need to consider Net Managers but that's a cpp territory @short arrow
Yeah thanks for 2 options. I'll definitely look into both βοΈ. Also heard about net manager, I believe vorixo made a whole blog post about it
Unlucky c++
Thanks again though
He did π¦
No worries π₯³
I went bankrupt, brb
But honestly I wish connecting servers and servers in general aren't such a pain. You either need to use something specific to the platform/store you're on. For example Steam's integration. Which often is free though but then you want crossplay and the madness begins, do you roll with some company that provides relay servers and all that stuff for often way more money than you would like to, do you go for EOS which requires an account which for small games that need every player they can get really is not ideal either. Do you role your own system? Which is quite complex beyond a few players.. Then we have the entire dedicated server madness. Why can't it just be easy lol.
"We ... do the other things, not because they are easy, but because they are hard"
Cross-platform play is going to require an account regardless of what route you take. So EOS helping in that regard is a non-issue.
Make creating an account super painless and 99% of people don't care.
Crossplay does not necessarily require a separate account though. If I want to play my co-op game with a friend who has it on Epic and I have it on Steam I could authenticate with the platform specific accounts.
But yes it's definitely more common to have.
Yes, just a few simple details...
Email address, login name, password, drivers license number, SSN, DoB, 3 security questions, and whether or not they want to use 2FA. Easy.
The thing is that linking an Epic account or a different account definitely scares off people. I have a friend who was playing a Steam demo. You needed an account for it, the moment he saw that just clicked away the game.
yeah I'm not keen on linking accounts all over the place myself.
And I'm not saying it's the majority of people, but I don't find it ideal either lol.
Is it not possible to use both and just have the engine detect which one is in use?
Err.. I guess it wouldn't work too well for sessions and stuff..
Sorry, detect what?
Which online subsystem you'd be using (Steam / EoS)
I know Satisfactory does it, but I'm not sure how it exactly works I must say.
They link I think
At the beginning of the game you can pick either one and then roll with that, but to change you need to contact their support I believe.
Been a year and a bit since I recall seeing that message, but that does sound right.
Can you actually look up sessions in Satisfactory now?
I know more recently they released a dedicated server build, but I was under the impression you needed to use an IP. I don't have it installed myself right now or I'd check XD
In terms of just using an ID to authenticate, I know with steam you can grab their steam session ticket and validate it on the server through a Steam API call, I would imagine EoS may have something similar.
Probably yeah.
i need a quick refresher on something
when calling a RPC which takes in a UObject pointer from the client, the UObject needs to exist in the server too right
also, what happens if i change a replicated TArray in a client?
It does need to exist on server as well, yes. It does not necessarily need to be replicated. For example a StaticMesh will resolve the same on a server and client and as an asset it's never replicated. If it's a runtime UObject, it would need to be replicated.
As for TArrays. Nothing will happen immediately. The client will just have differing data than the server. The server will not correct this unless whatever you specifically changed was changed on the server though. If you remove enties on the client, and then the server replicates some other change to the array, it'll just populate empty entries.
so changes in replicated variables propagate from server to clients
unless you do conditional stuff
Correct
i'm doing some kind of command pattern for RTS
been having issues with executing them on the server from clients π
because some of the logic does not need to be serverside and they're hot calls
for example when moving many units into a formation, holding right click will activate rotation mode for the final formation, which will probably run on tick or some fast timer
it should probably call a RPC with the final unit positions when you release the mouse button after rotating
synonymous to Total War?
thankss :3
i can't remember how it worked in total war
but imagine when you right click to give a movement command, you can hold to give a specific rotation
to face the formation to a desired direction
when you release then the actual commands will be send to each unit with their respective position
Basically that. Total war also sized the formation's width based on how far away you moved the mouse from the original right click point.
i tried raw classes for the command object, which made everything much more complicated
oh, i was thinking about using the scroll wheel to adjust the spacing while holding
now i changed it to UObject to be able to benefit from the engine's network pointer magic
I'm not sure why you would need more than an RPC of structs. Struct has location, rotation, and intended unit width?
Does even AGameSession exist on Dedicated server?
the command class has virtual functions which can be overridden in derived classes
there are gonna be command objects for movement, attacking, patrolling etc
they are pretty encapsulated, they manage their own lifetime
so i need to create the command objects in the server
Would probably just keep that with the lifetime of the unit and replicate it to who needs to see it. When giving an order let client locally manipulate it. Send the order through the unit's owner(PlayerController) as a struct. Order type, array of intended movements as location,rotation,etc. Server can replicate the new state to everyone if everyone needs to see it or just keep it on server as where/what the units will move/do. Should be pretty light. Less object creation with constant order spam, etc.
the orders are created in the player controller, and then added to a command queue array in the unit's AI controller (which does not exist in clients)
the AI controller's command queue is kind of a FIFO buffer
it starts executing from the oldest command if there's something in the array
i guess for now i can do a base implementation which has most of the stuff running on the server
Just imagining visuals and stuff. Waypoints and whatnot. Just seems easier to attach an order object/actor to the unit and let them share lifetimes. The controller can even get it directly from it's unit if need be. Or the order thing can be a sub brain and send new orders to the controller once a current order has been met.
virtual void Execute();
virtual void Cancel();
virtual void Finish();
these reside inside the command object
the AI controller calls execute for the oldest command
that part works pretty well right now
i'm kinda lost on efficiently creating the commands
i think i'll move more logic in the player controller to server side
because when clients try to issue commands, the RPC gets a null command object
Hi guys. I've got a weird issue with my character animation glitching while in playing multiplayer. It does not happen if I open multiple session from UE editor as a listen server - only when testing over the network.
My only guess is that something is not replicating but for the life of me I don't know what.
my first implementation had raw classes wrapped with USTRUCT
which failed, i think i need to serialize the raw class anyway
for example, move command has a location and a direction for the unit to face when it arrives at the destination
it also overrides Execute() from the base command class
Yeah that's tricky. Would need an rpc per data set which is shit
Does the server have all information needed by chance?
Aka can it generate the data
that's probably the part i'm having problems
there is an actor array in the player controller
for selected actors
I mean generally you only need to sync data generated by inputs
Mouse location for example
How about SetOwner()? Or would that mess up server RPC calls?
when you right click, i'm doing a get hit results under cursor then determine what command we need to create
SetOwner only allows one owner at a time and needs to be called on the server
Despite that you can use that to allow rpcs
then for every selected actor, we create a command object and send it to the respective actor
Yeah so with GAS you usually just send the Mouse Location to the server and let the server do the targeting
You could also let the client do targeting but cheeeaaters
for some commands i need to create a command object for every unit because for example to move units into a formation they all need to receive a move command to their respective position
the formation positions are calculated from hit location, i was doing that in the client
i couldn't think of a reason to do that in the server
but i think i'll just move the whole thing to the server for now
call a rpc with the trace results, and determine command type in the server, then issue the commands
but then i need to move unit selection logic to the server too, as the server needs to know which units a player selected
i implemented the selection logic client side as it had no gameplay effects, you couldn't issue commands to units you don't own anyway ( even if you cheat to select them )
is it worth implementing gas for RTS?
now that i think of it, it handles network stuff too so lowkey makes sense
would it scale well with a few hundred units?
( probably scales better than my own implementations anyway, even if its marginal lmao )
Hi, I'm new to MP, I'm currently trying to implement MP into my project that has GAS in it, I had to clean up a lot of stuff in order for it to work, but with this one particular problem I'm at my wits end... The character doesn't have anything fancy going on with Movement component etc... nice and simple movement, yet it lags both on Client and Listen server... any other Pawn/Character works perfectly fine, yet I'm strugglin with this one...
its gonna be the third rewrite of the command system if i'm gonna implement GAS 
Anyone any experience with this kind of Lag??
You need to set the movement speed on both the client and server.
I'm setting the base speed with attribute sets, thought that this way it would be set on both, how does one set it on both?
It unfortunately canβt be done in BP if youβre adding sprinting.
I have that set up tho
Basically the whole MovementCOmponent
Although I took from the Tranek/GASDocumentation
Nearly identical
just to verify it's corrections that are the problem, can you do p.NetShowCorrections how are you setting the base speed? If it's through a gameplay effect, it should be on both unless your attributes aren't replicating
SetOwner(nullptr)? non-owned actors behave like server-owned.
Whenever I try to use that command, it doesn't really do anything
Am I using it wrong perhaps? "p.NetShowCorrections 1"
let me double check
yea that should be the command, if you're not seeing red/green capsules showing up, the the "lag" isn't due to movement corrections, it's something else
Then I'm even more confused as to what could be causing it
I had a problem like 2 days ago where the attribute set refused to give me anything else other than 0, which resulted in an actual cluster ******* of movement lag on client, while the server was ok... But I just forgot to replicate MovementSpeed, which I fixed, but now I'm stuck with both client and server lagging just a tiny bit
Any other idea you might find plausable?
Cause I straight up ran out of them, been testing 'till 8AM, got 3 hours of sleep and have been trying to fix it since
Oh this even happens on your listen server's character? So not replication related then, probably something going wrong with your movement simulation. How did you integrate the attribute sets into your char movement comp?
The component calls a getter for the movement speed, which just returns the value from the attribute set
Have just been testing if the function is an issue, it's not, so ignore the 600.f
The attribute set has delegates bound to it's attributes, so whenever I change the attribute, it changes the value of MaxWalkingSpeed
In the video above with the laggy movement, is that just walking speed that was using the Owner->GetSpeed() before you hard coded it?
yup
And does GetSpeed() just return your MoveComp::MaxWalkSpeed value?
And with the 600.f it's the same deal
Returns a value from the attribute set, which should be the exact same
I'm confused what the SpeedChanged callback is doing then, if you're just reading attributes from the attribute set, what is that MaxWalkSpeed that you're setting?
Well, if, let's say, a gameplayeffect changes the value of an Attribute "MovementSpeed", it will change the value of MaxWalkSpeed according to the attribute
wait
Doens't make sense, does it
Am I just doing this whole thing wrong?
I don't even know... Changing it did absolutely nothing xd
In your GetMaxSpeed function, if you just change it to return the Speed Attribute's current value, do things stop lagging?
Also can you just paste what your Owner->GetSpeed() function does
Idk, still continues
What is the overhead for encapsulating behaviour in a component? I have noticed that CharacterMovementComp is using Character for all of its replications and now I am not sure what is the most optimal way to handle encapsulating replication.
When you send RPC's through a UObject (aka actor component) the payload uses an extra identifier to specify which object the Function needs to be called on. So if you're sending an RPC with very high frequency (every frame like movement component) then those extra identifier bytes can add up. I think that's really the only concern, so you could probably get away without doing it, but just paying more in bandwidth
It's not a lot. But also do be aware that CMC is older than Components having replication or networking. It was less of a design choice for that component.
Thanks for the explanation! I guess it's not something to worry about. @kindred widget I believe moving the replication from component was quite a recent change, this is why it was so concerning.
If it makes sense to keep it in a component, keep it in the component. Chances are there are likely many other ways to trim performance issues 'if' you actually run into them.
Hi, I'm having an issue with my interaction, I have a base class that all interactable objects derive from, which is used to display some widgets indicating that an object can be interacted with, when a player overlaps with the interaction overlap box it adds the actor into a array of overlapping actors and then it would display the widgets
then when the player actually interacts with the object that they're overlapping, it checks if the actor is contained in that array, however for some reason this works fine for the server player but all clients are returning false on this if check as if they're not overlapping the box, which they are
any ideas why this wont work for clients?
Also my interaction set up
The print statement after being added into the overlapping actors array in the first image is telling me that the length of the array is 1, like it should be too
You are populating the array client-side
And checking if the element exists server-side
Which it doesn't
Whats the best way to do it to push to the server? because all my interactable objects derive from this class so i need it to add the actor into the array from here i think
whats weird is that its been working perfectly for ages but for some reason stopped lol
It works fine for server, but not for clients.
Keep it all server-side I guess
No IsLocallyControlled involved
Instead make sure you're on server (gate with authority for example)
I need to keep the IsLocallyControlled check, without it if either the server or client is standing in the box overlap of an object it displays the interaction widget but everyone can see it (image below), with the IsLocallyControlled checks it makes it so only those within the overlaps see the widgets
Then you'll probably need to use a sequence. Top can use the Has Authority check, and the other that uses IsLocallyControlled to display your widget.
Exactly, those are different execution paths
It's sad how this guy copied Cedric's compendium without even giving him credit: https://russianblogs.com/article/80371517154/
Network in Unreal, Π ΡΡΡΠΊΠΈΠ΅ ΠΠ»ΠΎΠ³ΠΈ, Π»ΡΡΡΠΈΠΉ ΡΠ°ΠΉΡ Π΄Π»Ρ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠ΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΈΠΌΠΈ ΡΡΠ°ΡΡΡΠΌΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠ°.
Unless I'm missing something
*1: Despite my own knowledge, I used the official Documentation, as stated at the
beginning of the Compendium.
*2: The main network framework, as well as the two (recreated by myself) images
of the distribution of common classes is documented by 'Nuno Afonso'
and can be seen here: www.nafonso.com Thanks for this amazing page!
*3: Nearly all examples, Blueprint Pictures and C++ Code, are created by myself.
Which is both in the compendium and on this website π
@fathom aspen awesome thats working perfectly now, thanks both!
One way to do this could also be to allow the client to ask to interact with an object (populate the overlapping list on the client), but don't populate it on the server.
Instead on the server, just do some sanity checks to ensure that the player isn't cheating and can reasonably interact with that object (distance check, raycast to ensure that player isn't trying to interact with something on the other side of a wall, etc. Remember to add some leeway in the distance check because the player can be in a slightly different position on the client due to network latency)
You don't necessarily need to know if the player is overlapping the object on the server, you just need to make sure that the player isn't doing something dodgy with a hacked client (like trying to interact with something on the other side of the map or through a wall)
I'm following Vori's guide for a "non-destructive and better synced network clock", but I already have a player controller blueprint that I'm using. How can I use the timer with my existing Third Person Player Controller without having to make a new one? https://vorixo.github.io/devtricks/non-destructive-synced-net-clock/
Do I have to make a new PlayerController blueprint which inherits from the new CPP one and manually migrate all of the blueprint events, nodes and functions over?
Different questions each time though right?
Oh that sounds like it would save me lots of time, is there some sort of hidden away right click menu I need to click?
ahh i found it
Class settings, thanks!
omg I didnt even know reparenting was a thing
I thought it was more akin to IRL where you're just stuck with whatever parent LOL
So this gives me a float that counts up from 0, but how can I use this sever time to know when one second has passed and then decrease a widget timer? Currently I'm starting with an int like 500 or something then after a one second delay the pvp match timer is decremented by one. The replicated pvp match timer lives on the game state.
hey lawlster! whatsup ~
you could use it as you'd use any other increasing float
I'd need more details
Simple question :
Usually we tell people to not have input parameters on Server Events (RPCs) to avoid people cheating by sending the value they want for that input parameter, but why the node "Event AnyDamage" (That's the event receiving the damage from the "ApplyDamage" node) has an input parameter and is used on the server ?
Does that mean people could cheat ?
Please ping me if any answer π
yeah thats what im not sure about how id use an increasing float to decrease a shared timer all clients can see
Like a pvp match timer for example
I wonder if its not the right tool for the task....
You can call Apply Damage only while running on the server. The idea being, you'd detected whatever hit on the server, and calculate whatever damage on the server, then apply the damage (which would be on the server)
@graceful flame well you can do it by substracting the max-match time
Max(MaxMatchTime - RepliClock, 0)
Yes that makes sense
Am I able to do the same by creating a server event that could be called only by the server ?
Of course RPC can have input params. It's the developer's responsibility to make sure clients don't cheat. So after the RPC is sent, the server makes sure the client's provided values are intact.
ApplyDamage is BlueprintAuhtority function, i.e, can only be called from server, so it's not an RPC. Anyways, by same reasoning you don't call ApplyDamage on an actor unless you're sure that actor can be damaged (you're already on server by the time ApplyDamage is called so you can do your checks before that function is called)
@graceful flame just be careful cause u cannot trust the clock right when you join!!
so u gotta wait until it syncs up
okay
Any event that you mark as "Run On Server" means you're allowing the client to ask to execute that event.
Therefore, any event that you don't explicitly call while running on a "Run On Server" event means that it will only ever execute wherever it was called, whether that be the server, or client.
But how Epic succeed doing a node that could be called only by the server without the "Has Authority" node ? π€
In C++
but is it possible to do that through blueprint too ?
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Game|Damage")
static float ApplyDamage(AActor* DamagedActor, float BaseDamage, AController* EventInstigator, AActor* DamageCauser, TSubclassOf<class UDamageType> DamageTypeClass);
Specifically the "BlueprintAuthorityOnly" tag is probably what does it.
Oh nice
Not without using that tag. So pure BP custom events can't have it
I have another question, I have this code handling my health and shield system, and I need to modify it to handle 1 other thing. I have a boolean on my "Damage Zone" actor named "Shield Damage" which if set to true, the system takes the damage received and remove first the shield then the health (like in Fortnite, Apex,...etc) but now I want with my boolean "Shield Damage" if set to false, I need the system to not care about shield first and directly apply the damage to the health, what should I modify in my code ?
I tried to add a cast node to my "Damage Zone" to check if the Damage Causer is the Damage Zone and then retrieve that boolean variable but didn't work properly
Hey!
We are about to run the first alpha in our game CRETE. Was wondering if there is any plugin/API in the marketplace/Github to send data in-game into a database and bug reporter. Any tips about how you are monitoring gameplay, bugs and stats?
I'm aware of steam leader boards, thou wondering something more development oriented.
You'd probably be better off creating damage classes and start using them for applying damage. This way you don't have to care what specifically hit the player, rather the type of damage that is incoming dictates what happens. Then you'd just need to check the class of the damage type, or if you want to get more advanced, you create properties within your damage classes that you can then read and use in your damage calculations, like ignoring shields.
That looks far complex for me as I don't have that knowledge I think. The issue is It's mendatory in my case to have that boolean on my Damage Zone instead of the player as each instance of Damage Zone has its own version of that variable being either true or false
If it's a damage zone, why would there need to be a true or false option on it?
It should just try to deal damage.
Because maybe you want one zone to handle shield during damage and the second zone you don't want it to handle shield and directly hit the health
And therein lies why damage types would be better - you instead could define the damage type (by class) directly rather than using booleans.
Wouldn't an Enum be better ? Because I don't see how to dod that with a class as I never saw something like that yet π€
You've been using classes the entire time. Every blueprint you use is a class. You define variables in a class, and you can read variables from classes. You can make child classes and set different values for specific classes.
The idea here is to get away from needing to know what caused the damage and instead focus on what type of damage was dealt.
Yeah I know that a blueprint is class but I struggle to imagine how a damage type could be a class and what should I put in it (properties and methods). What makes more sense to me is an Enum containing different Damage Types
To create a DamageClass, you just need to create a blueprint based on DamageType class.
You put whatever properties in it that you want to help you define what "Damage" types there can be.
Then you create sub classes to help you fully define an actual damage type.
So if that right now is as simple as a "Ignore Shields" boolean, that's fine.
Leave it set as false by default. Create a child class and set it true.
When you go to apply damage, select the child class - you now are passing through the damage type that indicates it ignores shields.
On the "Any Damage" event, you can cast the Damage Type to your parent class - you can then read the variables from it.
If the cast fails, that indicates you haven't set up a damage class in the Apply Damage node, so you could log it for later revision, and just apply all damage as you would by default.
my brain just melt with these instructions π₯²
I think it's above my knowledge to do that, so I think I would keep going with the way I wrote it but just I need help on where to put the part to bypass shield damage when "Shield Damage" is set to false
It's not above your level of knowledge if you know how to:
A) Create a blueprint.
B) How to create a child blueprint class (which is basically the same thing as A)
C) Setting some variables.
D) Casting and reading variables.
Then it's just a matter of feeding in variables where you need them, just like you would anything else.
I did step A and B, what variables should i put inside now ?
somehow I already have some variables created by Epic
this node can only be called from the server ?
yea what wizardcell said - ApplyDamage is BlueprintAuhtority function, i.e, can only be called from server, so it's not an RPC
Thanks and do you have a solution for my other problem please ? π
@vagrant grail bro your problem is like 100 messages long
@past totem Here's the problem you only need this message to get everything you need to understand my problem π βοΈ
why is this even in here? go #blueprint or something. this has nothing to do with replication or multiplaeyr ?
your question is phrased so unclearely. what is this shield damage boolean? so u mean that u want to make it so a special type of weapon will skip the shield damage and damage health directly no matter if there is shield or not ?
the correct way to do this would be using the DamageType, you can either create a new damage type like DamageType_SkipShield and then check if it's that class (or cast or whatever) and in that case skip shield. or have a function in a parent damage type that does checks and calculations for what u want which can be overriden in any child damgetype
or, you can just not use AnyDamage at all, and use ur own damage system and create ur own damage function with SkipShield bool, but probably not a good idea
"shield damage" boolean is a boolean inside my damage zone, and if it's set to true, the damage zone will cause damage to the player buy bypass his shield if has some (as the player has some shield and some health and usually the shield gets consumed first then the health)
ye that's the solution then
vote for me issue : https://issues.unrealengine.com/issue/UE-149477

voted !
thx
Whatever variables you want that differentiates your damage types. You can use booleans if you so desire like "SkipsShield". You can think of this parent class as the "base" for what all other damage types derive from and any child classes are just setting the values.
As I pointed out, you don't have to use variables here right now if you don't want to - you can just create classes and then switch your logic around by casting the damage type on the Any Damage event, but it gets a bit hard to manage. If you do use variables, then you only need to cast the damage type on the Any Damage event to your base damage type and grab the variables from it, so again, if you made a "SkipsShield" boolean, you can get it from the cast node.
Do you have any tutorial showing up that, because if I don't see it I don't understand how to link stuff together. I always learn by seeing someone doing it first then apply it to my case then I understand how to do it π
Thank you it makes more sense to me like this π
Anyone know any free way to make a dedicated server for my steam game ? I have PTP set up already but my goal Is a dedicated server.
AWS, DigitalOcean, or similar free credits?
Or host it on a box in your house
Nice thanks
Question for people working on a shooter game, i've been struggling with an issue for over a year soon with replication race condition, in some rare cases, player will spawn without equipping his weapon cause owner had not replicated yet, so i ended up adding a call to my equip function in OnRep_Owner annnnnnnnnnd then another issue came where simulated clients can't see the weapon in other player hands in rare case also, ending up with 10 call to my functions in a few OnRep and yeah i still have some race condition actually π
So i saw UE4 was handling it like that, putting the weapon as pending while it has not replicate, my question is what is the best way to handle things like that, when switching to a not-yet replicated weapon ? Put a timer that runs until owner/instigator are valid and then switch to the weapon ? Do like UT4 and putting the weapon as pending and get 5 rpc to execute to switch to a weapon or yeah idk, feel free to suggest me anything π€·ββοΈ
I really don't like the way UT4 does it cause it runs a lot like A LOOOOOT of rpc to simply switch to a "valid/replicated" weapon
It's a common issue. I see simulated proxies without weapons in their hands a lot in fortnite too
I guess a bEquipped replicated property that attach/LinkAnimClassLayers in its OnRep would fix the issue permanently, actually itβs not replicated, my SwifchWeapon is like ShooterGame, every proxies execute the equip function
I fixed « attaching » by putting it to ClientGivenTo, so client is assured to always have a valid Character(instigator/owner) pointer
Now my issue remains with my LinkAnimClassLayers, so Iβll try to replicate my bEquipped and yeah Iβll see, it feels very dirty still, @jolly siren how u guys was handling that in Splitgate ?
I've got a weird issue I'm trying to get to the bottom of. My moving animation glitches heavily when the game is tested over the internet. This only happens on the client, the server runs smooth.
I'm not able to replicate it by upping the number of players in the editor, making ti extremely difficult to troubleshoot. I've tried posting to unreal forums and reddit but no luck.
I am pretty much at my wits end, could anyone point me in the right direction please?
Show it with the capsule visible
Also show your animation BP
and confirm you aren't doing anything goofy like trying to replicate walk speed changes all the time.
Do you have an acceleration tilt mechanic?
I do have an acceleration tilt machanic, but not the tilt values are not replicated
That's probably the culprit, show it
I'll take a video with the capsule tonight when I get home, as well as show the animation BP and the tilt mechanic. Unfortunately I'm at work now so it'll be a good couple of hours
My guess right now is the acceleration tilt is reading some value that's not smooth on client. But just post everything and we'll take a look
How can I tell what the difference is server vs client? Just print a debug message and compare?
The print will tell you what machine it's on
If you remember, how are you doing your acceleration tilt?
it SHOULD be derived from purely clientside info, either acceleration if provided by your movement solution, or computed from velocity and last frames velocity
I can't remember how I set my current velocity variable off the top of my head, but it's probably just pulled from the movement component
Assuming that all works fine on server, check that you're getting clean values for CurrentVelocity
I wouldn't be doing all that vector breaking though, just work with vectors and zero out Z if/when you need to
Vector x 1,1,0 zeroes out Z
Alright, good advice. I'll check the velocity values tonight, thank you
Why my replication Work in editor ( Local server ) But after build doesnt ? ( local )
Editor Correct Working
https://drive.google.com/uc?id=1wbOwOSYMMVn2Gh1wjKpEFYN6orQwj0Xj
Build Issue π¦
https://drive.google.com/uc?id=1bfgP2L4N1coHyA4pGoOxZkJH7OYQpamF
What is difference between local editor vs local builded ? Can someone explain me ? its frustrating...
How do I prevent SetActorLocation and SetActorRotation from replicating when being executed by server? I've disabled bReplicatesMovement for the actor and all its owners.
I'm trying to destroy an actor in a player controller BP in a server side function, is that illegal or something?
Meaning I run logic inside the player controller BP that destroys an actor I have a reference to
No error message but it just doesnt work
why are clients still receiving updates from a dormant actor?
I have a barrel with a health variable that changes every x seconds, but it's replication is set to dormant all. So why are the clients still up to date on it's constantly changing health? π€
I suspect that the channel hasn't fully closed once it's changed again
it starts off as initial and never changes
I suspected clients would never receive an update
but they receive it consistently
The client has to "ack" the most recent state before the connection goes dormant, but closing the actor channel usually takes a few seconds. Could be it changes too often for the channel to close
I'm not sure, it's quite variable - relevancy etc. is a good few seconds too
Also is this BP or C++?
I've no idea if setting a replicated property in BP means it automatically flushes dormancy
BP it's just an actor that spawns in with initial. It's so weird I didn't have this problem in a different project
maybe I should give it a few seconds and then tell it to go dormant, I'll play with it more
try not changing the health and see if it goes dormant
when I get the variable it says that it's dormant, not sure if it's reliable
But yeah IIRC, it won't truly go dormant until the client has acked the most recent state
@whole grove has been bleeding into #multiplayer more frequently lately...what are you up to π€
also is it normal for their to be a server print for every client? This is actually the first time I'm seeing this
It literally says that it's dormant all and then proceeds to update for all clients wtf
I create an actor and set itβs Net Dormancy property to βInitialβ. Then I add a replicated variable and setup a timer to modify that variable (only from server). Then I throw the actor in map and play in editor. The actor still replicates. I also tried setting dormancy to βDormant allβ from code and βDormant Partialβ (overriding GetNetDormancy...
Seems like a bug
Time to consider moving to cpp
C++ is honestly my 2023 resolution. The game is so close to beta man. Im getting rekt by a stupid blueprint bug at the last minute
7 tickrate servers it is! Thanks for letting me know the problem wasn't me though, I can rest now
It's weird how they marked it as "won't fix" though.
But then again, Unreal doesn't seem to really like BPs for multiplayer in general I suppose.
Ikr, I feel like epic is a bit disingenuous about being able to make full complete games with blueprint. Like I mean you can but soon as it gets slightly complicated youre screwed.
I believe they have said them selves that's not the intent of BPs. Any game should honestly use a mix of it, BP and C++ both have their ups and downs but when it comes to networking Unreal often just skips out on BPs which indeed makes anything that's slightly more complex than the basics impossible or not viable. Things like characters, optimizations, more advanced replication is all just not available in BPs.
Not hating on BPs btw, I think it's just fine to use but Epic is definitely not going to make it easy for you if you want a multiplayer game with just BPs π
Any idea how Fortnite is handling replication of firing of weapons? In one talk they about GAS they mentioned they have a custom way outside of GAS, but I don't think they mentioned details.
I am fairly certain they mentioned that damage is not predicted, but the rest is, and the prediction is what I am really curious about.
Don't try and predict damage.
No worries, that is one of the few details Epic mentioned. But the rest is a bit of a black box for me.
It's the designer friendly version!
as in
the actor is replicated
i guess its destruction should be broadcast to every client
aight
@long elkrq before i go do this
um
so this happens on standalone/listen server (server) too
so idk if this is the issue
I'm not sure exactly what you mean by clean value for velocity. Here are the screen prints of the client and server. They are different but not sure what to do to reconcile them? If that's what I need to do - I am very new to multiplayer. I have nevertheles addedd them as screenshots - this is my currentVelocity vector. I've also added the screenshot where it is set.
I disabled my leaning additive and the jerkiness stopped, so that is definitely the cause.
I setup a max player variable in my game session, but still more than 2 players can join
ALeapNGameSession::ALeapNGameSession()
{
MaxPlayers = 2;
}
Ahh - the ol', give 'em what they give me treatment
Draw debug line that velocity and make sure it's nice and smooth and pointing in the direction you're going
Then if that's smooth, do the same for your calculated acceleration and make sure that looks sane
can you please give some descriptive information.
This way the question is not very much answer able
OK great, I will try that. If it isn't smooth, what is the likely culprit? I can't check right now as the other devs that can help me test are offline so will most likely have to check it int he early morning hours
You'll have to trace it down. Maybe you're getting intermittant 0 velocities, who knows
maybe you're getting delta time spikes
OK understood. It could be a wide variety of things. Once I've figured out what the problem is I will try and isolate the cause
Is it possible to stream a render texture between two clients in a lobby (not session)?
Maybe but that sounds pretty awful.
What are you trying to do?
Imagine you're in a fighter jet cockpit that has MFD screens (the square digital display). You're buddy is playing by himself in his own server, but you both are in a lobby. You can look at your MFD to see what your buddy is up (a scene capture component attached to his vehicle in his separate server) on your MFD screen
except replace fighter jet with mechs
another idea is that despite being in separate levels, you might be able to set up artillery to provide support for your buddy, and having some kind of visual feed on your buddy's game world to see the effects of your artillery would be rewarding
That is a HUGE undertaking.
You'll be much better off syncing whatever base state is represnted in that screen
You wouldn't be sending the video over the network, but the stuff used to render that video. Still a big undertaking if you're in separate servers.
Assuming you figure out how to send data to a client on a different server at all, you'd send the stuff needed to render that screen (models, transforms, etc), not the raw video itself.
Well, I setup MaxPlayers, so no more than 2 players should be able to join the server, but still more players can join for some reason
I assume beacons are needed in such case
As far as I know, this should prevent more people from joining
Looks like UMediaPlayer has functionality for replication. I wonder if I can use a render target as the source for it
is you setting the session settings struct before creating a new session
there you can specify the max player to join the session or that specific session.
hello, i'm doing a multiplayer game and i'm having a problem where when a client crashes, its pawn still stays visible for the other clients for 30 s / 1 minute. is there a way to reduce the heartbeat frequency so the server game mode detects faster that the client is no longer there?
Why my replication Work in editor ( Local server ) But after build doesnt ? ( local )
Editor Correct Working
https://drive.google.com/uc?id=1wbOwOSYMMVn2Gh1wjKpEFYN6orQwj0Xj
Build Issue π¦
https://drive.google.com/uc?id=1bfgP2L4N1coHyA4pGoOxZkJH7OYQpamF
What is difference between local editor vs local builded ? Can someone explain me ? its frustrating...
Hi devs i got a small issue , I got multicast rpc on the character , which runs when this character got eliminated , and i want to print on the screen of ONLY eliminated player a message , but this message got printed on all clients and server as well , Why ?
void ABlasterCharacter::Eliminated_Implementation() { if(this->GetLocalRole() == ENetRole::ROLE_AutonomousProxy) { GEngine->AddOnScreenDebugMessage(-1, 14.f, FColor::Blue, "You are eliminated"); } bEliminated = true; PlayEliminationMontage(); }
I tend to use Kismet's Print for network debugging. Shows which machine actually ran the print.
alright thanks a lot !
How can I get all relevant actors for a given connection?
Iterate over actors server-side and check IsNetRelevantFor?
I guess you can iterate over actors client-side (without checking), though you will get static actors too
I would assume ReplicationGraph already does that
hi there. a question for anyone who knows. I've set up a tcp connection using FSockets. I've successfully connected, and can receive and send data over the connected socket. I'm getting some garbage unicode data at the end of my message. I've been using examples online for establishing the amount of data that should be recieved, but the unicode garbage still shows up. Here is my code on recv
TArray<uint8> ReceivedData;
uint32 Size;
while (Socket->HasPendingData(Size))
{
ReceivedData.Init(FMath::Min(Size, 65507u), Size);
int32 Read = 0;
Socket->Recv(ReceivedData.GetData(), ReceivedData.Num(), Read);
FString ReplyMessage = FString(UTF8_TO_TCHAR(ReceivedData.GetData()));
}
i'm assuming its how i'm calling init on my ReceivedData object, but haven't worked with this stuff enough to know the solution.
i figured out the above. i was getting garbage because the data returned from RecievedData was not null terminated. i fixed this by adding ReceivedData.Add(0); before my conversion to FString.
If I have a replicated client-authoritative value on character (such as bIsAimingDownSights ), would you replicate it with COND_SimulatedOnly or COND_SkipOwner?
I'm more used to see SkipOwner, but I guess it doesn't make a difference if you chose the former in case of Character
Is it worth using raw sockets or should I use RPCs like they are sockets? Where I call and RPC and parse a struct containing all the data I need?
What are you trying to do?
Want to do a rollback netcode implementation (done it in other langs before but using raw UDPSockets) so I am wandering whether to send structs across where I would do socket.send(bytes) I should just do CallRpc(bytes) ?
And use the CallRpc function as a top level base where everything is entered from
I would just use an RPC, it uses sockets under the hood but itβs more in an Unreal way. Itβs a bit unnecessary to create another connection while you already have one IMO.
π Cool, was just checking that I am not walking myself into any corners by doing it this way as I usually see RPCs used for 1 off updates rather than whole gamestate updates
I mean if youβre talking from client -> server RPCs are the only way. If weβre talking server -> client you can consider the replication system Unreal has π
But it just depends on what it exactly is, but thereβs not any need for a custom socket system for any server / client data as Unreal has systems for all that stuff π
Just got two clients, though in unreal I guess it is just server client with client also having authority
server has auth not clients
peer2peer setup, both have authority just need to keep the inputs in sync
if you're in Unreal one of those instances is the "server" though
I assume by authority you just mean the client is sending stuff to server and server is blindly accepting it
Yes, the original question was about sockets vs rpcs for implementing a custom networking architecture
Is there any way, we can connect multiple game sessions with each other ?
I want some Pawns to be replicated to all the sessions exactly at the same time ?
hi everyone. i have problem with simple move to location in networking. when i click anywhere player movement become laggy then the server correct the location after player stop which cause stutter at the end of player stop move
anyone know how to solve this?
Depending on how "connected" you want them to be, you can use normal non-ue sockets. For replication across servers I have no idea. Maybe you could use a proxy pawn and relay the input to the other servers
Anyone had issues calling RestartGame with steam listen server and having it not bring clients to the map?
@plucky prawnReplicate one Pawn movement with all the servers.
so all the sessions will see the pawn exactly in the same state.
@jolly siren I noticed you had the same issue 4 years ago with RestartGame and non seamless travel, did you end up fixing that or using seamless instead? As using seamless messes up the UI
Abnormal Flying Guns (Based on Lyra Starter Game)
any idea on what's happening here? Only occurs on the client side in a development package
Works perfectly on PIE, DebugGame, Standalone Windows for Debug and Dev, Shipping Build. Only occurs for the client when packaged as Development Build.
Logs:
[2022.10.11-07.16.01:299][120]LogNetPackageMap: Warning: Using None instead of replicated reference to B_WeaponSpawner_C /ShooterCore/Maps/BlasterMap_1/Generated/BlasterMap_1_MainGrid_L0_X-2_Y14_DL0.BlasterMap_1:PersistentLevel.B_WeaponSpawner_C_UAID_58112229E9901F3A01_2080049866 because the level it's in has not been made visible
[2022.10.11-07.16.31:828][786]LogNet: Warning: UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor. Actor: B_WeaponSpawner_C /ShooterCore/Maps/BlasterMap_1/Generated/BlasterMap_1_MainGrid_L0_X-2_Y14_DL0.BlasterMap_1:PersistentLevel.B_WeaponSpawner_C_UAID_58112229E9901F3A01_2066734865, Channel: 4
[2022.10.11-07.16.31:829][786]LogNet: Warning: UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor. Actor: B_WeaponSpawner_C /ShooterCore/Maps/BlasterMap_1/Generated/BlasterMap_1_MainGrid_L0_X-2_Y14_DL0.BlasterMap_1:PersistentLevel.B_WeaponSpawner_C_UAID_58112229E9901F3A01_2080049866, Channel: 5
[2022.10.11-07.16.31:829][786]LogNet: Warning: UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor. Actor: B_WeaponSpawner_C /ShooterCore/Maps/BlasterMap_1/Generated/BlasterMap_1_MainGrid_L0_X-4_Y14_DL0.BlasterMap_1:PersistentLevel.B_WeaponSpawner_C_UAID_58112229E9901F3A01_2097999868, Channel: 21
[2022.10.11-07.16.31:830][786]LogNet: Warning: UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor. Actor: B_WeaponSpawner_C /ShooterCore/Maps/BlasterMap_1/Generated/BlasterMap_1_MainGrid_L0_X-4_Y14_DL0.BlasterMap_1:PersistentLevel.B_WeaponSpawner_C_UAID_58112229E9901F3A01_2098003869, Channel: 49
VOIP isnβt working in shipped builds, in PIE/Standalone/Dev build it works just fine.
DefaultGame.ini
[/Script/Engine.GameSession]
bRequiresPushToTalk=true
DefaultEngine.ini
[Voice]
bEnabled=true
[OnlineSubsystem]
bHasVoiceEnabled=true
I add custom VOIPTalker, register it with PlayerState, and then I watch if VOIPTalker βEvent begin Talkingβ triggers or not, but it doesnβtβ¦
Also without VOIP, if I just use ToggleSpeaking 0/1 without anything else, it still doesnβt work only in shipped builds.
Why does "AtCapacity" return 0/false, even if there are 3 players and max players is set to 2? Do I miss something about this function?
ALeapNGameSession::ALeapNGameSession()
{
MaxPlayers = 2;
MaxPartySize = 2;
MaxSpectators = 2;
}
FString ALeapNGameSession::ApproveLogin(const FString& Options)
{
FString Message = Super::ApproveLogin(Options);
UKismetSystemLibrary::PrintString(GetWorld(), "Calling Approve Login now!");
UKismetSystemLibrary::PrintString(GetWorld(), FString::FromInt(AtCapacity(false)));
return Message;
}
Hello, i would like to setup a database for my games.
The game is started by clients, who can connect to small server for game, and can search into database for some information.
The client at some point should also be able to retrieve some data in the database (like level of the player).
Should i make a custom server who is in charge to handle communication between Client <-> Database and Game Server <-> Database ?
Is there solution who already exist working with UE ? or i need to do it from scratch ? if doing it from scratch, what is your advise for the protocol and quickly the architecture ? Is there a paper on the subject ?
Thanks !
Thanks, if you have any paper who can help on the subject, i take it !
Is it easy to integrate asp.net core to unreal engine ? Like there is already a native API for those thing ?
Normally you'd simply send HTTP requests from Unreal or use the websocket library
You'd then have a web server acting as front for the database
Because you don't want untrusted clients connecting to your db
Yeah, absolutely.
So something like a token generated for the session, i'm using steamwork for the authentification.
correct ?
Not very knowledgeable of authentication but something like that
I see, sound like exciting thing to learn.
We expect to have a "large" (At least for me) volume of player (300 000 on the release).
For the amount, do we need a complex setup or just one server for the DB will be enough ?
I know it's really dependant of the amount of data each client need to request/send, and it should not be to huge (data are requested only in the start of the game / end of each game).
I see, thanks for the answer @whole grove and @bitter oriole !
hey all, how would I accomplish for a multiplayer game to get the closest player to me? Sort of like a look at each other so I would have like the heads turning towards each other.
@dry pebble I switched to seamless travel a long time ago
Just loop over all your pawns/characters and check the distance and compare that π
Depends on number of players ofc, but the brute force option would be an overkill to the server. I would go for something similar but have the client do it (that way you only get relevant pawns) and check distance against them (You will still need to consult server so they don't cheat)
Or maybe have the client do a sphere trace (with a radius set beforehand) and get closest player in that sphere (again will need to consult server)
If performance is your concern you don't have to do this in tick or anything, put a 0.5 second timer or something on it and absolutely no one will notice the difference. I also don't think a distance check every now and then on at most a few tens of players will matter. If you've more than that amount of players to worry about I don't think the question would have been asked here honestly π
Or just 'time slice' it and query a few players per tick or per X tens of a second and then next time do it for different players.
The options are endless, though I like to deviate from the brute force option (CS vibes)
But yeah, the relevancy system kinda does something similar every tick
So why not utilize that π
A few distance checks really are not that expensive.
Or use the RG with 0.x timer π
Thanks for the response Thorn and WizardCell, I am considering aroind 10 or so players. So I would have to do like a get all actor of class and check for each element their distance from the current player.. (self)?
The thing is Wizard, this is not a crucial aspect of the game. If it turns out to eat more performance than you want to, just change it. If this was your world generator for the next Minecraft sure it would be a totally different story. But it's just not worth trying to make everything the best and most optimised you can, time is money too π
And like I said, worst case you just put it on a 0.5 second timer or check only a few players every time you tick it π
Taps "first rule of optimization" sign
Time is π΅ , I need to figure out how I work on tasks async
To answer your question btw. Basically yes. Just get whatever class you use, do some distance checks and store the lowest distance and then use that one π
Also btw. How on earth do people deal with moving AI in games? Imagine the following scenario: I have my most generic twin stick spaceship shooter where you have a cool laser beam to hit moving enemies flying towards you. How do you deal with the scenarios where the person shooting hits the laserbeam on their end on an enemy but on the server it already moved past that point? In this case I'm not worried about the actual hit being valid or not, lets say we go with client authority here. But how do you match up that laser beam going past the enemy visually?
vs like this happening for other clients for example.
I can think of ways to hide the fact that it may look off, but is that really the only solution to this?
But then again, I suppose that's the entire thing with multiplayer.. Trying to hide the fact that worlds don't line up with each other xD
I wonder how is this different from non-AI (PlayerControlled agents)?
It's not different. If I were to shoot at a different player it could have the same issue yeah.
Let me rephrase my question to "moving objects" then I guess π
I see. I mean rewinding solves hit registration
But visually it doesn't add up anything I guess
Unless we rewind them visually
Like I said I'm not worried about hit registration, it's a small fun side project to just keep going with multiplayer stuff. It won't be released nor pvp. So client will say "I hit this thing" to make it feel good.
I guess I'll just go the route of trying to act like it hit if the clients says so. Except with players as I think that may be too much considering that players predict them selves.
Then it needs to go from Client1 -> Server -> Client2 while Client2 may have already moved way too much by then to apply tricks π
Considering there's no pvp/friendly fire it doesn't matter if it looks off I suppose as it won't damage the ship.
I don't think it will be much noticed that the object is off (maybe it is in a space shooter type of game)
My concern with it is that with a bit of ping the laser goes beyond the enemy while still damaging the ship, that will look odd I feel like.
I think I'm just going to sneakily rotate the ship on the server when it's not the actual server to try and make it look like it actually hit the AI π
Although visually, not actually.
Fair enough, would love to see the results π
If I want to "toggle" relevancy for an actor instance through RepGraph, how would I do that?
would need to add + remove it to an "always relevant" node
May also need to remove it from the spatial grid nodes because IIRC the distance relevancy trumps everything else anyway
so if it doesn't exist in a node, it's not relevant?
there should be nothing else calculating relevancy?
If it's not in any nodes it shouldn't replicate to anybody
makes sense, thanks!
Ahh I see! How did you handle all the HUD/UI widgets messing up after that? I don't fully understand why certain HUD elements show and others don't with seamless travel
AFAIK all UMG widgets truly persist (with their data) a seamless travel
What do you mean by others/some don't?
Game HUD should really all be killed before travel
Unless you have some chat widget (or something else I can't think of) you want to persist
Yes Thanks Thom,
and do I have to do this logic from the player pawn BP, right? I am only asking because i did try to implement it earlier, but for example i wanted to get the shortest distance between 3 characters and the shortest distance always returned to self I think, I mean is there a way to ignore self and just check the distance from the other two characters.. sorry if I am dragging this out. I am following along based on this, https://www.youtube.com/watch?v=aKzjNTadrAc&t=4s but in the end I am not calling this from level blueprint, but from the PlayerPawnBP, which might be the source of my problem. Thanks!
Watch and learn how to add your own function in the game to find the nearest actor of any class to any given point.
Support me on Patreon and get access to videos early, join our developer community on Discord, get exclusive behind the scenes videos on my projects and much more over at https://www.patreon.com/ryanlaley.
Subscribe now to catch ...
It is as easy as checking != Self
And no you're on right track, you don't need the level BP
It will cause you more headaches than present solutions
Something like this WizardCell?
So you are saying that this approach is not ideal in this case? Or that running it from Level BP would be the inappropriate way. Thanks!
Yes like you did in the picture
I'm saying keep things in the Pawn BP (i.e. no further steps needed)
No need to move things to level BP
Even that should be honestly be recreated. If I cared enough to want chat to persist loads, I'd store it somewhere in a file or outside of world in a game instance subsystem and reinit the widget with that data. I really personally dislike going against the general golden rule that UI is for displaying state and accepting input. Causing it to carry that state past loads turns it into the state holder and not the displayer.
I somehow agree, I just tend for less effort and use what the engine presents. I was amazed to discover they persist out of the box, even if the persistent HUD gets destroyed before a new one gets created. I will still have to figure out how they persist though. I doubt that is a feature, but seems more like a glitch/hack hehe
It was talked about long ago on UDN and was published to the public without them figuring out how they persist: https://forums.unrealengine.com/t/cleaning-up-widgets-on-travel/320229/4 π
Hi, We think this post contains useful information which we would like to share with our public UE4 community. With your approval, we would like to make a copy of this post on the public AnswerHub which includes the discussion but strips out your username and company name. Please let us know if you are okay with this. Thanks!
I would guess they are deep linked into the GameViewportClient, though that doesn't explain how they are destroyed on hard travels
UWidgets aren't part of the actor system. They're not tied to world. They're just basic UObjects similar to GameInstance. The underlying slate they hold just gets redone when you add it back to another parent.
They're not exactly explicitly destroyed on hard travel so much that they are part of the viewport. You can store a Widget in GameInstance and put it back on screen after a hard travel for instance without recreating the UWidget. Seamless just doesn't remove the viewport.
The reason you don't have to clean them up from hard travel usually is because everything that holds a pointer to them is cleared. Without being part of the viewport hiearchy and no active actor holding a reference to them, they'll get collected.
I've seen this a few times. When you say they are not tied to a world I guess you mean their outer isn't world like actors?
I see, so hard travel does remove viewport.
Maybe. Actually let me look at that. Because it doesn't entirely clear everything. You wouldn't be able to do seamless movieplayer loading screens if it did.
Last I checked, there are a few function versions to creating widgets. IIRC, by default their outer is GameInstance, and you can explicitly make it HUD or PlayerController.
There are a few. I don't think anything ends up as the outer besides World, GameInstance or other widgets.
The controller context is for coop. That's actually irrelevant to the outer, that's for setting the playercontext for which coop player the widget relates to.
Makes sense. I will have to dedicate more time for this, though your insights have cleared things up for me, so thanks!
when working with steam online subsystem do you also want to be using the steam sockets plugin?
you don't have to
okay I have been having serious issues with establishing a connection so I thought maybe that was my problem
@fathom aspenDid a basic test. Found FWorldDelegates::LevelRemovedFromWorld. This gets broadcast from UEngine::LoadMap.
When UUserWidget has AddToViewport called on it, it internally calls AddToScreen. This binds that previous delegate from LoadMap. That calls OnLevelRemovedFromWorld, which will make the UUserwidget call RemoveFromParent on itself.
I would wager a guess that Seamless does not call this since it does not actually tear down the persistent world.
That also explains why MoviePlayer isn't affected despite being able to use UUserWidgets. You never actually call AddToViewport on it that way, you actually have it construct it's underlying slate and pass that to the moveplayer.
AddToScreen is virtual though. It would be easy to bind to the PreSeamlessTravel handle and ditch them from there.
Exactly. That was the function I traced last time OnLevelRemovedFromWorld and my guess was that it isn't called on seamless but iirc I was amazed that it is. Thanks for the breakdown though, now you made me really want to look into it again!
I'm not aware of the MoviePlayer part, what's that?
I guess its a UI related object
Movieplayer plays your game's default intro movies from these settings here. But it can also be used as an async loading screen display for hard level loading.
Read "Animated loading screens for hard world travel".
Great, that's something cool to read on
You can also call it at runtime to block the gamethread for cinematics. Less useful in multiplayer though.
So that's basically what games use to present their startup movies. Cool π
Anyone have suggestions on the best way to sync doors in a networked multiplayer system? Most videos and stuff that I've seen don't really feel optimized for a good experience. They just sort of play a timeline whenever the event comes through on the client and server.
Are doors open/closed or can they be in between?
either way, repnotify on state
Doors are one of the trickiest things to make. They might seem simple at first but can be an awful lot of work depending on how the door's complexity. For instance does the player click to open? Do they press a button? Should the character reach for a door knob? Can the character break the door down? Can the door be locked? Can the door be knocked on? Is there a door bell? Does the door just slide open based on proximity or with a key like in doom? https://www.youtube.com/watch?v=AYEWsLdLmcc
But if all you're trying to do is make sure an open door is open and a closed door is closed for all networked clients just use a boolean with repnotify like Adriel said.
I'm using sliding doors for my game.
What's UE4 source code version size?
iirc it was millions last I checked
I got outplayed 
what do i have to do to port forward on ue4?
NAT
i have weird issue, "simple move to location" works laggy when client moves on his instance π
It may not be so obvious on the video, but in the editor it is very noticeable
You want it predicted
i though it would be automatically done via movement component on character
It doesn't seem to be going through CMC
how can i do it with less pain
Easiest way to test is running the same code locally on the client too
So like Run on Owning Client
After the Server one
running on owing client after server run doesnt help
Then maybe try it fully locally so before the server
Forgot which was the way, lol
You just care for the pawn to have its own local sim and if it matches the server, it won't be corrected, giving you the smooth feeling
Unless the problem is somewhere else
i had to enable client Side Navigation in project settings, now it works
lol
but this makes a new security issue π
Neato
Nah, not really
It you run it on the server, it'll get corrected
I think that only allows the sim to run on the client too for predictions like this
okay, thanks
what port does ue4 use
Not sure when they changed it, I guess around 4.20 when the Fortnite stuff got merged in but I just noticed CMC doesn't do ServerMove() RPC anymore, they infact seemingly deprecated every single RPC relating to movement
so now i'm questioning, how does any of this movement code get called into on the server in the first place
I don't see where the client sends any of inputs to the server at all
Oh shit absolute madlads are manually sending the packed data in ServerSendMoveResponse π
ah nevermind, they moved it onto the character :p
But still crazy they manually pack the data that way
yeah all the CMC stuff is tied really tightly to the Character class, all RPCs are done through the Character class and then passed back to the CMC on the server
Why would they do it like that?
there's a comment somewhere that implies there's some overhead to RPCing through a component directly
Pedigree or is it actually a real design decision
Seems a bit weird to even have the CMC be a component then, except maybe for compatibility with other movement components
afaik its strictly an optimization
yeah i hate that about it, im sure there was a good reason they did that but i'd love the CMC to be a bit more "drag and drop" and usable with normal actors
Seems like that was not low for a game like Fortnite
That is replication overhead, not to mention the RPC overhead
yeah like the others said it's so you don't have to rep the component
which is costly
given that CMC was already super tied to ACharacter it's not a huge deal. Sucks for more reusable components though.
Sad day for the GMC (https://www.unrealengine.com/marketplace/en-US/product/general-movement-component). I would believe they have the component replicated with RPCs in there
In another context, Riot's dev blog posts are amazing: https://www.leagueoflegends.com/en-us/news/dev/dev-null-anti-cheat-kernel-driver/
From the article
: In a partnered study lasting approximately 8 years and backed by $20 million in federal funding, leading scientists managed to chronologically place the invention of cheating somewhere between 3.5 billion BCE and November 20th, 1985. While its precise origin remains indeterminate, one reality has become accepted as established fact: Cheaters gonna cheat.
oh yeah they are
