#multiplayer
1 messages · Page 712 of 1
Dunno if I should pass that in instead, because it just keeps adding parameters to the paths now
Yeah true
My solution is just to have add a set
Nodes can add actors to it like they would add their lists
I have MMO game (survival and in development) I have built server and I can connect in open 'ip' and it works. How could I build server browser and for example name for server? should server create session when opened or what?
Okay ty!
Params.OutGatheredReplicationLists.AddReplicationActorList(ReplicationActorList);
Params.OutSkipNetCullDistanceActors.Append(SkipDistanceCheckActors);
time to put this to the test
Works fine 
Is there anything slightly equivalent to EndPlay for ActorComponent that runs on client?
Try to bind an event to ondestroyed
Thanks 👍
OnDestroyed also seems to be server only if I didn't make a mistake 😢
override UnregisterComponent()
it'll be called when the component is being destroyed
iirc
Are you sure it's overridable?
Thanks for suggestions. UnregisterComponent is not virtual though
and called by DestroyComponent which is the same function that calls EndPlay so I think will only run on the server also
How do you transfer session from browser -> Unreal Session?
Wooops. mistook it for something in our codebase
my bad
oh yeah they do have EndPlay()
Haha yeah no worries. I was looking at it like an hour ago wondering why it's not virtual xD
they do have EndPlay but at least I didn't hit any breakpoint on client. Maybe I am missing a super somewhere
Ah no, it's OnUnregister and OnRegister
The component needs to be replicated and created at runtime btw if you want to destroy it in a network game
Thanks! Owning actor was not replicated 😳 Now I feel dumb!
Hey @latent heart hope it's OK to ping you here with my solution. I think maybe you would be curios?
The issue is that actors have a special "Net Relevancy" logic, that is evaluated during the start of a PIE session.
Ah ha.
The logic is... questionable, but it essentially says that actors with a collidable root component are relevant.
So my actor was AActor -> USceneComponent ->SphereStaticMesh
The "bug" went away when I removed the intermediary scene component.
Yaeh collision components should always be the root.
Unreal tends to go wrong when it isn't.
Well in this case the bug persists if SphereStaticMesh has collision turned off
So you really absolutely need an active collision on PIE start if you want the actor to have a replicated bIsHidden state
Well it just wouldn't work any other way. The root component determines the transform of the actor, so wherever it goes, the rest follows - collision be damned.
Note that NetRelevancy logic is evaluated continuously btw, every time the actor is viable for replication
But it's perfectly valid to have a collision component attached to a root component - in theory
Yes
Yeah for sure
UE just doens't like it 😛
I feel like it's still a bug though
But if you move the root somewhere, it'll sweep only that component
That being one of the issues!
So, just so I learn something from this: If net relevancy is evaluated continuously, what are the conditions that cause it to evaluate incorrectly, but only in the first few seconds of PIE?
If a collidable root component is a requirement, why does a non-nominal delay allow the property on-rep to succede?
None really, the server calls "IsNetRelevantFor" for each connection
If it returns false for whatever reason, it won't replicate to that connection
For the record a collideable root component is not required for the default network relevancy
But you do need a scene component at least so that the actor has a valid transform
Otherwise it has no way of knowing how to distance cull
He had one.
Except that it is.
In some conditions.
My guess is that bAlwaysRelevant gets enabled at some point, by UE4.
So at start of PIE we miss that early-out, and it only comes online later.
It doesn't have to collide - the actor just needs a valid root component. If it doesn't have one, then replication will not function unless the actor is marked as always relevant.
For example, PlayerStates, Controllers and GameState
No, this is incorrect.
They have no root component but are marked as always relevant
I could cause the replication bug to occur by simply switching the root StaticMesh to NoCollision
i.e., line 318 in the net relevancy evaluation
This was consistent across PIE, out-of-editor testing, packaged build, and testing PIE single-process/dual process.
That only takes effect if the actor is both hidden AND has no collision, so that makes sense
My actor began life visible, and was marked as hidden on the server, after a small delay.
In this scenario, the actor remained visible on the client, unless I made the root collidable, or bumped the delay up.
Ah right, in which case then the actor would shortly after be destroyed client-side
Was it spawned at runtime or placed in the level?
Placed in the level.
That's why then
It's not torn off or anything.
So what's happening is the actor is no longer relevant because it's hidden and has no collision, so the client will receive no updates for it
And shortly afterwards, the channel for that actor will be closed
If it was spawned at runtime, that will destroy it
You said you set it to hidden on the Server shortly after?
Yes
Exactly
So IsNetRelevantFor will return false - therefore no more property updates will be sent
Ah, so the race condition is that the server sets it hidden, and then before it has a chance to replicate, it evaluates itself as being non-relevant.
Fascinating.
Do you have any insight into why the IsNetRelevantFor actually does start working again, after a number of seconds?
I guess just some other condition is making it true
Yeah, once it's no longer relevant, no more property updates are sent. After a short while, the channel will then be closed. It doesn't close immediately because if an actor is frequently becoming relevant and then not, it can spam channels being opened/closed
And opening a channel will resend all properties of the actor, it's treated like a new actor
Similar to waking from dormancy, the only difference being dormancy doesn't destroy the channel nor the actor
If it was strictly necessary to code this feature server-only (it's not), the solution would be to force the actor to be relevant by setting bAlwaysRelevant, I guess?
Either in-code, or in the asset.
Or override + change IsNetRelevantFor so that it doesn't factor the actor being hidden/collision
Ah good point.
It is odd they chose to make that the default behaviour tbh
Yep
Like I said, I maintain that it's essentially a bug
Or at least ill-defined behavior.
You should in theory be able to change a replicated property whenever you please.
The fact it has hard-coded logic means that this "gotcha" exists.
It's certainly a silly logic issue, I wonder if this has been added at a later date or is a relic from UT/Gears days
Isn't there like an AlwaysRelevant flag somewhere>
Yeah but you lose distance-based culling then, which you may want
No clue. I spent most of my time doubting my own code/surrounding system.
I knew the solution was to just hide/show on both client and server, but I was very curios about the problem, since I feared it would uncover some greater issue in the code.
In the end we did chase it down into the default AActor::IsNetRelevantFor, and could implement simple fix 😁
Yeah, in this case I'd probably override that for this specific actor
It's a generic system 
But it is a questionable default implementation for sure
It makes me wonder, do companies ever write their own base class system?
i.e., AActor -> ASirLichActor -> AActualUsableThing
For the purpose of having a controllable layer, in case project-wide implementations need to change?
Because this issue could be fixed in ASirLichActor, assuming everything was inheriting from that.
It looks like this impl has been there since 4.0 so I guess it must be a relic
Just set bAlwaysRelevant!
That's not a solution if you want distance culling though
It is a solution if you want to have invisible objects with no collision replicate
In answer to the Q though, probably not - I'd just modify the engine like a turbo nerd
Just set always relevant when it's made invisible
Once again, I will reiterate that for my needs, it's perfectly acceptable to set visibility across both client and server.
I think the old optimization was already a bit too clever 🙂
Simpler, more robust code, alongside a bug fix.
But it is very useful to have theoretical solutions. I think I would tend towards toggling bAlwaysRelevant to true before setting visibility, and then I guess setting it again to false.
Although I'm not sure how you would detect that the replication packet had been forwarded 
You can't unfortunately, or at least the engine doesn't expose a method to know whether the client has acked the most recent property state
That information is known though, so would be a nice thing to have available
I think default port that UE uses is 7777
so it seems like its not like the 1990s where you could just host a server from your PC?
seems like they are blocking ports, has anyone got dedicated servers to work with a home pc?
UE ain't blocking ports. Just set up your home network to allow it.
I did and it says closed still
what a nightmare, looks like I wont be able to set up my own dedicated network
Hello, I have an actor that should only be relevant for each player, so it is not replicated, it is invoked with a button, when the player invokes it I have a print to see what I invoke. I don't know why when the server invokes it it looks like this. Any idea why this happens?
Is there a multiplayer lobbying guide?
Has nothing to do with Unreal. This is purely your network.
what other options do us poor people have to run dedicated servers? Gone are the days when you could just open up ports and run a server
it's like the server started it but at the same time it doesn't
If I run it only from one player with play a listen server , it works correctly, the problem is when running it with more than 1
If my actor has a value that increments every tick that I want to replicate, should I actually call an RPC on every increment (even though they happen more frequently than server can handle), or is there a sort of "server tick"-function or some sort of "prepare packet"-function that I can utilize to send the aggregated result of the ticking? Or would I need to implement it myself and have a timer that calls the RPC every ServerHz/1 second, where I'd get the Server hertz when joining?
Just as a heads up, I did end up passing in the location of the view target instead of SrcLocation and that seems to have fixed the issue for now!
Nice, good job!
ok so running a dedicated server on my pc wont work because of a port forrwarding nightmare, what other options do I have? If I was to rent a server, what subsystem can I use to have android and PC connect?
We test with dedicated server running on a trash laptop
I'd recommend just renting a cloud server to figure it out
Ok im defo facing rubberbanding
Idk how to fix it
its only before the character reaches max speed
Once it reaches max speed it stops
@dark edge how do you do this? i wish I could but my ISP is blocking ports
Does anyone know if the default WebSocket server implementation supports WSS?
Looking at this it doesn't seem like it does Engine/Plugins/Experimental/WebSocketNetworking/Source/WebSocketNetworking/Private/WebSocketServer.cpp
Seems like a bit of an oversight from Epic
Rent a $10 DigitalOcean server then
Hi guys,
Anyone knows why in the "Lyra sample project" their character movement component replicates acceleration with a rpc to simulated actors?
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(ThisClass, ReplicatedAcceleration, COND_SimulatedOnly);
DOREPLIFETIME(ThisClass, MyTeamID)
}
void ULyraCharacterMovementComponent::SimulateMovement(float DeltaTime)
{
if (bHasReplicatedAcceleration)
{
// Preserve our replicated acceleration
const FVector OriginalAcceleration = Acceleration;
Super::SimulateMovement(DeltaTime);
Acceleration = OriginalAcceleration;
}
else
{
Super::SimulateMovement(DeltaTime);
}
}```
the rest of the relevant code is in this gist: https://gist.github.com/RJrodrigo/ba5e2e33da3c4614451dc4eb6123ad14
FYI as I learned not that long ago, you're technically breaking the Unreal TOS by sharing 'large' amounts of code
this is the lyra source code
it does specifically say 'Engine Code' in their TOS so might be good then
@dark edge thanks for the digital ocean recommendation, right now im using the advanced sessions for servers, will that method work for pc and android players to connect to same sevrer?
@dark edge how come there is no windows options there? My server is packed as an exe, how can I use it there?
Hello guys! Can anyone give me a hand with a problem I'm having when replicating a rotation? I can show in a voice channel! Thanks! 🙂
Yeah idk if they do windows boxes. WHy are you doing windows dedicated server?
Hi, can someone tell me where can i find a person who could help me convert some Single player BP logic to Multiplayer?
Is there any known bugs in UE5 using the New Editor Window (PIE) and Number Of Players : 4 ?
when i run this Server and Client 1 works as they should but Client 2 and Client 3 is not!
what i mean by "Not working" is that i have a floor of lava rising up each tick! this is updated and you can see it on Server and Client 1 but not on Client 2 and Client 3 :S
PS: Using Blueprints
Show your lava floor blueprint
is there any reliable way to test MP in editor? because for me it works fine in editor but in build it doesn't.
@dark edge should i do it like this?
No
Just have the GS GOOFv or whatever tell your lava actor to start moving. Replicate movement might be enough, depends on how you're doing the movement
Countdown -> Get actor of class LavaActor -> Start moving
Or bind to a dispatcher if you have a lot of things that need to know that the countdown is done
so only replicate the code in construction script?
You should just be able to use replicate movement (not sure, never used the interp to movement component) and do stuff on the server
this one?
on the interp
so i ticket that off and ran the custom event on "lava floor" in the GS_GOOGF
but there is some weird timing issues, Servers lava floor is "slower"?
Client1, 2 and 3 are all synced but the server lava floor is behind
Can anyone help
Again I'm tryin to prevent / reduce rubberbanding
It happens while the character is accelerating, before hitting the max speed
once it hits the max speed it stops
same goes for decelerating
This seems to be enough in my testing
How are you doing your acceleration?
with the CMC
More specifically
gimme a mo
void AMyCharacter::move_forward(float Value)
{
if (Value != 0.0f)
{
// add movement in that direction
AddMovementInput(GetActorForwardVector(), Value, true);
}
}
and i binded the MoveForward axis to this method
weird! not working on my part! Server and all clients have their lava floor rising! but the server is far behind the clients for some reason :S
Try activating the component instead of toggling tick on it
also don't check on tick for if it should activate, just tell it to activate
Also make sure the actor replicates
is there a known issue with ue5 where changing replication settings on a blueprint variable causes nothing to replicate in PIE? i have to keep restarting the editor whenever i set a variable to replicate/not replicate
Hey yall, I'm looking at a directional combat system (like Mount and Blade, For Honor, Last Oasis) that takes the clients mouse input (or camera direction, whatever it might be) to determine if a player is initiating a left swing, right swing, or overhead swing. I got it working on the client side with mouse input, but do not understand the proper concepts to send that information to the server so that it knows how to show all the other relevant clients which swing I chose. Anyone got an resources for how to best tackle this?
Sum the pitch and yaw over the last x seconds as a vector, determine the direction from that
A thrust would look like 0,0
left to right swipe like 10.3,1.4
overhead chop like 1.1, -12.4
er I got pitch and yaw backwards but you get it
IDK how you'd do the summation but I'd just start adding the input vectors to SmoothedInputVector and then VInterping it towards 0,0
at some lowish rate, tune to taste
So each frame
SmoothedInputVector += InputVector
VInterpTo(SmoothedInputVector, (0,0), 1.0)
AttackDirection = SomeFunction(SmoothedInputVector)
Input Event Attack -> SomeOtherFunction(AttackDirection)
Appreciate the input! I guess my question was more around the multiplayer aspect of replicating out to relevant clients versus the methodology of determining the direction. Right now it seems like the input value is getting valid from client 1's perspective, but the server and client 2 are seeing 0's for pitch/yaw. Let me throw out a screenshot
(dont mind the special attack bool)
Just let clients pass over the direction.
Yeah those axis inputs are gonna be 0 everywhere that's not local
input is local only
ahhhh so thats probably my issue
Choose the attack locally, and replicate that out
💡 thank you for the feedback @dark edge !!
Or continuously replicate input and use that, but you'll probably end up with Client A seeing an overhead chop while Client B sees a thrust. You're better off letting Client A choose the attack he's doing
Yeah no, I'm trying to make it as performant as possible because there might be a use case where over 100 clients are considered relevant, all fighting on the ground with the ability to attack and block in 3 different directions
Yeah so make your Client -> Server rpc look like
Attack(Direction3)
Makes sense! Just needed someone to point out the obvious on the input being local
Thanks again!
please?
I check if the current players is equal to or exceeds the max playercount so players cannot join full servers.
The issue is, if they load the server browser when the server isnt full, then the server becomes full, and then they join it will let them in.
Is there anyway to give a blueprint session and "refresh" it to check if I can join (for example check if it still exists, if the playercount is max, if the game already started)
I am using advanced sessions plugin
I could just do the check on the host when they join and if they aren't allowed in it kicks them, but I would rather a solution that stops them from joining at all
im not necessarily a multiplayer genius nor do i know exactly how to do this but basically you likely want to reserve space somehow. Example:
Server 1 has 11/12 players
Player 1 is looking for a server
Player 1 finds Server 1
Player 1 tells Server 1 "i will join this match i promise"
Server 1 now technically has 12/12 players
Player 2 looks for a Server and shouldn't find Server 1 since its technically full
If Player 1's connection aborts while trying to join the server remove the reservation
My issue isn't 2 players joining at the same time or similar times, it's when 2 players refresh the server browser at similar times when the server is 11/12. One player joins the server making it 12/12 but it's still 11/12 on the other player's screen.
If this player decides to join the server (without refreshing) it will let him in.
What I would prefer is if the player tries to join the server it would refresh that specific session to make sure it's still valid before joining - as opposed to kicking them after they start connecting
I am not too sure if it is possible because all the other games I have played allow you to join and they kick you during loading (after starting a connection), but it seems weird that there isn't a solution to this
does anyone know if skeletal animations are played on the server at all? i understand it probably doesnt make sense but id like some clarity
Afaik they do replicate on listen servers but dont on dedicated
Oh sorry then, i cannot help
was that aimed at me?
yes
ok so my issue now is that on dedicated servers, when my door animates open, because it doesnt animate on the server, my line trace on the server still hits the door even though its closed :(
Are you overriding max speed anywhere? Just making sure you're not forcing acceleration by modifying max walk speed over time
Show how your door is opened
The logic from key input to door moving
im using an interface for the most part, would it be ok for me to just include that instead of the input stuff?
Just show the chain from client to server
hopefully this contains enough information. this is almost the entire door blueprint
Is there any good multiplayer guides on ue4 anyone could suggest? Whether video or website?
well i am but not over time
i change the max speed in SetupInputComponent
Check pinned messages especially third and fourth from top
You want the door to be open on server too
yes correct
Also that design looks like it'd fail if someone missed the opening state and only saw it in the open state
ye the DoorTargetState is the one thats replicated and i just reused the same enum for DoorState
the target state only uses open and closed
Just onrep bIsOpen and play the animation on a state change
Do you intend for the server side door to animate or what?
i dont know how this would normally be done so i have no preference, as long as it works properly. the reason for the door state having so many states is because i eventually wanted to make doors get stuck partially open or whatever, its not a big deal right now
You can just replicate a float DoorOpenAlpha
ah fair enough
thats basically what the DoorPosition float would be from the timeline
except that its not replicated
so do you think replicating this would be a better solution than my door state enum thingo? im also concerned about having the server tell the client when a door opens/closes since.. wouldnt it feel laggy? there wouldnt be any prediction
You really don't wanna deal with prediction and doors, just make it sync up well. Nobody cares if a door opens 30ms after they hit the button
Having an issue attempting to call the following function on a client
FGameplayAbilitySpec const * const Spec = OwnerASC->FindAbilitySpecFromHandle(SpecHandle);
It seems to always return a nullptr even when I verify the spec is there. It works fine on the server, not clients. Both the container holding
the SpecHandles and the component that contains them are set to be replicated. I saw where another user was having issues and calling InitActorInfo seemed to fix it but I am calling the init function on both the server and client side and I am verifying that it is actually being executed for each client.
Maybe this call is wrong, or it might need to be on bottom-most child class. Currently I am doing the set up work in a base character class.
//This gets called in both the PossessedBy, and Set up player input component functions
AbilitySystemComponent->InitAbilityActorInfo(WAKPlayerState,this);
I should also mention that I have even tried marking the ability spec as dirty and still seem to have this issue.
i really need to get out of the microoptimization mindset.. its bogging me down
Prediction is hard enough with stuff that a client is 100% in control of. What happens if 2 clients try to open/shut the door at the same time? total clusterfuck. Only do prediction where it's needed, it's a can of worms otherwise.
I would maybe try predicting a door in a RS: Seige type game but otherwise nah
oh. i thought prediction was like a staple with anything networked
prediction should be done only with things that need immediate feedback and ideally have minimal impact if mispredicted
which includes most basic player controls but generally not much else
is there a way to check if only the server is calling a function? afaik IsServer will return true on a listen server host even if the client is running it
The listen server is client too. there's IsDedicatedServer tho
ye but i only want this called on the server. i feel like IsServer and HasAuthority would work for most stuff
but i bet theres a pretty thicc edge case in there
The listen server host/client is both.
Are you saying you want it called on dedicated server only?
no, i want it to work on both, but dont want it to run on the client at all. i understand that the listen server host is both but surely that still means theres a separation between client and server right?
Hence why I tossed prediction right out the window on my modular vehicle game. Rocket League had a bad enough time with arcadey vehicles. Mine has realistic drivetrain and grip and the vehicles are fully modular.
Same process. It's a server that has a player on it.
What are you trying to do?
making sure that my door trigger only opens the door on the server
OK then just gate by authority
oh
listen server IS authority just like if they were playing standalone
right
Really the only difference between listen server and standalone is whether or not you're open for connections
In our project you actaully are always a listen server (so multiplayer can be seamless for the host)
im still not entirely sure how to fix my line trace issue since the door doesnt actually open (with animation) on the server, so even though the door is open on the client, the server still thinks its closed and the line trace on the server and client dont match
Do you want it to open with animation on server or not?
ye i guess unless theres a better option
its a 2 piece door
if that makes any difference
Is it a skeletal mesh or 2 static meshes?
Anyway, just onrep SomeStateVariable and have that drive it
in BP the onrep will fire on server too
in C++ you'll have to add that functionality
skeletal
OnRep bDoorIsOpen
Play timeline
play animation
rotate bone
whatever
i was driving it with a timeline in the bp i shared earlier but it didnt seem to work on the server
@dark edge my directional combat is now working flawlessly, thanks to you again good person! I was getting so frustrated because it seemed like it should work. Instead of getting values directly from input, i checked input and set an enum, replicated that and voila it all works as intended
one of those "i know its something obvious, but i've been looking at this so long i don't see it"
Hello, I´ve attached my characters to other actor so they can move together, but on the clients the animations of the characters doesn't update, it stays on idle. anyone know what could I do to fix?
How are you driving the character animations?
If it's by velocity, I'm pretty sure velocity is always relative to parent.
yeah, it's by velocity that's why isn't working, i've tested now with a created variable and it work
Is there an example of DemoNetDriver with In Memory Streamer that explains how can a kill cam can be implemented, without disconnecting the player from the gameserver to show the replay? Maybe I'm not able to understand but it feels like the official docs are not enough to just look and understand how to use it
I'm not sure if this is what you're looking for, as I haven't looked into it yet myself, but it's worth looking into 2nd pinned channel message from top if you haven't done so already
are options passed to openlevel encrypted? if not, is there any secure way to pass it?
can i pass a JWT here? (Json Web Token)
Oh I wasn't aware of it. It looks promising. Thanks for pointing out
I need custom rotation to avoid gimbal lock. I'm struggling with replicating this rotation from one client to the server + other clients, as I don't fully understand replication yet.
As far as I understand, simply having a variable marked as UPROPERTY(Replicated) and changing it on the client won't replicate it to the server.
Does this mean I have to implement RPC function such as UFUNCTION(Server) void RotationChanged to call from the client, which should then call a UFUNCTION(Multicast) out to all clients?
Obviously I need to apply the rotation-change instantly on the client per tick, but I certainly can't call an RPC to the server on every tick, so is there some sort of auto-throttle involved I can utilize, or do I have to use a custom Timer or accumulate with DeltaTime to let the client decide how often it wants to send this information? And when the server multicasts back, how do I prevent the original client from updating its own rotation to its previous rotation (if still rotating)? And should I pass the actual rotation-value, or the accumulated "change" in rotation? If only the change, how do I ensure that they are correct over time?
Nothing ever replicates to the server from the client.
The only thing that operates that way are RPC calls.
Why can't you rpc every tick?
You have to throttle it yourself
Because it sounds severely inefficient and useless to call a server rpc 240 times per second when the server only runs at e.g. 60hz. And if I send the actual target-rotation value, I don't need it to receive all the accumulated values between each server tick either, I only need the "last" value.
Sounds like you want a client-authoritative solution, so you would send the transform or whatever it is to the server at a given rate, optionally throttling it. Server would replicate those values to other players as replicated properties. Remote clients would have to "smooth" their local copy between updates.
Damn, I would've thought replicating values to server had a nice default implementation not needing rpc.
Yes, I do want client-authoritative for nearly everything actually.
Character Movement packs moves together quite aggressively to avoid calling RPC's every tick (and those RPC's are unreliable)
Bear in mind if you send the actual rotation, it will be rounded.
Probably.
Not sure if RPC rotations get quantized like property ones.
Does default character movement have a default "tick rate" for replication?
They don't nah, replicated movement rounds it's internal rotation but nothing else does
No, it's an unfixed rate by design
Oh fair enough!
UE's character networking operates under the idea that every client is probably simulating at a different rate.
Moves that are continuous (i.e, just moving forward) are sent less often than "important" move changes etc.
It's quite complex
Oh yikes.. Guess I'll start with just a low fixed rate of rotation RPC and take it from there then.. And that I should send the actual target rotation unreliably rather than the added offset from previous, to avoid errors that I'd have to sync. And "animate" the rotation from Old->New over that fixed tick-rate length of time. Or perhaps store the last timestamp, and animate over now-lastTime seconds, since they're unreliable..
The idea is that you apply the changes to the "collision" part of the mover instantly
You only smooth the visuals
Character Movement for example "snaps" the capsule instantly, but offsets the meshes relative location/rotation and smooths it over time. The smoothing + animations hide the snapping/blending
You won't get a steady stream of updates either way, so you can't blend at fixed rates
In the real world, packets will get lost, jitter occurs etc.
Holy shit. I'm currently using AddMovementInput for regular movement, and just need a custom replication for rotation (which won't trigger collision stuff in this particular case), so hopefully I'm able to avoid all that, and can live with a bit of rotation jitter. (Regardless of replicated rotation, the position is still correct).
I might need client authoritative positioning in the end, but I hope and assume there's a way to still use AddMovementInput for position replication without the server trying to correct it, rather than having to implement all of that stuff.
AddMovementInput doesn't really do anything, it just locally adds the values to an accumulating vector
Or at least, there's nothing MP-specific about it
Character Movement just takes that vector and puts it through all of it's complex networking
I'm trying to swap out some bool vars on my character to use the tag system instead. Is there a way to trigger rep notify events on tags, in blueprints?
These are tags on the GAS ability component system so they should be replicated
Rep Notifys will work the same way for gameplay tags
Same way you would any other property
Add a gameplay tag variable, mark it as replicated using or whatever the BP function is
@chrome bay These are being stored in my ability component system's list of tags though. I'd rather not duplicitiously track the tags on the ASC and the pawn
Well you can't add a rep notify to the pawn then
The ability system has dedicated callbacks in C++ for when tags are added to it
That's not exposed to Blueprint
The GAS shooter example seems to set up this async task like this
UAsyncTaskGameplayTagAddedRemoved* UAsyncTaskGameplayTagAddedRemoved::ListenForGameplayTagAddedOrRemoved(UAbilitySystemComponent * AbilitySystemComponent, FGameplayTagContainer InTags)
{
UAsyncTaskGameplayTagAddedRemoved* ListenForGameplayTagAddedRemoved = NewObject<UAsyncTaskGameplayTagAddedRemoved>();
ListenForGameplayTagAddedRemoved->ASC = AbilitySystemComponent;
ListenForGameplayTagAddedRemoved->Tags = InTags;
if (!IsValid(AbilitySystemComponent) || InTags.Num() < 1)
{
ListenForGameplayTagAddedRemoved->EndTask();
return nullptr;
}
TArray<FGameplayTag> TagArray;
InTags.GetGameplayTagArray(TagArray);
for (FGameplayTag Tag : TagArray)
{
AbilitySystemComponent->RegisterGameplayTagEvent(Tag, EGameplayTagEventType::NewOrRemoved).AddUObject(ListenForGameplayTagAddedRemoved, &UAsyncTaskGameplayTagAddedRemoved::TagChanged);
}
return ListenForGameplayTagAddedRemoved;
}
That's an async task for use in Gameplay Abilities
But either way, this functionality to listen for tag changes is not exposed to Blueprint
You can see the function it's calling
RegisterGameplayTagEvent
Or alternatively RegisterGenericGameplayTagEvent()
Yes, but is there any strong reason not to leverage this to listen for tag change events and set up "notifies" manually in a bp?
I don't see why not if that's what you need
But you mentioned "RepNotify" which is a very different thing
Is it a different thing? A rep notify event is triggered when a new value is received and is not the same as the original. No?
Including, when a server sets a new value on itself without any replication per se
No it's not the same
A rep notify is an engine-level concept where when a property updated is received on the client, a function will fire
You're setting up a dedicated system to listen for changes to tags, it's completely different
Also Rep Notifies (In C++) only fire client side. Blueprint rep notifies are a joke and fire whenever the property is changed, they actually have little to nothing to do with replication in BP.
That explains... some other issues I've been having
So would you say this manually constructed system is approximately the same as the joke-y bp rep notify functions? :p
I don't know, I've not used GAS Shooter
fair enough
No idea how that async task works, but async tasks are usually meant to be used inside abilities and share their lifetimes
Whether that one can work/live outside of it IDK
I think asynctask != abilitytask
yeah they're not identical. Maybe that node isn't an ability task
ok thanks. this was all very helpful
this async task includes some notes about how it needs to be manually ended to be garbage collected, which is sure to cause me a headache at somepoint but I think it's at least not expecting to live with an ability per se
Yeah, that's what I meant. I'd like to keep using the complex networking for positioning, but as client authoritative. If that's not possible I guess I'd have to replicate my own movement and will lose the complex networking. But I haven't looked into any movement yet, only working on rotation atm, where the default addPitch/Yaw/Roll suffers from gimbal lock.
hello all, in games like pubg mobile, there are lot of skins, shirts, cloth packs, helmet skins etc available to unlock after completing missions and owning them. Does the game downloads and retrieves whatever unlocked from cloud/servers after they are unlocked or do they download all of them and store in player mobile so that when ever a player unlocks certain item, it will be ready to apply to meshes? Thanks for answers
The assets always exist in the local game. "Unlockable" usually just means giving you permission to use it.
okay, thank you
hey guys, what entities exist on the server side beside game mode?
and what variables should I put on the game mode? will it be like Player stats and their inventories?
Picture 1
Player Controller (PC_GOOGF)
Custom event (ShowCountdown )
Executes on Owning Client
Picture 2
Game Mode (GM_GOOGF)
Event tick
Loop through all connected players
Display widget (Show Count Down)
This is all fine and good right?
Now, the server should do the countdown right? where should i put that code? in Game Mode or Game State or?
If you had to store an array of actors that the player was tracking, would you put that into the player state or instead place it inside of the controller / pawn?
@vestal cobaltIf you have game state data (such as a countdown), then that would belong in the game state
game mode does not get created on the clients
the game state however does get created / replicated between the server / clients
I haven't looked at your BP graph screenshot, but one thing to watch out for is the dedicated server typically doesn't have UMG enabled
It would be better to separate the UI from the server if at all possible
(I say this knowing there is a checkbox to let dedicated servers run UMG, but why?)
what do you typicaly have in the Game Mode tho?
Rules for the game
Things only the authority should ever have to know
Actually that is not the best description. Instead use this documentation as it gives more clear guidance. https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/Framework/GameMode/
yea nice! 🙂 ty for that
Anytime
yea so basic boildown
- Create Widget (CountdownWB)
- When everyone has loaded in to the map display said Widget
- Do the actuall countdown (in Game State now)
- Check if countdown is done (= 0?) then unfreeze players (at game start every player is freezed, they cant move)
the problem is that the way i display the widget to all players is this using the "Players" array that holds every Player Controller that are in the game
should i do it another way or?
the "Player" array is in the Game Mode
so i would need to cast to Game State in Game Mode and then copy that player array over to Game State :S dunno if that is bad or not
Just a heads up, GameState I believe even its Base form has a Players array, which holds all player states in the game
you could get the controllers from the player states
oh
oh yea look at that
it does!
hmm in Game State i cannot access "Show Countdown" function in the Player Controller
what am i missing
A cast to your player controller
there we go 🙂
You can hover over the return value and it tells you the class (which would most likely be just "Player Controller")
You have a bunch of player controllers. You don't know if they are YOUR SPECIFIC SUBCLASS of player controller.
so now i have that problem that i play inNew Editor Window (PIE) with Number of players : 4 and the last client takes to long to load in that the countdown widget never shows up!
in Game Mode i made this little function (Dunno if it is stupid or useless but it works)
so i checked if all players are loaded in befor i ran "Show Count Down" function
in Player Controller have i done anything wrong here?
when i exit game i get
The widget 'WB_Countdown_C' was already added to the screen.
The widget 'WB_Countdown_C' was already added to the screen.
The widget 'WB_Countdown_C' was already added to the screen.
3 times
also fine
so it just tells me that Is Valid was valid
you have a more elegant way to iterate PCs from blueprint
GameMode-<GetNumPlayers -> for (0 to NumPlayers -1) [body] GetPlayerController[Index] -> Cast -> Call RPC
its the only safe and appropriate use of GetPlayerController[Index] too 😄
didn't know that one existed
what calls ShowCountdownWidgetToAllPlayers?
in Game State @winged badger
I am using advanced sessions if I run a dedicated server, which subsystem besides steam can I use to check?\
I want to see if I can see it online and connect
unless you prevent it from doing so
that Tick will run on all instances of GS on all machines
if yoiu run it from GameMode it will only run on server
so run the "Show Countdown WIdget To All Players" on Game Mode and the actuall counting down (variable and function) in Game State ?
its how its designed to work, gamemode is supposed to have high level control over the game and gamestate is mostly there to help let the clients know about it
you can leave ShowCountdown in GameState that is fine for its purpose
but the entry point should be GameMode
@winged badgerso currently im doing the countdown itself inside the Widget
that is fine, itsd abit on approximate accuracy side
but i don't think it mastters for this
the only thing is i would need to somehow know when the timer hits 3 seconds in the Game Mode
why?
as when the players load into the map they start possessing Cameras that overlooks the map (and the countdown begins) and then at 3 seconds left they shift to possessing the actuall player pawns
ah, this is game level, not the lobby
well, GameMode should definitely do that then 😄
but how can i get the "timer" variable over to Game Mode tho
the widget is created in Player Controller
you don't want to spend an hour looking for where you put that logic every other month when you forget
you can use alternate approaches
like write the GameStart time in the GameState
have the widgets show from OnRep
and run the timer from replicated server time that the GameState alreayd replicates under the hood
but generally
timestamp it
repNotify?
yes
there are plenty of ways to run the timer
my having it read the end time from, say gamestate when instantiated
then displaying endtime - currentgametime as time remaining for example
I'd just send the initial time, then an RPC to start the timer and let it tick locally. Only when the server hits 0 to actually unlock control for the players and all that.
and then gamemode who put the end time there to begin with can just read it
Sure there could be issues with times appearing to be slightly off, but meh.
nothing anyone would notice unless they are playing side by side and both as clients
so i could run the timer in Player Controller or even Game State ?
if you have the gamemode inform the widgets (indirectly) of what is either their start or their end time
the gamemode knows how long till 3 seconds left
as it basically declared when that will happen in advance
and widget can run just fine
one thing you really do not want to do is have a game critical logic in the widget
game has to function just fine if you completely replace the UI
or you'll learn to regret it
another point here, a HUD derived class is designed to create and control widgets
it has 1:1 relationship with the PC and exists only where the PC is a local controller
@winged badgerso i did this
In Game State i created a variable currentCountdownTimer (set to replicated)
In Game Mode i did
and in the Countdown Widget i created a binding
Server and client 1 works fine but Client 2 and 3 it just says "GO!"
this should work right?
@winged badger going to bed can you PM me or tag me with an answer so i can check it tomorrow
you might be better off not using a timer, but instead using GameState (Which is replicated to all clients), setting a float with your target time using GerServerWorldTimeSeconds as your base time, then offset it with your actual timer value. so if you want a 30 second timer, you would just set your replicated float value to GetServerWorldTimeSeconds() + 30 then to get the countdown from 30 to 0 on the client (or server) it would be replicatedTimerValue - GetServerWorldTimeSeconds(). its not as pretty but it will definitely work better than whatever you are trying to set up. if you dont want a floating point value you can truncate or round it to an integer and id probably clamp it at 0 since some clients might experience a ~100ms variance and will show negative numbers if you just print it to the screen. you could also wrap this up in a macro so you have a more timer-like API
Whats up yall
I'm trying to make a host game menu, but I'm not sure how I can make it so I launch a lobby without reloading or changing the level I'm currently in. Any advice?
Like how you can start a LAN world in minecraft while staying the same world
Hey lads I'm having an issue where my door is opening on the client (and the time line that opens it is running on the server, so is the onrep function that drives the ooen/close blendspace) yet I can't walk through the door when it's open. When I start the blendspace on the open animation I can walk through it fine. Here's some videos that hopefully demonstrate more of the problem. I posted in #legacy-physics but I feel like this is more of a network issue. I have not tested this in standalone or as a listen server and the videos are shown with PIE as a client and a dedicated server in the background. https://media.discordapp.net/attachments/221799426820276226/971911924835041360/UnrealEditor-Win64-DebugGame_jcid8fvEZE.mp4 https://media.discordapp.net/attachments/221799426820276226/971911979730104340/UnrealEditor-Win64-DebugGame_G2rQkgeSPE.mp4
nvm I got it
AGameModeBase::PreLogin has const FString& Options but how do I pass them when joining a session? I'm currently joining via IOnlineSession::JoinSession(const FUniqueNetId& LocalUserId, FName SessionName, const FOnlineSessionSearchResult& DesiredSession)
guys how can I find out number of players connected to one port ? for example :7777
Can I prevent the owning client of an actor to receive replicated values of a variable?
COND_SkipOwner
Hi, I can't for the life of me figure out why other players can't see my Niagara particle system I'm spawning on the characters. If I put it in the character itself, they can see it, but as soon as I try to spawn/despawn it or change its visibility with code (blueprints), the other player can't see it, only the one who spawned it. Why is this happening? 🥲
The code happens inside a function that already replicates so I can't figure out why it's not working.
show the code
Would I change the second event to multicast? I've tried it
it would kinda work, but badly
If I just add the particle system to my character bp they can both see it
multicasts can't really handle stateful changes
buuut I need to turn the particle on/off
because its the part of your (replicated) character
so they can both see it
you should replicate the State (Flight) itself
then spawn the particles from OnRep
Oh that's a good point
otherwise, lets say im standing 16000 units away from you as a client
I do have a "is flying" variable in my character, I could try putting the particle spawn in the repnotify of that
you start flying, you multicast the particles, but you are not currently relevant to me, so i don't get the MC
i come closer and MC being fire and forget won't retroactively execute on my machine
so no p[articles for me
in contrast, if you replicate state, when you become relevant, your character replicates its stuff, among those, the fact that he is flying
and my machine spawns the particles
same scenario applies to hot joiners
(only for hot joiners, bAlwaysRelevant won't save you)
AHH putting it in a repnotify worked sort of!
so MCs are mostly for effects, bomb goes off, explosion and sound happen that moment
and I see 🙂
and doesn't matter if someone enters the area, he shouldn't see it anyways
anything statefu, use replication instead
omg it worked, thank you
So on repnotify should I do a flipflop and on A have spawn particle, then on B have destroy particle?
nvm that didn't work lol
Okay I just did a branch instead and that works! 🙂
Also, while I'm here, I have an item pickup system- but if the player carries the object out of render distance and then comes back with it, the other player won't see it anymore until they drop it. Not sure how to keep it loaded in
It still works it's just a visual issue
non relevant actors on clients are destroyed
and spawned again when they enter relevant range
so you're dealing with a brand spanking new instance of that pickup here
it will attach itself where it needs to from under the hood OnRep_AttachParent
but rest is up to you
hey guys!
i have a problem -- weapon doesn't want to call it's own server functions through client (it puts to console Client is absorbing remote function ... on actor ... because RemoteRole is ROLE_None) -- i tried putting ticks on actor Replicates and Component Replication for each component -- warning disappeared, however bug is not solved yet :))
what am i doing wrong
The actor needs to be replicated to call Server functions. It also needs to have been spawned at runtime on the Server only, and replicated to the Client
It should also be owned by one of the clients' owned actors, like it's pawn or controller
bumping in case anyone has ideas. here is a somewhat updated version of the door blueprint im using. DoorPositionAlpha is the only variable that is replicated and its only set from the server. https://blueprintue.com/blueprint/uujrgyrj/
ok, got it, thanks!
So project is getting to the point where it would be reasonable to test stuff out with other players. Are there any good tutorials on setting up a proper multiplayer environment over the net? Ie everything I need to do from start to finish so my friends can open up a client on their own computer at home and connect to the same session as me?
well 🙂 now it doesn't spawn my weapon actor through server function called in BeginPlay because it says that my BP_MyPawn has no owning connection
If it's an animation, they don't play on Dedicated Servers by default
thanks, thats understandable. do you happen to have any suggestions to achieve this? (literally opening a door and making it work nice)
On the Server you can set the doors' skeletal mesh to "Always Tick Pose and Refresh Bones"
mate you are like multiplayer jesus
ty for that! i will deff try that
either be a listen server or you need to RPC to the client the data needed for the widget
whats the situation? like give us a real world example of what you are trying to do
im not sure exactly what your setup is but you could just make a Run on Owning Client RPC with the data you need. like maybe a bool input for success/failure or maybe a struct with each field with a bool and error message or something
the reference is on your player controller. i dont want to say "normally" because i dont know if thats correct, but if you need a reference for later, store it somewhere. it seems like maybe HUD or just the PC itself could store a reference to this widget, then when the client RPC is called, just grab that widget (and check its validity) then maybe call a function on it like "OnResponse" or whatever
so i got a bit confused (please excuse me)
this is in Game State! so i make a Float Variable named countdownTime (and this should be replicated)?
yes it should be replicated
but dont set it on BeginPlay
unless thats when you want it set...
id honestly just make it a macro that does GetGameState -> GetServerWorldTimeSeconds -> SetCountdownTimer
in a Blueprint Macro Library ?
sure
just make sure its Actor
otherwise you wont have access to any of the World stuff like GameState
@plucky prawn would i then run that macro in Game Mode or?
because you selected Actor you can use this macro in any Actor
including GameMode
also note that if you call this macro from the client it will not replicate to the server
just a quick side question here! is this a valid way to check if all players have loaded in?
how loose is your definition of "loaded in"?
i mean, when i started this project and i tried to add countdown widget "to viewport" it would only popup on Server and Client 1 and not 2 and 3... so i made this so "add to viewport" would only fire on True! and well it worked but i wanted to make sure that this was "valid" to use
the way you are implementing it now will replicate to all clients
if you want to know if all clients are present in the game and ready to play, thats more of a side quest
Easy way is for clients to send an RPC to the Server when they deem themselves ready to start
Wait for all clients to be ready on the server.
you can automate this but its honestly better to just have players declare themselves ready
that is kinda what i want tho! so
- Load the map
- Wait for all players to load in (be ready to play)
- Display countdown widget
- Start the countdown
Exactly what I do
For my project, each client sends an RPC to the Server when the PC, PS and GS have all begun play on their side
so i could just in Player Controller make them press a button (say space) or anything that will then send to server that they are ready?
or am i wrong?
Sure, or just send it automatically in BeginPlay()
if you want or do what @solar stirrup suggested which is also how i do mine
correct me if im way of! so in Player Controller i would make a Custome Event and set that to Run On Server and Reliable?
Hey, guys. I'd like to implement an online system to my game. Just as a few extra detail, it's 4 players co-op and P2P (no server involved).
First time I made an online game was using Unity (Mirror Networking) and was a mess trying to figure out things on my own.
Do you happen to know an online course or a good tutorial where I can learn the fundamentals (or even more) about online in UE4?
Disclaimer: I'm still googling, but back then it took me a few months before finding the correct educational material that actually helped me understad Mirror.
Hello, can anyone help me with possessing an actor or a pawn(?) on client? Seems like possession works but camera doesn't change.
@plucky prawn @solar stirrup
P2p is not supported by UE networking, it uses server-client model. You can avoid a dedicated server by having one of the clients act as a server (called a listen server). Search for Cedrik Neukirchen's network compendium for a good explanation of UE multiplayer
Thank you! I'll take a look at that!
It's also a pinned thing in this channel. Just FYI
Can some players be on 1 level and some players be on 2 level? And travel to each other? Is it possible with advanced session plugin?
Hey, I got a bit of an issue. Probably something really simple to solve though. I'm trying to make a server build but I get a "corrupted files" error with this message on the terminal:
Seeked past end of file /Engine/EngineResources/WhiteSquareTexture (129645 / 3851)
I'm just using the 3rd person sample to do this build
Client build is fine
Im getting rubberbanding while my character is accelerating/decelerating with the character movement component
as soon as it hits max speed the rubberbanding stops
any ideas?
I could just make the character go at constant speed but that's ass
By accelerating you mean accelerating within the context of the CMC or are you varying max speed over time (trying to do acceleration yourself)?
You just have a low acceleration value right, leaving the max speed of the CMC constant
Within the context of CMC
yes, if i have to change the max speed i do it in the constructor (or right after the constructor (BeginPlay))
Hey guys, when I call ServerTravel on a player server, sometimes a client will receive the request to travel to the map they are already on instead of the one the server is requesting, all other clients get the right map however. Any ideas what may cause this? (client also in this case ends up loading the map earlier than the host too)
I know it's super basic, but I've followed tutorials and checked guides
I'm trying to make a widget appear on two clients
but I either get errors saying viewport is none, or I get 2 widgets on the same screen (if I'm using a listening client)
Try get owner controller instead
owner controller? I can't find any calls to that specifically except in AI stuff
I tried get player controller from player state, but it seems like everything is running on the server and not actually in the target clients
works for the server client, but kicks back that it's not a local controller for the second client call, making it seem like it's still running the code on the server not the client
Maybe it is.
yeah... no matter what replication form I choose
same result
it's all running the code serverside
which is really weird, I copy pasted code from a tutorial into the same class and it just didn't work lol
my bad i gave you the widget controller function, the pawn/character one is just Get Controller, then you cast it to your Controller
where would I be putting this code normally, to make a client side widget?
inside the player pawn class?
I've tried player pawn, game mode/state, player state, player controller
everything I try just runs all the code on the server
for some reason
i generally prefer to use my custom Hud class which is client only but you can also use the PlayerController with Switch Has Authority -> Remote -> *Client logic
since the player controller exists on both the server and the client then you will run into issues creating widgets unless you make sure the Authority is client side
but you think having a specific client side class makes more sense?
Why do you have a special event to initialise the UI instead of, say, BeginPlay on the pawn?
(or controller)
mostly because I've tried a million iterations of this
that was one of them
not the one I screenied
I've been smashing my head on this for a while ><
where would I initialize it so it's actually client side?
I know this is dumb but I trust nothing anymore XD
since all the tutorials have flat out failed me
Agreed, also just in case you were not aware, the Hud is client only. Think of it as the player's screen.
game mode only ran once when server starts no?
it is set in the GameMode
ooooh
But the game mode will tell your PC which class to use.
a setting
erm
well
this is my new HUD class
set in the game mode I use
which, since I only want local visual stuff on the screen
that seems like all I'd need?
Pretty much.
only shows on the listening client again, not secondary...
no text error
just doesn't show
only the server and client 1 are trying to run it
client 2 never tries
welp
I'm friggin dumbfounded
@latent heart @velvet kettle I made a dummy test in about 5 minutes, input just the suggested code and it works
but that doesn't work on my project lol
hm
will test
loe and behold
yep
it's something about my widget that's the issue
I think the strange thing there is that said widget silently errors when you try that
but looking in it there's a chunk of code so there could be an error baked into it somehow
i'm sure you will figure it out
as someone coming from outside of ue, what is the setup for multiplayer?
things you need to keep in mind from the start so to speak
ie dont convert a single player to multi 😄
also how does that work with blueprints, are they client side
i assume bp when compiled are part of the source?
Game mode isn't replicated.
Never assume that things are replicated in any kind of sensible order.
Replication doesn't happen from client to server.
Go
Yes, bps will exist on both server and client, similarly, begin play/etc will run on both server and client.
can we run server on old laptops? We dont need to have super fast video cards or the newest 19 processor right? I just want 12 players per server thats doable with a laptop on a good ISP?
Does event tick do the same as beginplay on both server and client too?
Yup, both server and client will tick.
is it ok to pass values to server functions?
or is this like a big no no
because in my mind when someone shoots, right, it makes sense to me to calculate the position and rot on their end, then pass that value to just spawn the bullet on the server.
I'm still new to multiplayer, and I am still not quite sure what huge server overload or whatever looks like, and idk if calculating the spawn location on the server is bad
Can players be on different levels? And travel to each other any time?
I have the beginnings of my game but when I test it in PIE with multiple clients (in listen server mode), as soon as I cast an ability (GAS) on a client, that client seems to disconnect or something. He can no longer be seen by the other clients and can't see them either. Any ideas what I've broken?
Is there any documentation or guides on Multiplayer player basics, i get how to cast from within the GameMode to the GameState in order to update the PlayerController and which of these exist why and where (Thanks to exi's network pdf).
However I'm more interested in actual examples of wether i should be running an event/function to update say the score in the GM or GS (Game mode updates a score var thats on the game state or should the game mode call the score from the game state and update it there...)
I'm guessing GS and The Rule that governs scoring is in the GM and that that calls an update score function in GameState but id really like some basic info around this and similar best practice. (This could be a confidence thing or a methodology on my part) but just seen so many different ways of doing it that I'd like a direction on which and why
i get how to cast from the GameMode to the GameState
This is never a thing.
Imo (and people's opinions vary) I don't think game state should have any controlling logic. It should hold state information, like scores, teams, etc. The game mode should be responsible for updating everything. The game state is also useful for any kind of global broadcasts you want to do (like chat systems, etc.)
I used to do all logic in gamemode as well. Then hardlinked with controller. Its Way easier if its in gamestate since its replicated and more tied into the playerstate which is also replicated.
I mean, you can have logic that needs to run on the clientside on game state or the pc... but server-authoritative logic should be only on the game mode.
That's not casting a game mode to a game state. That's getting the game state from the game mode and casting it to your particular game state class.
Wording is important.
If you use the wrong words, you may misunderstand what a) you're doing b) what the engine does c) fail to communicate what you're doing d) misunderstand what people say when they try to help you.
i never said/typed casting a game mode i used from
Hmm what would you call exclusively server quthoritative logic? An example would be good.
Changing player or team scores would be a big one.
Deciding if a player can use a particular item (based on their team,) for instance, is probably good client side logic.
But you'd still verify that on the server before actually using the item.
Everything is pretty much dependant on your game, really.
Apologies. I missed the 'within' word. I'm still half asleep.
That case would be better handled by gas though. Since it could hamper gameplay responsiveness
Probably, yes, I really couldn't think of something else. 😛
But staying on topic, there really isnt any golden rule
Only if you have a team or convention already set up
You could just put all your logic in the game state and it'd be perfectly fine.
thats what i was wondering
It really makes no difference in the end, except to hackers/cheaters.
If you consider epic a best practice, lyra is heavily using gamestate
Epic is rarely best practice 😄
They use deprecated stuff in Lyra already. Their engine code is a mess of conflicting standards, etc.
Really? What deprecateds stuff?
The GENERATED_UCLASS_BODY macro isn't meant to be used any more (I believe anyway,) it was replaced with GENERATED_BODY ages ago.
Maybe they have a reason for it, shrug
as theres an all players array in the GS would you use that in the GM or do an event postlogin to create an array of all connected player controllers?
Im wanting to check if all players are ready to do x
The "is ready" var should be on a player state, not a player controller.
Player state array afaik is an updated list of playerstates in session. I used to hold a list of controllers ingamemode on post login. I have to manually update it whenever a player leaves or what. Playerstate array in gamestate is updated
well so far i have this in my GS but am wondering if it should be in GM
Yup. I have a comp in GS that manages howmany players are ready. PS can communicate to GS to tell if ready
Why not just use the World methods to query the controllers?
If youre feeling spicy you can do it on the clients GS aswell
because im just googling that now as its the first ive heard
Way cleaner if you make it apure function that returns false it one player in the loop isnt ready
true but i was thinking i want to extend it to tell everyone who is and isnt ready
I like the current implementation. But it relies on you triggering that event at every required point.
@tame sapphire the player states are already replicated, so a bool on a player state will already tell everyone who is and isn't ready.
well would a event by timer work in gm that check if all ready or a var reaches 0? as theres going to be a 20second time limit anyway this check is just to cut short the timer
Check if all ready whenever someone presses ready
Or when a player leaves
Damn fckn edge cases
I should note that down but in this instance if some one leaves that shouldnt effect game play
If 10 players are ready and 1 isn't. If that one player who isn't ready leaves, all players are now ready.
yeah
and after the 20s decision timer the turn progresses to next state
so he kinda has 20s to reconnect and make his decision or miss that turn
if he leaves permanently then for now its unlucky on that team
So it does affect game play 😛
Its qol though.
Qhy so you want to move it to gm?
feels like it should be there * shrugs* I think its because its setting the bool in the GS and not in the GM
You could put the event on the Game Mode - or you could put the event on GS and when everybody is ready trigger a "everybody is ready" event on the GM to start the countdown or whatever.
well it happens on every turn start and that is going to have to be GM so i think its gonna make sense if i think about it but the timer is running at the same time
Why the get PlayerState call
You already loop the player array
Just take the pointer
Should APlayerController::AcknowledgedPawn be the same as AController::Pawn? I see (pic) that they may not be. What is the difference then? And if so, whats the AcknowledgedPawn purpose (Used in net games so client can acknowledge it possessed a specific pawn doesnt tell me much)? AController contains Pawn anyway
or is it like a callback
still learning, but thank you
Better to check where acknowledgedpawn is getting cached. I believe its a local cache. And getpawn could be referring to a previous pawn due to latency.
Following some more lovely tutorials, and I'm digging into the concept of ownership.
The tutorial said "You should run all of your client -> server code in either the player character or the player controller since those are owned by the client"
And I was stymied for an hour or so before moving the code from my character to my player controller. Is that tutorial out of date or am I missing something obvious?
The character should work fine as a place to send RPCs
As long as it's spawned on the server and possessed by the player.
Any generic character or any player's character won't work.
The player state is also a valid actor.
isn't the player state owned by the server though?
can't say I understand the distinction but hey I've got lots to learn
I was using the game mode pawn that I set that's a character and is autospawned when players load in (basically example code + experimenting with stuff)
I'm gonna assume somehow that's the issue
You can have 10 players on your server, but only your character will let you send RPCs.
You can't send an RPC on somebody else's character.
right
I was running dedicated server
2 clients
and calling "execute on all" to spawn a ball
inside the default pawn character you autoposess
what I'm gonna guess is I should have
run on server "make thing func" and on the server "make thing func on clients" as an echo?
the execute all code spawns the ball on all clients
If you ran an 'execute on all clients' node from a client, it will execute just on that one client.
You are correct, you need to tell the server to do it for you.
when spawning stuff, only the server needs to do that right?
if we're talking about visible/interactible to all objects
Yes
and turn on replication in these objects
ye, that one I remembered at least :D
cool! I got it!
I definitely stayed up too late working on this last night and missed "only call multicast from the server"
I think I've got the logic straight now
👏
also the tips about using HUD last night for client side UI stuff is good
anyway I'll be back in probably 20 minutes with more questions when I mess the next thing up XD thanks a ton everyone.
Does anyone know if Advanced Steam Session plugin is working for UE5?
Any 1 able to recommend a basic abilty/spell for multiplayer? (Essentially the idea is to call on a specific vector that you send to the server at the start of the round the server then enacts your turn and casts the ability/spell at that location)
I know I should probably look at/into Gameplay abilities but was pretty certain somethign basic would be fine
Spawn an object at that space?
simple if you're talking about testing the code out
@latent heart I'm back :D
I'm testing spawning a custom object, and for some reason just the basic replication set up it vibrates horribly during replication
what I don't understand is that the replication settings are identical to the example classes
their moves smoothly, mine looks like it's vibrating
Shrug
wish me luck then lol
this turn based with a grid?
It depends on what your abilities can do, and how complex they get, but I'd start with a DoAbility event and an Ability structure or class
Where should i start with Multiplayer player basics in UE5?
Keep this in mind
yep I've read that quite a few times
the issue was actor spawned on server good, actor speed variable modified on server bad
Repnotify on bDoorIsOpen
That depends on how you're doing movement. What is doing the movement?
IDK how replicated the stock projectile movement component is but you'd at least want to make sure everyone agrees on what its speed should be (if it's even simulating everywhere, I just made my own projectile system because I don't like the stock one.)
but it didn't update its speed when I changed it on the server
so what I did was multicast the speed update
and that fixed things
Is speed a replicated variable? Remember that speed is only used for the first calculation of velocity
Speed probably wasn't a replicated variable
well, whatever it is it's all internal in the porojectile movement
not something under my control
Yeah I think the stock projectile movement is pretty ass tbh
well I'm just making a funny little multiplayer game for starters
I'll just work around it for now
I did solve it though, it's been a really good example to practice
For sure tho, don't use a multicast for that. Speed is a state, so use a repnotify if you must update it after spawning
I don't have the variable for speed
well, tbf it's actor velocity
I'm talking about
sorry me using the term wrong
Show how you're doing what you're doing
sure
@dark edge sorry wife asked me for something
here's how I handle it currently
I'm modifying actor rotation and velocity in the multicast
no custom variables, projectile is set to replicate
Show ConfigureCannonBall
That's a bit spaghet, do it like this
In your cannonball, add a couple variables for all the additional stuff you want, mark them exposed on spawn and replicated if need be (not sure if they have to be)
fair, although the spaghetti would just feed into the spawn cannonball then lol
the spaghet is eteranl
eternal*
the issue is still that velocity update
there are going to be times I want to update the velocity
and it seems doing that server side only is bad
Then your flow would go like
Input -> ServerFireCannon
ServerFireCannon -> Spawn Actor Cannonball (passing over the additional info in the spawn pin)
Cannonball Begin Play -> Apply the stuff
I'm not sure if projectile movement component replicates its internal state (I think it does). is the component replicated?
Make sure the cannonball and the projectile movement component on it are replicated
Leave out the randomness for now, just try adding the ships velocity so
Cannonball Begin Play -> PMC.Velocity = PMC.Velocity + ShipVelocity
component is indeed replicated
everything about the cannonball is set to replicate
Is replicate movement checked on the cannonball actor?
yep
like I said
if I do my update function on the server
it still works
it just wigs out beause the clients don't think it's moving
and the server constantly reminds them it is
causing weirdness
OK so set AdditionalVelocity to be replicated, and on beginplay in Cannonball
PMC.Velocity = PMC.Velocity + AdditionalVelocity
try that
Don't gate that by server btw, try just Begin play -> set pmc velocity
👍 I got it working
Yeah IDK how the guts of the PMC work but I can't stand it using a collider vs just line tracing so I made my own.
well it doesn't seem to replicate at all
so I have to set and update everything on each client for that
which is big blug
Nah it does some replication I'm pretty sure, it has all sorts of interpolation stuff
well, the velocity component doesn't*
which seems kinda important lol
thanks a lot for the info :)
I just heard about playfab for the first time, is it really that good? Sound too good to be true if I undstood correctly
What I mean is, is it basically free servers for small games? And what is the downside?
I'm trying to figure out the best way to add servers to my game and I really don't have any idea 😭
Would it be better to go full playfab or just p2p? :D
no grid but turnbased you plan a move with rest of your team and then server executes it, think simulatenous turns
I was planning on a basic move to for now and sphere traces at locations
can I create a server reliable function in a UGameInstanceSubsystem?
I'm trying to make a subsystem where you call a function from a player, and pass text.
Subsystems aren't replicated (might be possible and hacky but aren't out of the box)
I see
I think some people are just making an actor the subsystem can route through
I'm sorry, i didn't understand
I'm supposed to make a Text/Chat subsystem, but after reading and trying a lot, I'm not able to do anything from the subsystem class
hard mode: Do all the servers by yourself than get an angry community that demands better queues and less ping, and in some cases these demands are almost impossible, All of this all the while you have to push out updates and pay for the damn servers.
Hmm, easiest mode: give up and start making a singleplayer
Anyone? Literally any idea?
Also how do i spawn a replicated actor again
just set bReplicated to true in the constructor?
Speed needs to be the same on both client and server when they're playing moves
How are you changing your speed
I just ran into this issue with the default projectile movement: The velocity of projectiles is not replicated by the server in the default class
I'm not sure if it's entirely related, but I needed to adjust my velocity on clients and the server to stop making the weird rubberband/glitch by getting server/client to agree on the location of the object
If I want to attach one player character to another (e. g. for a grab), what's the most sane way to replicate that? Just an ordinary multicast rpc or setting the mesh component to replicated or is there some best practice here?
that is extremely tricky if you can't turn off collisions for one of them, can you?
Yeah I would have to turn off collision and movement too in a replicated way
root motion animation via gameplay tasks then
there is an option where you'd rip the skeletal mesh off one character and attach it to the other
but that turned out somewhat tricky to get right
What option exactly
I can't recall an option that attaches one actor to another from a root motion task
its not a root motion solution
that was our attempt 1 for something similar, and we discovered gameplay tasks with root motion before we got it working
although i think it could had worked
I'm currently using a gameplay cue for the attachment since it reliable gets to simulated proxies, but I could also try an anim notify
you'd still need a cue to replicate and trigger the anim notify here, no?
No, the gameplay ability montage task takes care of that
we have several monsters that can throw you, drag you, pin you down or even swallow you
for all of them gameplay task driven root motion animation works just fine
So ure just disabling collision somehow and then have a task pin the char to the other char?
we have to disable collision or someone would end up in orbit
most of our abilities that do stuff like that don't do attachments, but i think one does
The root motion tasks all have finite durations, so I suppose ure not needing variable duration attachments?
Or u made custom rm tasks?
we have one boss monster that can drag you away
its a root motion to get the drag going
but its attachement afterwards
And the attachment is rpced by multicast or an anim notify?
this scenario its stateful, so MC wouldn't do
replicated gameplay tag on a character
pretty much
And u somehow extrapolate to who and to which socket the player is attached from the tag?
getting into relevant range, or hot joining after you did grab via MC would break for the newly relevant client
no, the monster ability is running
and its controlling the attachement
the replicated tag disables (most) player's controls
Yeah but how does it tell the simulated proxies that the player is attached to a particular socket of it
The boss ability isn't replicated to anyone after all
the scene components replicate their attach parent
if they are replicated themselves
aside from that
By default? So I just have to check replicate component in my characters mesh component and I'm good?
can do a FProjectReplicatedAttachement
send a socket name and a pointer to a net addressable componenet you're attaching to
if the scene component replicates, sure
Interesting, so if I do attach actor to actor, the skeletal mesh comp of the actor I'm attaching to must be replicated and I can do it on the server only and be good
replicating the skeletal mesh is generally... not great
But that's the scene component with the sockets that I attach to
you don't need to replicate the component you're attaching to, its part of the CDO as are its sockets
you need component you are attaching to replicate
But that would be my char capsule comp
void AActor::OnRep_AttachmentReplication()
you might need to experiment a little, i did not write that system personally, just kept informed
So I just set my characters capsule component to replicate in the blueprint and I'm good?
but root components of the actor will use Actor directly to replicate the attachment
/** Handles attachment replication to clients. */
USTRUCT()
struct FRepAttachment
{
GENERATED_BODY()
/** Actor we are attached to, movement replication will not happen while AttachParent is non-nullptr */
UPROPERTY()
class AActor* AttachParent;
/** Location offset from attach parent */
UPROPERTY()
FVector_NetQuantize100 LocationOffset;
/** Scale relative to attach parent */
UPROPERTY()
FVector_NetQuantize100 RelativeScale3D;
/** Rotation offset from attach parent */
UPROPERTY()
FRotator RotationOffset;
/** Specific socket we are attached to */
UPROPERTY()
FName AttachSocket;
/** Specific component we are attached to */
UPROPERTY()
class USceneComponent* AttachComponent;
FRepAttachment()
: AttachParent(nullptr)
, LocationOffset(ForceInit)
, RelativeScale3D(ForceInit)
, RotationOffset(ForceInit)
, AttachSocket(NAME_None)
, AttachComponent(nullptr)
{ }
};```
you have everything you need here
Nice, yeah I knew about that built in stuff, so if I have my capsule comp set to replicated it should work automatically or do I need some cpp overrides of my custom character subclass
Or is there some on rep I need to expose to BP
capsule doesn't need to be replicated for this to work
see ``void AActor::GatherCurrentMovement()`
Ok thx a lot, I'll have a look at those functions and the struct
Alas disabling collision really needs some manual rpc I guess
it needs to be in the same packet that triggers the grab
so, basically, same actor channel
you don't want a replication race here
I see
you can control the order in which variables within the actor replicate and call OnReps
or you can just do the whole thing in one go in PostNetReceive
Thx, I'll look into that rep struct first, gotta expose the on rep to bp
Im trying to make weapon firing for clients. Valorant rewinds the position on hit targets and the firing client to validate the hit. Im thinking about doing this, but Is there a better/simpler way of doing this?
Is Lan-Play multiplayer possible via blueprints on UE4?
Wdym by is there a better way of doing this?
Like a better way of doing rewinding for shot validation?
The simple way is to not do rollbacks at all.
^^
That sort of lag compensation is inherently complex to implement (and get right).
But it's also pretty much the only way to build a competitive multiplayer shooter.
Yea def depends on the type of game