#multiplayer
1 messages Β· Page 189 of 1
Mover has a bit more activity than I was expecting to see
Welcome to Unreal Engine
Oh I'm aware, been using it for a long time but never dug into multiplayer until now. I feel like 5.4 was a big step up in some areas of the docs though
https://github.com/EpicGames/UnrealEngine/commit/52be71dfce4d51b6d5782960c6d67ff50834ab81 at least Mover means NPP also gets attention
though this is the only significant change in a while
Hm well, I guess I'll just go with the good old CMC for the time being until Mover has matured a bit at least
I poked the guy myself and he seemed very open to actually getting it sorted.
My usual fix BP side, is just trigger the rep notify/ edit on begin play.
if the vps server is not stable, it could be the reason of clients crashing?
I literally just did that to our local version haha
FML for spending time on it I guess
I think that's triggered by SirKai PR having that stuff in it
Actually, that is just a very small change. I actually turned the whole Mover plugin up side down and got rid of all FNames for Modes and Blackboard.
And also (in a previous step already) added full Tag support to the Blackboard.
i want to return a value, but i can't because i work with custom event. how can i return that value ?
Using a function instead
Events can't
i want to call a replicate function in my widget who can return me a value. how can i do that ?
You can't
Replicated Events, aka RPCs can't return values. You would need to send a second RPC
Now if there's a built-in solution for having clientside interpolation for the fixed tick policy now that'd be something
Also keep in mind that widgets can't have RPCs in them. The RPC itself needs to be somewhere else @vital furnace
Heh
It was good enough for Quake
yes i know, that is why i call a replicate event in player controller and iwant it to return me a value. how can i do that ?
Send a second RPC into the other direction
please make me visualize
??
If you have a Server RPC in your Controller then use a Client RPC to send data back
There is no return values for RPCs
thanks
When packaging a game w multiple levels in the project , should I be deleting levels im not using or does it not matter if they are not being used in the logic / game (currently)?
Does anyone know why serverTravel does not create the playerControllers when we use it with a dedicated server as gamelift
If I play it as as client it works
When packaging you can usually select what levels to package.
wdym when you play as a client it works?
And wdym with "does not create the playercontrollers"?
amazing, yea im clearly a noob have not packaged anything yet and im so worried for whats about to go down
@thin stratus The problem I have had for days. I have a dedicated server created with gamelift and when I have a certain number of players on my map server lobby and I do serverTravel in its gameMode it makes the map change but it does not create any player controllers therefore I cannot control the players. This only me It happens when I play it on a dedicated server.
Do you say that because you know the Objects don't exist, or do you say that cause BeginPlay of the PlayerController isn't calling?
hi, Im new to multiplayer in unreal. is there a way I can turn off this Niagara effect when you are playing as the character but can still see it when looking at the other player. so turning it off for myself but still have it show in the game.
make it state driven
@thin stratus What really happens is that the postLogin of my destination map and using seamless travel does not create any player controllers, therefore the gameMode of that new map is not being called because my server crashes. The same code works fine for me in ue4
what is the effect? Is it meant to always be there or indicate some sort of state?
this running on a dedicated server with gamelift
SeamlessTravel doesn't call PostLogin
I'm relatively sure that your PlayerControllers create just fine.
You are probably having code hooked up to stuff that works nicely in HardTravel situations, but won't work on SeamlessTravel.
with the handle node Starting new player doesn't do anything for me either
I wouldn't know why PlayerControllers won't create if that's really happening.
That would point to an utterly broken Engine
I have seen the different logs. And on the server it does not do the serverTravel and my clients do, therefore the session is closed for me after a while
The strangest thing is that the same code works perfectly in UE4 4.26
I don't really know how UE5 works with smooth travel.
The problem is that it only fails for me on a dedicated server hosted on gamelift
Is it possible to filter anim graph nodes in dedicated server? I don't need all the blends in the server
Im having an issue with the weapon that i am attaching to the player. The weapon in my hand is the one we see and the one in the air is what they see . it looks like its attaching properly (second picture) but when I unhide the pistol its stuck in its starting position and wont follow the transform. can someone help
[Question] What's the best way to handle sprinting if I want to gradually increase and decrease velocity.. and not have it lag.. I've been testing a few different ways out.. and when I use some artificial packet lag it always hitches
When I'm sprinting and I stop sprinting, I want the character to gradually slow back to their normal MaxWalkSpeed... to do the gradual speed up, I used MaxAcceleration
but kinda stumped on how to slow down gradually without it having rubber band effect when there's lag
Customise UCharacterMovementComponent to allow client-side sprinting prediction
ok cool, we do already have a custom CMC.. what would you do in there specifically?
Create custom network prediction data for the client and custom saved move; you would need to fill then with the sprinting state, so that the client can predict it. In the custom CMC you would need to package and dispatch those packages accordingly. You can google that as there are plenty of tutorials about that
So I need to have an AActor that belongs to the server (be it dedicated or listen server) that I can use replicated functions with. It can either be placed in world or spawned at runtime. But I don't necessarily have a PlayerController to give ownership to.
Anything that doesn't belong to a client, automatically belongs to the server. You don't have to own an actor to perform RPCs as long as it's replicated
you won't be able to have clients call server functions on it though
Ah, see there's the issue
it will be able to multicast down to everyone.. but your clients have to have ownership of something in order to call a server event
What's the best method then?
might consider just... giving ownership to whatever client needs it at the time
Use the PlayerController instead.
But what if it's a dedicated server?
If you want to encapsulate and abstract away the details of what you need to have done specifically, put it all in a Component that you add to the PC.
Ok yeah that was actually my original approach, but it felt funky
I worked on a game that had like a shop keeper.. and it would spawn an actor that we'd give ownership to for the client.. and that's how the client would buy stuff.. it would be talking to ITS actor that the shopkeeper spawned
Make a Subsystem that manages the details on the Server side if you need a centralized place.
The Subsystem would talk to the Components on the PCs
To do the network messaging
Yeah but this is like a central terrain chunk manager. And I need to be able to have lots of players modifying it. I don't think I want to be changing ownership a whole bunch for this
Yeah then have a Component on the PC that is the TerrainModifierComponent
Which talks to the TerrainSubsystem
π€·
Yeah that makes sense. Shoulda stuck with that approach haha. I was trying to reduce bloat, but I guess I oversimplified things.
How new to game dev and programming are you?
C++ maybe a year and a half. Haven't done much multiplayer in C++ till now though
Been doing blueprint for like 8 years though
Ok
But I definitely don't mind getting my hands dirty with C++. It's what I'm using for this plugin. I like it better than BP
Premature optimization (this includes combating "bloat") can be detrimental.
It sucks development time and impedes your ability to iterate properly.
Yeah, I've heard "Premature optimization is the root of all evil". I guess it's kinda true π
First pass on systems design and implementation should be focused on just getting the idea working.
Wise advice.
When you have it working how you envisioned, you can then take it in as a whole and evaluate it with the rest of your systems.
This helps identify areas that need improvement.
One of which could be performance
Second pass is when you focus on those elements of improvement.
Because you can formulate a plan on how to achieve those goals.
Yeah. TBH I've really given in to scope creep on this project π
Mainly in optimization. Which I do realize is a problem.
Optimization should not be considered a whole lot at the start, at least not that which is beyond the obvious.
really? I'm currently doing the complete opposite and trying to get everything perfectly right the first time
This is definitely the advice I need to hear right now
Well stop it, you will be more productive.
I think you should get it good enough at the start
Obviously if its tanking frames, thats an issue.
Having a good plan is one thing. Constantly reworking it is another
Designing things on "paper" first is also a beneficial practice. It allows you to think through the problem space and identify possible pitfalls in your initial assumptions early.
I use this online tool quite often to sketch systems before writing any real code.
Interesting!
You can think through a pseudo implementation before actually committing to anything.
Yeah that looks really helpful
It can take extra time to do this, but it is worth it.
Especially with larger systems. It gives you a reference to point to as well.
I think this really is the hole in my workflow right now. I've been hitting a lot of roadblocks recently and a lot of time it's been lack of foresight.
"Paper" design helps a lot with foresight.
It helps you predict outcomes.
See around corners.
And enables you to address them before you really encounter them.
For sure
Yeah. I'll gladly take that advice. Wish I had started that way π
Any suggestions on tutorials that make a multiplayer game in unreal just to get comfortable with it, cpp or bp is fine
learn multiplayer
Take a look through Epics Youtube channel, they should have playlists of things like that.
Also generally just search on Youtube for that exact thing.
Cool will do
There isnt going to be a single tutorial series that will perfectly cover all aspects of multiplayer development.
It takes time to learn and from different sources.
Yes I know I just want to get familiar with RPC workflows and such
Part of the journey
Have you read the Network Compendium?
Yes
https://cedric-neukirchen.net/docs/category/multiplayer-network-compendium
https://wizardcell.com/unreal/multiplayer-tips-and-tricks/
I have lol, i probably will read it even more. Just curious if there were any tutorials people thought were great. Iβm gonna search on YouTube to follow whatever good one I can find right away just to get comfortable.
Honestly, 1 time is correct, but you have to practice what you learn
that's really important
I tried using CHATGPT to help debug this and tell me what i'm doing wrong but it just keeps saying the same things over and over. Why isn't the first person who entered a number not getting their widget updated?
Use OnRep. Don't use Multicast.
Part of your problem could be because of when you're constructing your widgets.
You won't get a valid playerstate until it effectively "Begins Play" so if you happen to construct a widget before then and don't have anything to let you know that another player has joined later, then you'll never have an appropriate way of referencing the player so you can't get its number.
I'll see about changing that.
What do you suggest I do?
You can have something that properly constructs the required widget when the PlayerState begins play
Thanks, I'll look over those blueprints. you always are the most helpful.
What happens with a replicated property in the following case?
- Update1 sent
- Update2 sent one or two frames after Update1 was sent
- Update1 was lost(Packet loss)
Will the client receive Update2 Only, Update2 then Update1 or Update1 then Update2?
It will receive the most up to date state.
So Update 2
Otherwise, if it was to resend Update 1 after Update 2 was received, that would be a desync.
Thanks! π
Is there any guide what the definition of an ActorChannel actually is? There's nothing in eXi's guide, and WizardCell refers to it twice in his tips+tricks.
Searching here on Discord, I think we are saying it is the connection of a replicated actor from the server to the clients version.
Is it one actor channel per spawned entity, or if I have 2x MyActor is it one actorchannel for both of those?
and it sounds like components of a replicated actor use their parent actor's channel to replicate through?
ActorChannel is a low level concept so its not really something you will interface with directly.
It is a per Actor instance connection.
It is the pipe between the Server and Client version of the Actor instance.
And yes, Components attached to that Actor will use its ActorChannel to replicate.
yeah - the reason is the phase that Reliable will result in RPCs garunteed to remain in order if it is part of the same ActorChannel.
Obviously we normally never assume the order of RPCs, so I'm just trying to make sure I understand the logic of when I can actually assume the order
thanks though - that does help clarify the meaning
From my quick Convo in #cpp message
How do I guess?
Go about "conditioning" an entire actor?
Much like the net cull distance squared, or general UE, where you know of stuff around you, instead of the entire map.
But, far more controlled.
Also, any way to know when it happens?
I understand the client has begin play, but does the server have some like added controller to relevance, or removed controlled from relevance
Another thing that would be of use to me, rather then maybe doing something complex.
Any way to have actors be always relevant for some clients, and thee rest following a net cull distance squared type setup.
does anyone have any advice on creating a turn based system where it's really 2 sides and they take turns ? any good things to keep in mind or follow ?
I don't think that complicates things, if anything it should be simpler than most multiplayer setups
tbh was thinking the same thing but i think initial setup is what im looking for some guidance on
looking for a tutorial on liteally a setup of 2 sides, player 1 turn, perform actions, act, players 2 turn, etc
You might be able to just override and extend IsNetRelevantFor
@halcyon ore You may want to look into the IsNetRelevantFor function
tbh it just sounds like you will need to extend AGameModeBase and go ahead and put in a "state" like system for turn behaviour, you could probably do it also without a gamestate but that sounds exactly like what you need to do
(this doesn't help you but I am planning on git open releasing a gamemode/state frame work plugin I am working on that allows you to have game states represented as UObjects that can be extended and override things like ExitState, TransitionToState etc. It should be nice because when I started extending UE's gamemode/gamestate I really didn't enjoy it at all)
Hi,
For hosting linux dedicated servers for a steam game, is GameLift generally preferred, or vanilla AWS? If so, why?
There is no general preference for those types of things.
How does that interact in general I guess?
Does it calculate on tick.
What if I first want it to not be relevent, then 1 second later, be relevant? does it calculate on tick constantly?
Or, how do I guess add an actor to the like "try to be relevant" pool?
Also, what if I want it to no longer be relevant later?
You should read into how unreal gathers a list of actors to replicate every frame, it will give some insight but yes, it will be queried whenever it is going to update on the server if its even relevant for
How about data?
Does the client just have the CDO info, or the full actor data?
and, if so won't that not help me?
It still uses network calls, and time?
IsNetRelevantFor is only called on the Server.
Look at the base implementation of that function on AActor
You will notice it handles bAlwaysRelevant etc
Oh, I must've read something wrong.
Thought I read it as running on client side
Here, I know it was an older convo but I just seen this now https://dev.epicgames.com/documentation/en-us/unreal-engine/replicated-object-execution-order-in-unreal-engine
thanks yea i was suspecting gamemode would be where this would primrily done.
basically a setup like the game in the image is what i'd be aiming for. 2 sides , 1 side does it's actions/attacks/etc, then the other
GameState, its the only thing that is replicated that controls game flow, clients wont have game modes
now that is a blast from the past, wow
the sniper was op
lmaooo, glad someone recognizes it
was a classic
ahhh gamestate. will def need to experiement to get things setup, never have made something like this
gamemode would just know who's turn it is for example ?
enjoy, I more or less just copied AGameMode and AGameState but I started from the Base classes to implement it better for my own needs
cool, by extending them do you mean in cpp? i don't do any cpp really, just whena bsolutley needed
Yes I did, but, not necessarily needed, you can do it with BP but you are really hurting your ability to go full custom with alot of systems if you are just doing bp only multiplayer game
yea i've learned the limitations so far as im building a larger open worldish mp game
So I have a question as to why something works vs didint work. I have this setcolorRPC which is multicast call this setcolor function. the OnRep_PlayerColor function contains the exact same code that is not connected after the set W/ Notify node for player color. Using the OnRepNotify works for setting the players color properly to all clients. However if I dont use the OnRep function to execute the code, and simply have it execute after the color is set, the colors of the player only change on the server. Can anyone explain why this is the case? I feel like I am being stupid, but from my understanding multicast should run code on server and all relevent clients?
these are the two dif outcomes btw. With the RepNotfiy both clients have a red and blue player. With no RepNotify and just a multicast the clients are all purple and only the server has a red and blue player. (server is bigger screen)
Is this because the clients player pawns were not relevent? I dont see how this could be as the pawns are ticked to always be relevent, and so are the player controllers.
Any insight is much appreciated!!
where is the multicast event being called?
and when you don't use it as multicast, and only repnotify, what do you make tht rpc ? (server,notreplicated,multicast,etc)?
so the multicast is being called from another actor that is owned by the server
Even with the repNotify, It is still a multicast
can you show me the event where that rpc is called?
Don't use them both together, you set the value on the server and it will replicate to clients with OnRep being called if they differ when they arrive
You dont use multicast + replicated and OnRep together
ones for state and ones for events
it is kindof a complex heirarchy. Bassicly the game state spawns this PlayerManager actor, which I assume would be owned by the server. Then it calls an RPC on the playermanager that calls the setcolor multicast RPC on the individual player controller. Bassicly I wanted to have a function that executes on the player and sets it up, so down the road I can do additional setup I might need in this function.
So would Multicast be for states, and OnRep is for events?
flip it
its working but have a bug like for w and s it moves in client left right and a and d left right in server not actually movw but plays animations while transdfering from server to client
Are you using the CMC or a custom movement component because that looks like it will not predict or replicate nicely at mid to high pings
refering to me
?
yes
no
ππΌ βοΈ
lol
all I will say is - emulate your ping at 50, feel sad for about 5 mins and then pick yourself back up and look into network prediction or look into using the cmc the intended way and watch a youtuber by the name of delgoodie, he has a nice little intro to extending the cmc series.
It will show you some insight as to why you want to do it with client side prediction and corrections in mind
For a non networked game, this would be fine (assuming it works) but for networking its a lot more complex
Hey guys, how can a USTRUCT member trigger OnRep? Does it need to have UPROPERTY() or UPROPERTY(Replicated) ?
Let's say i have:
UPROPERTY(ReplicatedUsing=OnRep_Data, BlueprintReadWrite)
FData Data;
USTRUCT(BlueprintType)
struct FData
{
GENERATED_BODY()
FData();
// Identify
UPROPERTY()
int ID = 0;
}
How can ID change with trigger OnRep_Data ?
I swear i read about this somewhere but i forgot.
I think only UPROPERTY() is required?
You cant do onrep on struct members
Only on the struct itself
Yes i know, i mean how can a change in struct member trigger the parent struct OnRep
??
Because itβs made so any changes to the members itβll trigger the onrep for the struct
But that require that the member have UPROPERTY() on right?
How about chain struct though
Same thing there
like this
USTRUCT(BlueprintType)
struct FData
{
GENERATED_BODY()
FData();
// Identify
UPROPERTY()
FData2 Data2;
}
USTRUCT(BlueprintType)
struct FData2
{
GENERATED_BODY()
FData2();
// Identify
UPROPERTY()
int ID = 0;
}
Yea, same thing there
Thanks mate
hey how do u normally handel "slow effects" with replication ?
since the CMC is not replicated
do u cast to server then rpc an event on every change or ?
what haha
is baffled
You can override the cmc's GetMaxSpeed or you can set the max speed in a way that is replicated, like through a flag so all clients have the same conditions.
The CMC for example has a sprint flag that gets sent with every movement update every frame, if the client was to flip that, when it sends its movement update then when the server receives it, its going to unpack those flags, see the sprint flag is true and that will lead to the MaxWalkSpeed variable being updated to the same as what the clients should have been, thus predicting it and causing no stutters/lag.
And the CMC most definitely replicates btw
hello all! I'm using EOS to host peer2peer sessions (one player host, the others can join). My problem happens when the clients try to travel to the map. I'm using Session->GetResolvedConnectString(FName("TankSession"), JoinAddress); to get the URL but when I execute PlayerController->ClientTravel(JoinAddress, ETravelType::TRAVEL_Absolute); nothing happens. This is the value of JoinAddress (very weird value indeed):
Any insights about this would be extremely helpful. Thanks.
nothing -.-
Why on earth RepNotify happens faster than BeginPlay. How is this even suppose to make any sense. RepNotify as I understand is made specifically to help initialize existing actors in the game for newly joined players. But how can you initialize them, if RepNotify function for whatever reason happens right before BeginPlay, making it impossible to affect any components of the actor without a delay or timer.
I can understand why Player State takes some time to fully initialize on Player join, thats fine, but this RepNotify behaviour I simply can not comprehend.
Because when the data arrives, it broadcasts
and that can happen before beginplay
important note in ue5 the serverTravel for packaged games is broken
I don't know if this is happening to anyone else but I have a dedicated server with gamelift and when we use serverTravel to change from the lobby to the game map the server crashes and it happens in all versions of ue5
Yes I figured that already, but I'm saying that its kinda bad. Sure RepNotify can be usefull for existing players, its easier than RPC (and cheaper too?).
But, as I understand, its main idea is to initialize actors for new players, for example when a new player is joining a session or when it becomes relevant to a player.
And it absolutely no good for that purpose since it always happens before BeginPlay.
Why does it matter, they shouldn't have write access to them anyways
so if they have the values or not shouldn't matter in the context of rep vars and beginplay
I'm just trying to initialize my Characters. I thought RepNotify would be good for that, all tutorials say that its good specifically for that.
But your initial character will spawn with the replicated values?
But I can't Initialize my Character with these values because when they arrive, Character components do not exist yet.
then if you change them after you spawn, the repnotify kicks in?
then check if they have arrived on beginplay or not
and just call the same initialize function as in the onrep
are they reliable? I thought if they are all part of the same ActorChannel the order is always correct for that specific actor (when reliable) - i.e. so its components would replicate with the character and that would occur before any RepNotifies?
Reliable?
the replicated items for you repnotifies - are they marked as reliable?
cause if they are unreliable - the order is not garunteed
this only applies for the speicfic actor channel
ok let me visualise my current issue
Screen 1 - Character Pawn (The event is called when Player State is fully initialized (takes some time))
Screen 2 - OnRep function
Screen 3 - Game
Screen 4 - Log
So my RepNotify function for the client will always fail for the existing actors, because it is happening faster than their BeginPlay. Now if a Player 3 will join, then Player 2 will see his name, but Player 3 won't see neither Player 1 nor Player 2, again because of race conditions.
Loop timer helps, but its an ugly solution that I would have to use every time I want to initalize a component, there is got to be a better way.
Hm maybe I over-complicate things. Maybe I should just use BeginPlay as an Initializer rather than rely on OnRep function.
RepNotify ensures that the variable is replicated BEFORE BeginPlay. Well then I guess I can do it the other way around - Initialize on BeginPlay since the value has already arrived.
read that
it talks about the right hooks to use etc
but fyi - only using BP - your going to have a hard time, yes. In c++ you have more options
I really wanted to start a C++ project, but the fact that you have to fully recompile after each little change is kinda tilting and repellent
you can just do the part where you need C++ in C++ and the rest in blueprint
Ye APawn::OnRep_PlayerState() indeed looks like a problem solver
It's also a crime that by default, there isn't a delegate for the PlayerState being valid on a controller
Hey guys, is it possible to somehow keep rendering debug geometry when detaching the controller using F8 in a multiplayer game?
I used to draw chunk edges for my world (like in minecraft, when you press F9 ot something..) and it worked fine in Standalone even when detached via F8. But since I started launching it as Listen Server it shows only replicated stuff in the detached mode
by debugging geometry I mean DrawDebugBox() and stuff like that
This whole rendering thing makes sense to me only in the detached mode, cause only there I can see the world from reasonable distance
just to clarify - it is not a "full recompile" - its just a compile of the changes, which usually is only a few moments because 99.9% of your code+headers have not changed
Hm. I should try C++ then. Because at this point I feel like whatever discomfort it brings, it can't be worse than not having such features as OnRep events.
for multiplayer - yes
and like ColdSummer said - you dont do it "all" in c++ - you just hook the main functions and some code, then create BP implementable functions and do the rest there.
but your future self will thank you if you are serious about multiplayer
you can also use live coding - but the recommendation is only do that for function body tweaks. Dont use it when doing header changes etc. So that can also help speed it up.
Is there anyone who can help me by explaining how networking works with matchmaking/ battle royale match queuing? From my research Iβm assuming you make a server and when a player presses a βjoin matchβ button they get sent to a random lobby but Iβm not entirely sure
I'm not sure what you're expecting as an answer, matchmaking services are usually a backend thing
Either provided by the platform, some thirdparty SDK like Playfab, or a custom service
and that would be connecting over something like HTTP or Websockets, not Unreal networking related
I guess thatβs what I was most confused on, Iβve never made a multiplayer project, and while I somewhat understand replication, Iβm entirely lost on the matchmaking process and didnβt know where to look to make sense of it
Thank you Iβll start looking more into it
There isn't an Unreal networking part to that, it's a service that ultimately tells you which server connect to, and then you connect to it
The only Unreal thing you might do is use beacons to do something like reserve a slot on the server
I'm trying to use the NetworkPrediction plugin and going crazy with a linker error on NetworkPredictionProxy.Init. I even removed all of my custom logic to just tame the linker error so the logic is now
NetworkPredictionProxy.Init<FGenericPhysicsModelDef>(GetWorld(), GetReplicationProxies(), nullptr, nullptr);
and it still fails. the error is
LNK2019: unresolved external symbol "public: void __cdecl FNetworkPredictionProxy::Init<struct FGenericPhysicsModelDef>(class UWorld *,struct FReplicationProxySet const &,void *,class UPrimitiveComponent *)" (??$Init@UFGenericPhysicsModelDef@@@FNetworkPredictionProxy@@QEAAXPEAVUWorld@@AEBUFReplicationProxySet
here's my Build.cs
PublicDependencyModuleNames.AddRange(new string[]
{
"Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "OnlineServicesInterface",
"CoreOnline", "OnlineServicesEOS", "SocketSubsystemEOS", "OnlineSubsystem", "OnlineSubsystemUtils",
"OnlineSubsystemEOSPlus", "NetworkPrediction", "GameplayTags"
});
PrivateDependencyModuleNames.AddRange(new string[]
{
"Mover", "NetCore", "OnlineSubsystem", "OnlineSubsystemEOS", "OnlineSubsystemEOSPlus", "NetworkPrediction"
});
and my .uproject has
{
"Name": "NetworkPrediction",
"Enabled": true
},
any ideas?
Hi, what are the actual benefits on keeping default ServerUpdateCamera()? I have a topdown game, trying to understand why I should need it. I know that clients are sending camera location to server, but why should I need it? Thanks.
Does find session can find session host on a machine not on the same network like a friend's computer ?
Yes, but only if you have a subsystem setup properly. If you are using Steam subsystem then I think app id 480 only works if both machines are in the same region. Not sure about EOS restrictions.
And if I don't use steam ?
EOS
okk
hello guys! I'm struggling really hard with weapon ammo prediction
my previous weapon implementation suffered from ammo counter constantly re-adjusting when ammo variable was replicated from the server to the client, so it sometimes led to pseudo-shots being spawned, when on the client you fire the weapon, but on the server you've already ran out of ammo and shot did not actually do any damage
i thought about implementing CMC-like prediction system for weapons, but i thought that would be really overkill... would like to hear your suggestions for this issue
This sounds like you are not shooting correctly in the first place.
The client should not, normally, have a different ammo count to the server.
So if that was happening often enough that it was affecting you, sounds like something is wrong with how you are shooting in the first place.
ammo is replicated, but when client shoots locally, ammo subtracts locally too
I understand that, but your example still doesnβt make sense, because it should end up been the same when they stop shooting.
So something is not replicating correctly.
Otherwise how does the server get to 0 before the client in your example above?
oh. i don't know how to word it properly, i'm sorry.. imagine firing a weapon, and instead of spending, let's say, 10 bullets, you would spend ~11-12 because it takes time for the new ammo amount to replicate back to the client, so some pseudo-shots are spawning that doesn't hit anything
Yep. I understand that. But that just means you have a logical error somewhere.
If you client fires 10 bullets, then what does the server think you fired 11-12?
That shouldnβt be occurring.
Anyway, itβs impossible to say what the issue is, as we donβt have your code.
But from a βrubber duckβ perspective, you might want to walk through the logic and see if you can work out why the server thinks you fired more than the client. Even with prediction locally etc, that doesnβt make sense
When should you, and when should you not use "reliable" for run on server/multicast events? Can anyone give me an example please?
reliable -> guanratee ordering and arrival (with the exception when the reliable buffer gets filled)
unreliable -> they dont guarantee arrival, so they could be dropped on hazardous conditions
essentially, use reliable for everything that is gameplay critical - ie - spawning a grenade when the player presses a key
and use unreliable for things that dont matter much if they drop - ie: little sparks when the character overlaps with a volume
If you shoot fast enough you will see a roll back effect
Because you already subtract your own ammo again before the server comes back to you
The prediction for ammo can be implemented with a counter, that's what Stephen did
I can take a look after work maybe
ammo prediction, especially for fast firing weapons, is actually somewhat complicated. Your client needs to stop firing as soon as you run out of ammo so you do want to predict ammo changes locally to avoid looking like you fire a ton more than you actually are able to, but in doing so you'll find your ammo counter constantly jumping around as you receive updates from the server that are a bit behind where your client is.
One solution is to ignore the incoming server value until you've stopped firing, and only snap back to the server's authoritative value once you know both you and the server have completed firing. With a bit of extra complication to handle the case where you fire again in quick succession.
Knowing when the server has finished can be accomplished with GAS prediction keys or an equivalent - the client sends a locally generated number along with every request to fire. That number is sent back from the server with every change to the ammo count. In that way you can know from the client whether you've already predicted ammo count past what the server has replicated to you.
I think it's as simple as you want to update the ammo count to server value when your counter and server counter is the same?
I saw stepgen doing it with a few lines to address the issue
You can't only do that, because you need to correct your value locally if you mispredicted.
Yeah I will take a look again, he does have prediction and server rewind for the ammo
can you link it please? would also like to take a look
same
its his c++ multiplayer course - I've done it as well - its very good
There are discounts every week on his discord - so dont pay full price - it usually like $10USD etc
but its a bargin, and its very good c++ code styles - i.e. its not like a poor youtube tutorial - the methods aling to many best practices on here. Sure, its not perfect - but its better than most things
can anyone buy it for me?
It says its for UE4 - but it'll work for UE5
lol - no
thanks, will take a look if i catch a discount
if you cant spend $10USD on a course, perahsp multiplayer development is not for you at the moment. Sorry, but thats the reality. There are many other 'free' choices out there, but the quality varies significantly
on Stephen's discord - he posts coupons every 2nd week. Defintely dont pay full price - thats just Udemy
wait wait wait, i think i once bought some course from him, let me check rq
it was also multiplayer shooter
oh yes, i did, i bought this https://www.udemy.com/course/unreal-engine-5-cpp-multiplayer-shooter/
is it really different? or i can stick to the one i already bought?
it's the same but ue 5?
no idea honestly
wow, so i already had one. thats good
but fi you bought it, why not just go through all of it?
because i bought the course a long time ago, since then a lot has changed for me so i couldn't do games
yeah - if you have that course - probably need to switch back to it. The best part is, one you do the full course, you can just continue "from there" and build your game from it
and that way you have a solid base to build from
Hello, I am making an attempt at multiplayer online for a board game i made and I am realizing quite far in that I am making a mess of my architecture ( quite new to unreal. so i am learning as I go. )
i thought I could shove the majority of my game logic in the game mode and now I come to learn clients dont get access to it at all. server only..
Do I need to move all that logic out of game mode to somewhere or do I need to just figure out a way to call to the server from the client to access it?
I have every type of call to game mode in different parts of the code; interface calls, castings, getting and setting variables.
I assume this will be a grind to repair but I am curious what might be some short cuts? (like convert every cast to an interface or add an in between node to make calls out to game mode from a client.
definitely will take a look at it again
Is it good to buy course or understnad stuff from the base from yourself?
thank you all
im on it right now
Any tips greatly appreciated
Have you read eXi's intro to networking guide + Wizard cell's tips + tricks from the pin's in this channel?
How do I replicate random number in range?
you replicate variables, so you put the result of your random number into a variable
or you use seeds and replicate the seed before doing the random
Whats a seed?
look at random numbers from streams
but getting the random number on the server and replicating a variable is probably smarter
well using a stream or normal random and doing that, syncing the seed then using from stream would be fine as long as every action is synced
what doesnt work?
The random num gen it only gens on server
well it runs on the server, sets the variable, then the on rep runs for it
inside the on rep print out the random number and see what shows it printing. it should be all clients and servers
so what do you see printed out
Printing it 2 times
so what is this setup? listen server, dedicated server, how many clients?
Im playing as client I only have 2 screens its printing 2 times cuz I wanted to be sure.
Client num of players 2
so a dedicated server with 2 clients
Yeah
and what calls this code to run?
and what is bp_breaker? is it spawned in, is it in the level at start?
so im curious, since random num is exposed set it to something in the level and what does it show when your event runs
Ok
Give me a couple min im loading OBS then imma compress vid
I added a delay and made the num -1 every sec
cuz I forgot that part but that has nothing to do with my prob so that is of no use only reason im saying I did that is so you know I canged code a bit
so is the default for randomnum set to 6 then?
Yeah
ok so i want to know why server is firing twice
it should be server, client, client
Cuz im printing 2 times
Yeah and at tick
show the on rep code
no I mean that first interact shows serverx2 and both clients, which doesnt make sense
oh... didnt know you had another print..
what is changing your code down every second?
Wdym
you said you added a delay and are making the number -1 every second
what is calling that
Tick
I have a branch if Random num is <=0 then -1
with a delay of 1 sec
so its not instant
One changes color
because if your doing that on the client side, its going to overwrite any rep from the server
Oh?
well I mean if your not gating your code, which im guessing you arent, each isntance of the blueprint will run. one server, one client 1, one client 2
and then your server will update the number and try and rep it to the clients, but the clients will also be changing it (locally)
Yeah but even when I first gen the num it is not the same on client
which is why I was asking if anything is updating the number somewhere else thats not ran on the server
Uhhhh
you are multicasting?
you sohuldnt be multicasting that
Sorry I js names it that
yeah its just named that...
you probably want to break that habit early - cause its crazy confusing
and a sign of why we're having trouble helping here
Fair
Changed it
Lol
I usually dont do that but I wanted to fix this replication issue first
ok
and unhook your tick
the on rep is what you expect, just printing
this should get you the same result in both windows
we have to ignore the fact that there is a bug that prints all clients as Client 0... π¦
well then thats weird lol
Yeah lol
cant really mess this one up assuming thats the item in the level and uh.. its all hooked up
you could but that wont help fix this issue. maybe show the code now?
its possible the on rep is bugged, which is what I was testing with this
F9 on the blue node where you call the randomnumberonserver, see if it triggers a breakpoint
do blueprint interface functions or function library functions need to have some sort of replication setting? or is it best to just have them point to a server only / client only function?
well it lets us know the code is running
do the same thing on the set with notify, and remove the f9 from the first one
so now we know the code is running but is it running the RPC on the server
yep so it should print if your print code is good?
This is so weird
assuming you filled out the on rep lol
Wdym
well I mean you added the print string to the onrep_testnum function?
ππ
Fair
Its only showing server
Nvm
Now its showing nothing again
Greaaaatttt
change the print string duration to 10 seconds in the onrep
and then try again
see if it only every shows server: random number and never shows clients before it goes away
We back to only server
so only shows server for 10 seconds, which is enough time for the clients to show up on your screen?
Yeah
I set actor to replicate and now it both shows up
It replicates corectly now π
Is that it?
Alr
I should have checked that first but.. live and learn
it makes sense and since you had other code, outside the on rep, printing its why we saw the other values since it was the local things doing the printing and not the on rep from the server
hopefully it works now
It works π Thank you very much!!!
yeah so something important to learn from this I guess, your thingy needs to replicate if you want it to replicate across the network
if you didnt have the variable, it would have been fine but the variable wanted to replicate and your actor was like "Im not allowed to replicate, so you cant replicate either"
Yeah
How does one correctly handle Character's Launch Character node in a multiplayer context?
Say I'm doing a wall jump. Calling Launch Character when the player is the server works great, but doesn't work if the player is the client, unless I make a server RPC that then calls Launch Character on my behalf. I'm used to character movement being typically replicated on my behalf from the client, so this is new to me.
I'm assuming that doing something as timing-sensitive as a wall jump is probably best predicted on the client if there's sufficient latency, while also making the call to the server in parallel? I'm not entirely sure how to reason about this. Any tips?
looking through these compendium and maybe I missed it but does the level blueprint exist on clients as well? Im looking to move my game mode logic somewhere that client can call
the logic is tied to actors in the level but it is mostyl math and other backend logic
You shouldnβt be using the level blueprint regardless
No bp can communicate with it
This specific case could be different.
But, just trigger both.
Client -> launch -> ROS
Server -> launch
If they have the same exact data, they should end up at the same, or very similar spot, so no lag is felt.
Thats how input/ movement in general works, to have no direct latency, but also not allow the client to phase through walls.
Its just all wrapped up in a couple functions you call, for normal forward, back, left, right input
At its core thats how they work.
Client does input, then tells server to do input.
They compare locations, and undo/ forcefully adjust server side as needed
If client didn't do the input, and just told server to do it.
It'd work.
But, even a couple ms of latency would be aids.
I once made a custom camera system, but didn't replicate it properly (server did all the edits, client didn't do its own edit)
It was goofy.
Spin mouse.
0.1 second later, your camera moves.
Huh that actually works way better than I expected, thanks for that suggestion. I tried it even with these settings and it's pretty responsive on client-side, with the occasional rubber banding to some other location, but in theory it should be perfectly deterministic on both ends.
Glad that's handled for us already
TBF, thats just basic replication.
Server overrides client.
The movement component just is a bit more nice with it, within limits.
If I were going to play say a gunshot sound at the location of a clients PC, and wanted it to play on the server and all other clients, how would i achieve this? Multicast only works if it is the host client, and run on server only ever plays for the host client.
I feel like doing some weird rep-notify thing with a bool for play sound or something is not the best way to handle this.
Fair enough!
Have the server call a multicast event.
and, if your an owning client, then call to the server, then the server calls a multicast event
Oh good to know so then gamestate would be better for a controller to call that can also query a different client?
Does the size of the controller matter in the end? Iβm trying to obscure direct access of logic from a player (thinking about cheaters)
so I would need a seperate actor like an audio manager owned by server to handle playing the sounds for a client that is not the listen-server?
No?
Assuming this is some sort of gun.
have the holder of the gun call to server, then servers calls multicast
The server owns everything.
It can do whatever it wants, whenever it wants.
sorry could you elaborate on "call to server"? Should I check for authority and if actor has it it calls a run on server rpc and if its a server it calls a multicast rpc?
im a bit new to multiplayer
call to server
run on server
ROS
Whatever you wanna call it.
ahhh okay thank you
What's the most consistent way to implement a moving platform that players can stand on in a high latency case? Seems like the tradeoff is either have the platform jitter (implementation is based purely on the actor mesh movement replicating) or have the simulated proxies jitter from server corrections (implementation is deterministic with forward-ticking the platform to account for ping)
bServerAcceptClientAuthoritativePosition doesn't appear to help the latter case either
[saw some discussion about it here but looks like there wasn't any explicit solutions uncovered](#multiplayer message
)
Not sure about all that but GI might also be an option
Moving Platforms will always require based movement. Based Movement ensures that server and client only compare relative locations to the Platform and not world Location, cause the Platform will never be in the same place for server and client.
The only additional thing that you need to provide is smoothing of the platforms location on the Client, because just replicating movement will have it lag. And if it lags it will cause problems
Gotcha -- for the smoothing of platforms on client i think the forward-tick by ping amount should work (with some regular sync'ing there for jitter purposes).
Anything you can direct me to for using Based Movement on the platforms? I see some references to this in CMC w/ ReplicatedBasedMovement but not sure where to go for adding this to the platform
In theory this is automatically handled as long as both sides can resolve the platform
hmm. so basically when im setting up the platforms to be deterministic w/o movement replication, such that the client is forward-ticking by their ping, i still get issues from CMC network corrections.
but the platform itself is in sync now, and i know that because if i jump on the client its just a vertical jump up and down. but if i do this w/o the forward-tick to account for the lag, then when the client jumps they teleport to the side and back in midair, which makes sense since thats where the server character is
(this is all with like 150-200ms lag)
so this leads me to believe the issue lies on CMC, no longer the moving platforms themselves. but i could be totally wrong here...
ah ok after digging into this a bunch more i think i have a path forward -- smoothing of the platforms is handled by just having movement deterministic based on start time (no need to forward tick)
and then if i can somehow get the character to still be BasedMovement while its in midair after jumping off the platform, i think that resolves it -- perhaps just forcing based movement if the character is overlapping in a volume over the platform
On C++, is the only way to launch OnRep's on server is by calling it manually on the server? As I heard, there might be cases where the variable might not actually have been changed and ofc the manual call still will happen? Or is it actually how epic games recommends doing it?
Why do you need the "above platform" part?
Do you want the Platform Velocity to be taken into account when jumping?
--
Anyone here with NetworkPredictionPlugin and NetSerialize knowledge? I have some stuff I can't find anyone for to discuss with.
if the client jumps up and down on the platform while its moving, the server applies corrections while in midair because MovementBase becomes invalid
so in midair they teleport in one direction, and then land back where they were on the moving platform
In theory, OnRep is meant for Clients only, to be notified when the Variable replicated, and then optionally call if the value is the same.
If you have logic in there that should also call for the Server, then you'd call it manually in the Setter of your Variable. Given you know if it changed there, you can simply choose to not call it if the value is the same.
Hm, makes sense I guess, cause the RelativeLocation is based on a not-synced BasedLocation
open to better solutions though π
I have to figure out BasedMovement for Mover soon anyway, so I will face that problem too.
I always wondered how that is solved hm
Hello, i want to know how to logout a player who reach lobby after i reach maximum player in server, how can i do that in OnPostLogin with blueprint ?
Only Blueprints?
You could actually try to make UE already do that for you, even in Blueprints, without any "After joining" logic.,
Is the amount of players for the Lobby fixed from the point that the Server opens the Lobby with OpenLevel?
im too nervious to switch away from ACharacter right now so waiting for Mover to get fleshed out more π¬
But if i set variable on server function which launches the onrep on the client and after that, i just call the OnRep and it makes it just a normal function call, on the server only. So i just think should i try to prevent doing this or is it fine in this situation.
As i just think this would be the most simple way
yes
void AFooBar::GetLifetimeReplicatedProps::(TArray<...>& OutProps) const
{
Super::GetLifetimeReplicatedProps(OutProps);
/// Only calls OnRep on change (same as regular DOREPLIFETIME)
DOREPLIFETIME_CONDITION_NOTIFY(AFooBar, Bar, COND_None, REPNOTIFY_OnChanged);
/// Calls OnRep even if the Value doesn't change
DOREPLIFETIME_CONDITION_NOTIFY(AFooBar, Foo, COND_None, REPNOTIFY_Always);
}
void AFooBar::SetFoo(const int32 NewFoo)
{
if (!HasAuthority())
{
return;
}
if (Foo == NewFoo)
{
return;
}
const int32 OldFoo = Foo;
Foo = NewFoo;
OnRep_Foo(OldFoo);
}
void AFooBar::OnRep_Foo(const int32 PrevFoo)
{
/// Call on Server and Client only when changed
}
void AFooBar::SetBar(const int32 NewBar)
{
if (!HasAuthority())
{
return;
}
const int32 OldBar = Bar;
Bar = NewBar;
OnRep_Bar(OldBar );
}
void AFooBar::OnRep_Bar(const int32 PrevBar)
{
/// Call on Server and Client even if same Value
}
@fervent leaf
yes
That ignores the concept of Property Replication that says that only the latest update is ensured to arrive on the Client of course.
If the Server changes the value from 2 to 3 to 2 in a very short time (e.g. same frame), Client might not get that update at all.
Then try to pass ?MaxPlayers= with the OpenLevel command, in addition to the ?Listen param and specify the actual number behind the =.
You can use an Append Node to set the value to something dynamic in case the Player can choose the size.
UE should then already deny the connection automatically.
Please show me
I'm not so keen on shoving pictures of nodes into you. What are you struggling with?
You should 100% not touch Mover atm, if you don't have the ability to utterly rework NPP and Mover a lot.
Our Internal NPP version is so damn changed by now
I'm honestly annoyed at it.
fair enough, that's probably beyond my willingness to tinker with this stuff right now
Thanks, makes sense.
It's beyond mine too, but well
Is that true that GC "Reachability Analysis" is not done in gamethread in shipping builds? because I see huge spikes in my dedicated server not sure how can I profile shipping build
hmm i was testing a fix with overriding CMC::FindFloor but that didn't seem to entirely work. it does have some effect on the BasedMovement, but not entirely what i'm looking for
to make more concrete, that's the issue i'm trying to resolve -- server applies corrections as soon as client jumps in the air (and is no longer Based Movement), and then undo's those corrections upon landing back on the Movement Base
best lead i've got is temporarily enabling bIgnoreClientMovementErrorChecksAndCorrection on CMC while on the platform, but if you're on the platform long enough then there starts to become noticeable desync in position
The problem is that the Server and Client only align due to the RelativeLocation. You should also have a correction when initially landing on it, in theory.
At least that's what I have on Mover. Not sure how exactly that translates to CMC atm.
Somewhat assuming they didn't reinvent the wheel.
yeah ideally what i was trying to accomplish with custom CMC logic for FindFloor was to just not lose RelativeLocation while in air, and persist the BasedMovement. but that didn't pan out
seems overly complicated just to get this client-server sync on a moving platform argh
@compact plume
static float ClientAuthorityThresholdOnBaseChange = 0.f;
FAutoConsoleVariableRef CVarClientAuthorityThresholdOnBaseChange(
TEXT("p.ClientAuthorityThresholdOnBaseChange"),
ClientAuthorityThresholdOnBaseChange,
TEXT("When a pawn moves onto or off of a moving base, this can cause an abrupt correction. In these cases, trust the client up to this distance away from the server component location."),
ECVF_Default);
static float MaxFallingCorrectionLeash = 0.f;
FAutoConsoleVariableRef CVarMaxFallingCorrectionLeash(
TEXT("p.MaxFallingCorrectionLeash"),
MaxFallingCorrectionLeash,
TEXT("When airborne, some distance between the server and client locations may remain to avoid sudden corrections as clients jump from moving bases. This value is the maximum allowed distance."),
ECVF_Default);
/** Property to set if characters should stay based on objects while jumping */
UPROPERTY(Category = "Character Movement: Jumping / Falling", EditAnywhere, BlueprintReadWrite)
bool bStayBasedInAir = false;
/** Property used to set how high above base characters should stay based on objects while jumping if bStayBasedInAir is set */
UPROPERTY(Category = "Character Movement: Jumping / Falling", EditAnywhere, BlueprintReadWrite, meta = (editcondition = "bStayBasedInAir"))
float StayBasedInAirHeight = 1000.0f;
They do a lot of stuff to allow the Client to in the air for a bit before corrections come back
There is a lot of code in UCharacterMovementComponent::ServerMoveHandleClientError that handles this exact case before it actually compares Server and Client Location.
It seems to modify ServerLoc a lot to bend some rules for these corrections to not be that bad.
oooh these are super helpful, thanks!
looks like StayBasedInAirHeight might be what i want, but not seeing that in 5.3. might be new to 5.4?
I don't think it really resolves the issue over all. It just improves it.
Could be, yeah, the engine is 5.4 where I got that from
yeah well in the case i have where it applies the correction and then removes it, the client starts and ends on the base. so i think that actually does solve the case
its kinda similar to what i was trying to hack around earlier by having a volume / overlap box over the moving platform where CMC properties would get modified lol
I think the initial correction when landing on the platform causes the problem over all
If the Server tells the Client that the RelativeOffset to the Base is wrong and forces the Client to keep the same offset (so they are relative to the center of the platform on both sides), then when jumping off of the platform, it will have the wrong world location.
It almost feels like it would be simpler to increase the correction threshold on based movement
true, but that initial correction does keep the client + server position on the base itself in sync despite lag -- without that the relative offset would be different
i guess its a tradeoff of where we want the "desync" to happen
Yeah
yeah
only problem tho
if the desync happens, then a client might fall off platform while server char is still on it. or vice-versa
The problem is, let's say you walk off the platform. The edge of it will be different. But if the edge is the same, you get the correction anyway due to world being different.
not sure i follow
oh you're saying it'll correct as soon as the client starts falling off in midair?
that would probably be more visually jarring i think
Doesn't matter if the Base is ahead or behind
You kind only have these two cases. You are either keeping world align, and the relative is off, or you keep relative aligned and the world is off.
If you Jump in case 1, you won't get a correct.
If you Jump in case 2, you will get corrected to the correct world location.
ahh yeah
If you walk of the Edge in case 1 (the edge to the left in the screenshot), you'll get a correction in both cases.
Case 1: Server reaches the Edge first and starts falling, causing client to have a different base and be forced to falling.
Case 2: You both start falling but the client gets the corrected world location.
Now the CMC has these variables and stuff to allow the Client to be authority in specific cases, but I don't see the gain yet.
Let's assume Case 2 is what we are going with. If the Client jumps and remains Auth over its position offset during falling, as soon as they land they would be corrected.
And even with the code that allows some offset when landing, eventually sou need to sync them back.
And to get to Case 2, you need to correct the Client when landing on the Platform.
this may be overly optimistic, but if the variable allows some offset when landing on base, and the client-server relative location is intended to be synced but its within that difference, then walking off edge should minimize a partial amount of the distance
i guess as to "reduce" the correction distance
Yeah
although p.ClientAuthorityThresholdOnBaseChange 5000 in console is still causing corrections to happen lol
So can I ask - based upon your significant expertise with UE and multiplayer, and clearly you know the CMC inside out - have you realised any benefits of using Mover? Has it actually given you anything that you couldnt have achieved with CMC?
Sync between Mover and other Simulated Systems
as in GAS prediction - i.e. staminia?
or "other" simulated stuff?
lol
so having a weapon means having a GameplayTag to slow you down if aiming, and you use that for Mover?
For example, yeah. But also being able to fully rely on Locations, Aiming, etc.
and if you take an example of been shot causes you to "stun" for 0.2 second or something - Mover is able to handle that ok with prediction etc which is easier than with CMC?
Being shot and stunned will still be a correction
cause client will always be a few ms behind server to know it got shot?
Yeah, you can't predict other players
yep yep
confirmed the 2 stay based in air properties are introduced in 5.4 -- i think at bare minimum these will help reduce the overall number of corrections to just when entering/exiting the moving base
and i'll debug this more tomorrow -- 430am now, gotta sleep.
@thin stratus thanks for the discussion and help here, genuinely really appreciate it a lot!
No worries
Hi, it looks like GameplayTags from GameplayAbilitySystem take quiet a lot of bytes when replicating, has anyone noticed that and what are the opposite approaches of sending them? I get that GameplayTags are basically FName and FName is quiet heavy over a network, but I wonder what are the better approaches here? Like running GameplayCues or GameplayEffects, their tags are filling up packets. Or am I missing something?
If you pre-register GameplayTags in c++, it should be super efficient with FName bytes?
You mean pre-register with definitions like UE_DEFINE_GAMEPLAY_TAG_STATIC? Or what do you mean by pre-register?
Because all I do, is I make a tag in GameplayTags manager in editor, then in C++ define with UE_DEFINE_GAMEPLAY_TAG_STATIC and then pass it to GameplayCue or GameplayEffect executions (I assume this is the part that make these tags expensive, not BP GameplayEffects or GameplayCues).
Hard to figure out witch tags are the issue, either from UE_DEFINE_GAMEPLAY_TAG_STATIC or used ones in GE/GC BPs.
Iβm going to defer to one of the smarter people in this channel. I have some theories but I donβt want to spread false info. All I know is gameplay tags are considered super efficientβ¦
Are you sending them as individual tags or gameplay-tag-containers?
FGameplayTag are 12 bytes but can store essentially more values than you would ever want to have to type out. A similar type would be Enumerators which are 1 byte but can only manage 255 values which may not be enough and that means having to use multiple enumerators to represent the values you want, but now each flag is only 1 byte rather than 12.
If you were really concerned with network usage, you could use bits within a byte for flags, thus allowing you to use the full 8 bits of a byte each representing a unique flag. 12 Bytes could now represent 96 potential values instead of the 1 single one you'd get with an FGameplayTag or the 12 you'd get using Enumerators.
How to best handle it then? Still use GameplayTags in your normal logic, but when replicating things, you'd serialize them into bits before sending them over the network, and reconstruct the bits as GameplayTags on the other side, but I would only go down this path if it was something very network hungry like replicating stuff on every frame, otherwise it's probably a bit of a pain to have to set up and add more values as you need them, and it's trading CPU and a bit of RAM for bandwidth, but it is an optimization you can utilize. But here's the thing.... If you properly utilize FGameplayTagContainers, I can guarantee you that the engine is likely already doing something like this as Epic themselves use FGameplayTagContainers for almost everything in GAS.
I'm using a single FGameplayTag. Here one of the GameplayCue executions.
.h
UPROPERTY(EditDefaultsOnly, Category = "Gameplay Ability Damage")
FGameplayTag GameplayCueTagTargetCore;
.cpp
FGameplayEffectContextHandle Context;
for (const FActualHitResult& ActualHitResult : ActualHitResults) {
ActualHitResult.AbilitySystemComponent->ExecuteGameplayCue(GameplayCueTagTargetCore, Context);
}
From this optimization I don't think that my solution should take so much, probably just a poor implementation of GameplayCue execution or GameplayEffect execution.
But thanks a lot for detailed explenation of possible optimization, will keep this in mind. But first might need to try out FGameplayTagContainers, as you @glossy iron and @gilded vapor both mentioned it.
Used FGameplayTag not container because this function asks for it.
I'm manually executing GCs this way, so that I could have benefit of caching when they all executed in one frame. I'm doing similar thing for GEs.
I haven't used GAS in a while but aren't cues usually batched in with events
IE you generally don't manually replicate cues because another system replicates them for you
Hey guys!
I've started learning multiplayer recently, and I don't really get something.
I have the attached blueprint in my PlayerController. The behavior I'm not understanding is that the highlighted OnPosess and OnUnPosess events only get triggered on the server, not on the client. Is that correct behavior?
Any tips on how I can make this attaching-removing UI behavior work in that case?
I'll have to check, haven't really dived into it too much.
Most likely, initially I had these executions in GEs (when GE executed, it performs GC), but then caching was not properly utilized when there were 50+ GC executions in a single frame. But now I'm just trying to figure out all this GameplayTag thing in Network optimization.
ngl that sounds like you are trying to spawn wayyy to much vfx/sfx in a single frame. You'd probs want to batch some of those effects into a single cue
It happens when player hits many targets with one attack (like in ARPG scenario). For it to look responsive to a player all these effects are performed all at once in a single frame. Using caching & Niagara Data Channels it performed well. All that's left is to figure out Tag networking optimization in this case. But I'll have to look into alternatives, thanks!
Has anyone here rolled out custom motion in multiplayer without GMC? Climbing / sliding / creature movements etc?
i made my own completely custom network movement without using the CMC or Mover... it was not easy lol
well then let me ask you this good sir..
how would you handle interpolating MaxWalkSpeed based on velocity..
I already made some custom client prediction and custom SavedMove stuff.. and the sprinting part works great.. but my company, they want things to feel real organic.. they want it so when you run up to a cliff edge you gotta pull back on the controls to slow yourself down.. and everything I've implemented works great on the server.. but man.. the pullback jitters so hard.. I'm using GetVelocity.Size() to interp..
what else can I mess with in the CMC? lol
I've messed with all the network values and given them obscene values.. and it still jitters..
You wouldn't really use MaxWalkSpeed for that, but rather different Acceleration and Deceleration values in CalcVelocity.
that teaches you everything you need for what your asking
well I was originally using Acceleration.. but didn't really find any variable to tweak for deceleration
ho man, thanks for the tutorial link! will watch that in a bit
so I should override CalcVelocity, righteous
I just this week started doin the deep dive into overriding things in the CMC
so it's all pretty new.. kinda hard to believe I'm this many unreal years old before learning this stuff
so it sounds like you're thinkin its totally within the realm of possibility to be able to adjust acceleration and deceleration without having network jitters
As long as both server and client have the same info, yes
well.. soo.. I've been using GetVelocity to calculate things and interp my values... and GetVelocity probably will be different on the server and client a lot of times.. is there anything better I can use? like maybe some stuff in the move predict data?
I'm lookin at the source as we speak, just a lot to take in..
just so I understand this right.. the part of CalcVelocity that's assigning values to Velocity.. that's what's actually doing something to our movement, right?
This calculates the velocity that is later applied.
Not a clue if this is a dumb question, if I make an online game either for mobile or desktop, do I need to be adding security features in my game for players to not get hacked or is that something that either doesnt/cant happen or is it handled somehow by unreal?
ideally, id like a steam account/switch profile/apple game account/ etc to just connect to an entrypoint for things like rankings and then name and icon and nothing more.
uuuuhh should I be worried that my game is basically unplayable even with just Average emulation?
I dont think I could be doing anything much better than I currently am, theres nothing too bad, other than I guess replicating my players aiming value every frame because I have no idea how else to do that
I mean realistically, if I just make my game and set up multiplayer properly and everything using the steam system, then get it into steam, isnt there still a chance itll just be incredibly laggy out of my control? like what determines how well it will work beyond physical distance between clients
Yes
What's the problem?
Multiplayer is hard
Test with average or bad net conditions from day 1.
I think thereβs a way to factor in that difference, thereβs a great playlist Iβm watching about the CMC that touches on this discrepancy
https://youtube.com/playlist?list=PLXJlkahwiwPmeABEhjwIALvxRSZkzoQpk&si=LsZNtQSBsHQLgrI0
but even just jumping is broken. how could I have gone wrong there?
literally the only thing that isnt completely broken is just running around which is only because its default character movement. the second I use a dash or jump theres a huge teleport or delay, firing the weapon has at least half a second delay
and these are all one off things, just simple server to multicast events
nice! I watched the third video to get the SavedMove stuff in there.. I'll watch through the rest!
Not saying you need this plugin (itβs crazy expensive and itβs possible to handle with C++ though I donβt know how difficult yet) but wondering if youβre running into the same problems as this guy
Wishlist our game Spanky! https://store.steampowered.com/app/1732420/Spanky/
GMC: https://www.unrealengine.com/marketplace/en-US/product/general-movement-component?sessionInvalidated=true
Smooth Sync: https://www.unrealengine.com/marketplace/en-US/product/smooth-sync
In this video we address the topic of multiplayer games made with unreal engi...
yeah I saw this before, looks great but I do NOT have that kinda money lol
but I dont think basic movement mechanics should be falling apart on average emulation
Are they basic movement mechanics or are they custom movement mechanics?
The built in CMC movements should replicate and interpolate without crazy jitter
If you get into custom movement I think you have to dive into the C++ and extend the CMC or make an even more complex solution
yeah as I said the movement is fine but its my jump and dash (which are mostly just launch character)
How did you implement these (broadly speaking)?
it's very easy to implement this stuff wrong in a multiplayer context so it's not a surprise that it isn't working well if you haven't been testing the game with latency since day 1
its mainly just play montage + launch character (and some other movement component settings that need changing for the dash)
but again, what could I even be doing wrong. its just individual one off standard events
theres no way to know whats wrong without an example
but simply dashing the player with a server event is already bad because they will notice the latency
yeah I think I noticed that I had to have jumping on server as well as a non replicated event
Im perfectly happy with any way that I can let the player move freely then just have the server try to replicate it as best as possible on the other players ends. Im not really worried about cheating as this is co op but I think that will make enemies a problem
but uh yeah even this still has problems
realistically as someone who just cannot learn c++ or any form of coding beyond blueprints (believe me, Ive tried) and probably wont be getting any other help with this project, should I even be trying co op multiplayer? Im always so determined to try but it just doesnt seem doable
like even with how difficult it is to get working at all, as far as I knew Ive been doing everything right and its still unplayable anyway
also, steam p2p hosting definitely doesnt require paying for servers right? if theres no free option at all then I will know that I can just save myself the effort and quit working on mp right now (I know the steam page costs of course)
To be clear. Steam doesn't host. Steam matchmakes. And the only fee is having your game on Steam for the 100$. Or using the testing app code if you're not that far. There isn't a fee beyond that for using their session searching services.
yeah, thats what I was thinking, p2p player hosted servers using steam accounts
If I wanted to call a function from a server owned actor that would only run on a specific client how would I do that?
Run it on a ClientOwned Actor of that Client
Will help to know more specifically what are you trying to do / what obstacles youβre facing @tired current ?
Interact --> Server RPC --> Verify that it's good --> AddItem to inventory array which is replicated --> How to update the client Widget?
I need help with the last part, where I want to be able to update the client ui
OnRep on the inventory array then broadcast the change to the widget
Wouldn't that fire the function on all clients? (I only want the owning player, knowing that this code is in a component in the player character)
you can use DOREPLIFETIME_CONDITION and COND_OwnerOnly if you only want the owner to receive the replicated values
will the array still be replicated for everyone?
Which do you want owner only or everyone getting it lol.
I dont know anymore
people are telling me that the array shouldnt be replicated at all
it's multiplayer ye
so everything should be client only and when some do a trade, what happen?
No?
I mean you likely want your inventories to be on the server
The server keeps track of everyoneβs inventories
you can then tell clients what their inventories look like for UI
Everyone are telling me different stuff... That's confusing
and a listen server is still a server. You just have a server and a client on the same machine
wait so how would I onlky store an array of items for each player on the server?
that's already what I have
that's not on the server lol, all clients have their own array
so you are telling me it's already on the server?
So I would attach the inventory component to the game mode (where the server is the only one existing)
that's already what is happening
but it's there for everyone... (not server only)
I want to do what you are telling me but I dont fully understanding how I would replicate for the server only
Wait, I understand, the server would know everything in the world, the player couldn't unless they do a server RPC, since the array will not be replicated, I now need to find a way to use the RepNotify without replicating it fro all clients for the UI property..
I thought a repnotify meant that it's replicated
and that only fires on the owner?
That's so good
there's only 1 guy that should receive it
the guy that tried to pick up an item.. right
'the actor's owner'
ye
ofc, the player is client owned
I think what you're misunderstanding is that replicated actors and properties are basically copies from the server. When you have a replicated actor spawned on the server, the server tells the clients to spawn that actor on their end as well, and also tells them any replicated properties that the server has.
If you have an inventory, and you want players to know about what their inventory contains, you normally rely on the server to tell the clients that information, otherwise you're relying on clients to tell the server what is in the inventory which can lead to cheating. Like I can tell the server I picked up a +9999 Damage sword and equipped it and if the server just accepts that, then that's what'll happen.
by replicating the entire array, anyone can change the array and the server will also take that change as nothing happened?
No
Replication only happens from server to client.
Clients can change any data they want on their end, but unless the server changes it, the server is the actual source of the information.
You would need to first ask Server if you can change the array, if the change is in the scope (like dmg +99max) then it would work, but setting it to +9999 would be forbidden
but setting it to 98 would work?
No.......
Well it's just a example how you can set it up
You wouldn't even do that.
The most you could do, is maybe say, I'd like to equip what is in slot 5.
picking up an item? oh that's a request to the server asking to pick up the actor you're looking at, or the server detects the overlap.
since clients doesnt need to know about the array of other clients, it only replicates for the owner in my case...
"Replications for the owner" means that it exists on the server and would replicate to whoever is marked as the owner.
It still exists on the owning client and the server.
So if I need a data from a client to another, I need to go through the server, if I dont it will be default... ?
You can only communicate to other clients VIA the server.
If you don't then nothing goes to those clients as you didn't go through the server.
some told me to loop through all clients and that would work
You could if you were running on the server, sure.
Clients cannot send any communications to other clients directly.
There is literrally no connection or means to do so within Unreal's networking system.
UPROPERTY(ReplicatedUsing = InventoryArrayWidgetClientUpdate, EditAnywhere)
TArray<FItem> ItemsArray;
InventoryArrayWidgetClientUpdate will run only on the owning client, right?
Do you have it set up with the COND_OwnerOnly replication condition?
Or does the thing containing this inventory exist on something that isn't replicated to everyone (like the player controller)?
yes ofc
we just did it
Then yes, it should only execute on the owning client.
good, I was just making sure it wasn't autoritive
OnReps in C++ don't fire on the server automatically unlike in blueprints
And the OnRep only triggers if a replication was received, and COND_OwnerOnly would prevent the replication from going to anyone else.
okkk
thx a lot @normal fulcrum @sinful tree β€οΈ
is the best way to prototype an online game to host the server in your own pc? i plannned on using aws but im kinda scared of it cus i have No Budget at All and i dont wanna accidentally go over the free tier limit for gamelift
by server do you mean actual game server where players connect and play or server that stores information about player progression etc?
since rn im trying to just get player interactions to work, the former
then i guess it'll be fine to host on your computer
ight ty, i assume aws would be better for player data when i get to working on it later on, right?
never really used aws, but i guess its fine for both game server and data stuff
understood
this is my first time doing somethin like this so im kinda Full of questions
and i KNOW its usually bad to start with an online game but i work on a "if the motivation is halted due to an issue the project dies Immediately" mindset
yeah, you should keep your game server(s) and data server separate from each other
This is exactly why it's bad to start with a multiplayer game though. There's going to be a lot of issues in the project on a singleplayer game. Multiplayer is just going to turn that into a nightmare.
That said. Unless you need something special. Start with listenservers where players can host games as well and stick with Steam. There is a lot more info out there to work with.
if it helps what im trying to do is like
instead there being "lobbies" you can pick from, whenever the player enters a zone/level/area (whatever you wanna call it), they get put in a "room" of sorts with a limit of 8 players
idk how to explain it better, but its the best description i could think of
,, i guess
? im not very knowdledged in this stuff
your explanation actually reminds me of minecraft minigames, where people enter portals and play some kind of game mode
isn't it similiar?
yeah that's pretty much it i think
is the Velocity variable in the CharacterMovementComponent client predicted?
is this how I should handle item replication for players?
this is on a character that the player controller possess
I marked the InventoryItems array and other inventory related variables as replicated
do these need to be "run on server" instead of multicast
hmm
at the moment it's
client -> server
does it need to be client to server, server to multicast?
yes
hmm
but if thats a widget blueprint it wont exist on the server
nah it's on the character, controlled by a pc
Basically, I'd like for every player to know what each player has in their inventory
and for each player to be able to see each player's inventory functionlaity
functionality*
i dont think a client can call a multicast function directlybut i might be wrong
so for inventory related functions, if i want every player to look at every player's inventory functionalities (such as current slot selected, items in inventory, etc.) then I need to:
client -> event (execute on server) -> event (multicast)
since only server can multicast
this makes sense tbh
also keep in mind these rpcs wont be run on players who join late, if thats an issue
hgmm
so when the new player joins, I have to feed that player data
this might be an issue, maybe cause some lag
I'm essentially trying to create a lethal company prototype, if that helps
(the game isn't an exact copy of lethal company, but very similar lol)
hmm
I'll try client -> event (execute on server) -> event (multicast)
like players change materials on objects?
yes
it's not self-promo
I'll watch that if client -> event (execute on server) -> event (multicast) doesn't work
yeah dont worry this isn't, this is updated per player input
also
for some reason the player's rotation isn't replicated
like, the host can see other player rotations, but the client players cant see the host's rotation changes
ohh
well the character is
You don't want to multicast everything. Replicated variables are used to replicate stately things, like an inventory which is something that definitely has a state. You can multicast and it can appear to work, but that's not how the engine is designed. Multicast can be used for fire and forget events, like displaying a visual effect or playing a sound effect in response to something happening.
let me check pc
so should i multicast when player changes slot in their hotbar and a new item is there, show it
No
I see
That's something stateful.
so if the "CurrInventorySlotIndex" is replicated then itll be fine
like the int variable
Yes, and you'd set that variable as an "Rep w/ Notify" or "OnRep" which gives you a function that fires when a new value is received for that variable which you can then use to drive additional logic when that new value is received.
Depends on what you're wanting to do with the variable and who needs to receive it. For now, stick to None until you're more comfortable.
And none means there's no additional replication condition - it'll attempt to replicate to any clients who have the actor or component relevant.
Oh okay, then none should be fine
Pawn rotation is usually replicated under a function "Get Base Aim Rotation" but the default projects don't have anything utilizing it to make the character look around so to speak.
that makes sense
It is replicated, just not utilized by the anim BPs and such.
It's nothing with movement specifically, it's about where they're looking.... Like, if you open up the third person template and aim upwards to the sky, other players would still see you looking forward.
huh, it seems like only the host actions are replicated for the clients. for these two functions
this is on the character blueprint, controlled by the player controller
for some reason it seems to add to the inventory, other players can see, but when dropped it doesn't work the second time
Again, you don't want to multicast everything. Something being held by the player is likely something stateful, meaning you'd have the server actually handle what happens on its end and replicate the results to others
so only the On_Server part
Yes, otherwise you're basically having every client executing the code which isn't what you necessarily want.
so it's looping the code per player, yea that makes sense
Yep, send to server, server handles what is supposed to happen, (ie modify replicated variables, or spawn/destroy replicated actors). You then use OnReps to trigger any additional logic if necessary based on the new values.
changed it to this, the player host can pick up item and client players can see that, but client players can't pick up the items
What you have above looks replicated correctly now. What happens in these functions?
so item interact checks to see if the player is holding an item, if it is then the player interacts with the held item first. if not then it does nothing
add to inventory does this
What is "Curr Hit Object"?
curr hit object is set from a raycast, checked every tick
i know that's not the most optimal but yk
Ok so here's where it starts to get a bit off - you probably have that tick function firing on all instances of the game, and because this is a character, that means you're probably firing it for every character on every instance. It's not really necessary to do in that sense. You'd only need to maybe do it locally on the one client that is in control of that character rather than having all clients do these traces for all characters, right?
Like, you only really need to know what the locally controlled character is looking at, at any specific time.
are you talking about just for the CurrHitObject? so that variable doesn't need to be replicated?
I see
Like it can make sense to do that on tick for a locally controlled character as you may want to know what they're looking at so you can show an interact prompt for example.
makes sense because CurrHitObject is just what the player is lookingat
not what the player controls
So then that kind of needs to change what your code on the server does - as you'd prrobably still want the server to know what the player is looking at - and you have two options:
- Let the client tell the server what they are looking at (Done by adding an "Actor" input on your Server RPC) and then passing in the local "Curr Hit Object"
- Let the server run the same trace when attempting to perform that interaction, basically running the same logic for detection on the server.
Personally, I usually go with option 1 and then utilize the value passed in from the client.
yeah I already changed it to option 1
huh, the client player still can't add the item to the inventory, but it's clearly looking at it
and I mean, I have a function that pops up with a "E" icon to tell the player to pick it up
that shows for the client
Next problem is here... These look like widget blueprint calls. Widgets don't replicate, so you can't use them to replicate any data or reference them across the network.
Your inventory should be something that is an object that replicates data, like a component or even just placed on the character.
I've been meaning to research UI replication after fixing this
Your widgets then read from that object to represent what the data is saying about it.
so this will be "false" no matter what
Yes, except for the host since they have a local widget themselves
yeah that's fine
at the moment it basically duplicates the ui
like when the client looks at a pickupable object, it shows the E icon on the host too
That's because of your tick π
The tick is running on all clients on all characters.
I see
And if your trace is detecting something on all of them and you have it adding a widget when any of them detect it, then they'd all see it.
is locally controlled
are we all doing inventory systems lol?
yas
im trying to recreate lethal company's inventory system lol
almost there, just messes up for multiplayer
I wish... I'm currently in the process of designing a procedural galaxy generator
ohh that sounds cool
this GetLookAtObject is on event tick
i added in that condition
should I do the same for the inventory ui here?
No. Your UI needs to be driven by OnRep changes.
Right now it seems like your UI has the inventory data rather than having something replicated containing the inventory data.
I didnt even need to use IsLocallyControlled...
So you have a ref to the actor you want to pick up.
You can have a variable like "Slot1" which can contain an actor.
yeah
So if you had that variable set to Rep W/ Notify, you'd then get an OnRep whenever the value of that variable changes.
That OnRep you can then have the UI update (if locally controlled!)
Gamers, I'm having a problem making sure an "expose on spawn" variable is replicated. I have units that record their current location as a reference to a CurrentTile actor BP. I have it set to Instance Editable and Replicated without a condition
In game, the CurrentTile is set on the server but not the client. Making a new boolean variable with the same settings works fine. Is there something I'm missing to properly replicate a reference to an actor?
Oh the onrep event, gotcha
Just to make sure, is the actor itself replicated? (The reference one I mean, BP_Tile)
You may also want to use an OnRep to ensure that any startup logic that requires the reference actually can do it when the value is received.
so OnRep_CurrHitObject, do the UI logic in this function?
Why are you OnRepping the current hit object?
Unless, that's what you're wanting to use as your "Slot".
Should programmers be using Unreal's push model these days, or is Epic still working on it?
The BP_Tile was not replicated, thanks for that, I figured it'd be something easy. This somehow broke the whole game board, but at least it correctly replicates the tile lmao
So really, the OnRep that needs to happen is with your Inventory Items Array. When that array changes, then that should be a signal as to when something entered or has left the inventory.
Okay so I changed it to:
- CurrItemPickingUp, RepNotify actor set when a player presses E on the item they are looking at
- OnRepp_CurrItemPickingUp calls Add to Inventory
There is no need to OnRep what the client is looking at.
no no
You don't want clients adding items to their inventory if their inventory is replicated as the server should be replicating it.
it's only when the player presses E is it set to the currhitobject
CurrHitObject is not on rep
You don't need to onrep what they're picking up either.
?
Same thing - you don't need the clients to do anything with adding to the inventory.
The server adds it to the inventory, that triggers an OnRep.
Client can update their UI based on what is now in their inventory.
That sounds contradictory to something you said earlier, so now im confused
I don't use OnRep on the item I am adding to the inventory of a player?
OnReps are used to trigger logic, not to set replicated values on clients.
Client (I Want to Pick Up "Cash Register") > Server RPC (Actor: Cash Register) > Server Adds "Cash Register" actor to Inventory > OnRep Triggers > Client now knows "Cash Register" is in their inventory and can update their UI.
So I just need to de-couple the inventory data and inventory ui
at the moment it's in one function
Yes, UI should only be used to represent data. The actual data should be stored on something that replicates that your UI can read from.
I see people talking about it fairly frequently.
How should I get started making my game multiplayer?
I have, hopefully, followed decent code etiquette for like collisions damage events and whatnot. I just need a guide to spawn a second player and sync like the world. From videos on youtube, most of them are just saying to get some like eos integratiokn kit or some plugin but they say its recommended for those who dunno cpp at all. I do know c++, so what would you recommend I do?
Not relevant but is this from Darker Nodes?
nah it's Flat Nodes π
works on 5.4.2
can't get node graph assistent to work tho π¦
Is there a binary build for 5.4.2 or did you download it for 5.3 and migrate it to source?