#multiplayer
1 messages · Page 612 of 1
Player 1, the host, loses all controller input. So nothing happens at all for them. Just headset tracking
Maybe unrelated, but I had some similar issues when getting mouse position from host controller and it was being used on client for some reason. I ended up using owning client rpc to fix
@spice skiff well it is at least something I have not tried yet, so thanks
I believe part of the issue is happening because you're calling this spawn controllers RPC on BeginPlay of your WizPlayerPawn. When you're hosting as a listenserver, and you're the only one there, you wouldn't notice any problems, and that's because since you're the server + client, so it doesn't do anything different on your end.
Once another person joins the game, their begin play fires on the server and the client, so immediately, you have the client making an RPC request to do something on the server that the server would have already done.
Example: On my character BP below, in a listen server setup, if I run this with only the 1 client, I see 2 characters - My BP_Female_Hero_Character (the default pawn) and the one being spawned in the DoSomethingOnServer event of class ALS_Hero_Character.
If I have 2 clients, you would expect that I should have 4 characters showing, but I end up seeing 5 characters. The two 2 Default Pawns of BP_Female_Hero_character, and 3 of ALS_Hero_Character, and that's because the server's version of the second player already called DoSomethingOnServer, and then their client version once it spawned on their end calls DoSomethingOnServer and Spawns yet another one.
I have checked spawn counts, there are 2 pawns and 4 hands as there should be for both the client and the host. But they could be spawning at the wrong time or in the wrong way somehow
@celest sleet https://vreue4.com/
Use Mord's plugin and example templates and multiplayer should work just fine for you without all of this headache.
if this works as it says it does, this plugin may be precisely what I needed, thank you so much
Hey all, I have an issue.
At the beginning of my game, the game-mode selects a connected player at random and changes a vector parameter on one of their materials to a different colour.
The colour uses a repnotify when it's changed, and subsequently changes its colour to all the other clients. That much is replicated, even the server sees that the colour has been changed.
But if the game mode picks the listen-server player at random, the listen-server player does not see their color change - however all the clients do.
I'm trying to figure out how to replicate that colour change to the server. As I said, all the other clients see the change... and if a client's colour is changed, the server sees it. The server only doesn't see the change in itself.
Any ideas?
@odd sundial Are you using C++?
I am
Repnotifys are not called by default on server in C++. You have to call them manually for the server machine.
void ASpy::RepNotify_ChangeEyeGlowColour()
{
UMaterialInstanceDynamic* DynamicMat = GetMesh()->CreateDynamicMaterialInstance(0);
DynamicMat->SetVectorParameterValue("EyeGlow", SpyGlowColor);
//change on server
if (Role < ROLE_Authority)
{
Server_ChangeSpyGlowingEyesEmissiveColour(SpyGlowColor);
}
}```
So I tried to get around that by calling a server rpc from the rep notify
The server function does the same thing as above... but obviously doesn't execute
I mean when you change the color. You can't just set it and let the repnotify run like on a client or in blueprint. You have to
RepNotify_ChangeMyColor();```
It does
I know it's not shown but...
It does it elsewhere 😛
(from the game mode)
I'm not sure then. The logic flow should just be, Select new color, Set replicated variable as new color, call Repnotify manually on server. And that should affect the instance on all machines.
Thanks for taking a look! Appreciate it. I'm going to look it over a few more times before I hit the hay and sleep on it....
Appreciate your help!
Does it work if you change it twice?
The repnotify for the server could somehow be out of order?
Ah. I missed that earlier. I think it might be the server check?
What do you mean?
For checking if the actor is running on it's authority you can use
if (HasAuthority())
Which is actually
GetLocalRole() == ROLE_Authority
Let me switch it up, thanks for taking another look for me
I tend towards Kismet's IsServer a lot if I'm checking if it's on the server specifically. Using a few client spawned actors and since those have authority on the client, it simplifies it a little.
I didn't even know kismet had that functionality, that's helpful
UKismetSystemLibrary::IsServer()
Just checks the net mode of the world and makes sure it does not equal NM_Client
void ASpy::RepNotify_ChangeEyeGlowColour()
{
UMaterialInstanceDynamic* DynamicMat = GetMesh()->CreateDynamicMaterialInstance(0);
DynamicMat->SetVectorParameterValue("EyeGlow", SpyGlowColor);
//change on server
if (HasAuthority())
{
SpyGlowColor = FLinearColor::Red;
Server_ChangeSpyGlowingEyesEmissiveColour(SpyGlowColor);
}
}
Here's where the code stands now, attempting to make some of the changes you suggested. I actually a bit less functionality now as the listen-server doesn't see the colour change in anyone now, instead of just not seeing it on itself
Out of curiosity, what does your server function do differently to the server instance than the clients? The one you're calling behind the authority check.
Generally speaking stuff like this should be the same for all instances without server code inside of the notify. Value gets changed on the server and then all machines including server run the same code to update their own instance in the same way.
void ASpy::Server_ChangeSpyGlowingEyesEmissiveColour_Implementation(FLinearColor NewColor)
{
SpyGlowColor = FLinearColor::Red;
UMaterialInstanceDynamic* DynamicMat = GetMesh()->CreateDynamicMaterialInstance(0);
DynamicMat->SetVectorParameterValue("EyeGlow", SpyGlowColor);
}
Just to be clear from what you said before...
UPROPERTY(Replicated, ReplicatedUsing = RepNotify_ChangeEyeGlowColour, BlueprintReadWrite)
FLinearColor SpyGlowColor;
I change this on the gamemode:
When that variable is changed on the gamemode.... the function RepNotify_ChangeEyeGlowColour is called automatically without additional instruction - correct?
Only on clients once that variable's new setting is replicated. It won't call automatically for server.
Okay, so the client issue is fine because the changed glow colour shows up for all clients, no matter, reliably at this point. However the server is the only one that does not see any changes.
First, comment out your whole if statement in the RepNotify, just leave the first two lines in the notify for creating the material and setting the parameter.
OK
I assume you have a reference to the instance of ASpy you're calling the set color on, like ASpyRef->SpyGlowColor = NewColor; ?
Yes, in the gamemode. The gamemode makes an array of all the spy characters in the map, choose a random one and sets the new color (the variable using the repnotify)
Okay, go to where you're setting the color and the next line after the color set, do ASpyRef->RepNotify_ChangeEyeGlowColour();
Alrighty
See if that works as intended.
Same result
No change at all for the server machine?
Correct
void ASpy::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ASpy, SpyGlowColor);
}
UPROPERTY(ReplicatedUsing = RepNotify_ChangeEyeGlowColour, BlueprintReadWrite)
FLinearColor SpyGlowColor;
Unfortunately this funny enough isn't even a replication issue, since the replication is working fine and the machine without the replication isn't.. I wonder though.
Can you put a UKismetSystemLibrary::PrintString(this, "RepNotifyFunction"); in the RepNotify and see if it prints a Server: log to screen or if they're all client prints.
YEP
Cause it's either running on server and getting updated elsewhere, or for some reason never running.
It's only being called on the clients, no server printstrings
Even though you're calling it manually right after the color set? O.o
Looks like it gets called three times, all from clients, when I'm playing with 4 players in total (one of which is the listen server)
To be clear it's being called in the game mode during the BeginPlay() after a 10 second delay
And just to be clear, I'm calling the repnotify from the gamemode using BP's, I'll post a screenshot of it
You may be getting different instances there.
Definitely is.
???
You usually want to cache a value from a random node. Each time a BlueprintPure function is ran, it'll generate a new return value, so your RandomInteger is changing values.
Huh... alrighty why don't I go ahead and make that change
had no idea that was even a thing
I'm not even sure why random functions aren't just BlueprintCallable rather than BlueprintPure.
Okay well... first test it worked 😛
Huh. Okay. So random nodes. Cache the value. Good to know...
Or just use C++ :p
Wow... yeah it seems to be working now.
Yeah, any time a blueprintcallable function runs, it'll rerun any blueprintpure functions that it's getting input values from.
Jesus christ... wow. What a mess.
On a side note, it might be better to create a function in your ASpy like "ChangeEyeColor" and have that take in the color, and set the replicated variable and call the notify, and whatnot.
I'll definitely clean it up and go pure C++
THANK YOU
what a nightmare lol
something so.... simple...
Haha. Been there. Glad you got it sorted though.
Wowwww hahah good lord I can sleep now
Thank you VERY much, what a huge lesson to have learned. Thanks again. That's awesome.
@bitter oriole Good morning, I'm not using seamless yet because I didn't want to have to manually simulate the start of a round/match. As all of that happens on its own in non-seamless. It would be great if I can use seamless but without persisting the player controller and state
What do you mean simulate the start ?
if the PC/PS classes are not the same in lobby/game levels
they will get reinstantiated
and only thing you'll persist is what you manually copy during PS' CopyProperties override
as for start of a match, adequate first iteration is overriding AGameMode::ReadyToStartMatch to return true if NumTravellingPlayers == 0
@gusty slate
They are the same classes as it is a chain of rounds
I'll have a look though Zlo thanks
controller shouldn't hold any states in a game designed like that
just some backend trackers
so persisting it or not, wouldn't matter
What I mean by simulate the start, is basically simulate the normal flow of joining a session
I can do it, just that before I do that, I wanted to check if I can do it non seamlessly
you can manually reinstantiate or reset the PlayerState
seamless is, except for the complexity of code involved to fine tune it, superior in every way
True yes, the map load when I tried was super quick as well
What wouldn't work?
connecting via steam sockets would break
if you toss in some hard travel
and with steam, sockets are the only reliable way to get NAT punchthrough working
or at least, were last i checked
Interesting, thanks for the info
although I just noticed that you suggested the gamemode, which is server only so it wouldn't help with smoothing it out
honestly though
I'm like trying to solve what seamless already does
x)
GameMode is in full control over seamless
So, I'll just use seamless and properly setup the flow
it usually won't work out of the box, you'll need to override a few functions, probably without calling Super
but its not that complicated
Yeah, just the hassle of setting it up
seamless does give you excellent control over your level startup
Does the transition map matter much?
a little bit
its gamemode does need to persist the Actors you want to persist
you can't for example, decide to, say, persist a custom actor, then leave the travel maps game mode to be AGameMode
best to have the same gamemode there as in lobby, if you have one
or in case of sequence of matches, it would have same GM as combat levels
its not visible
and it won't call HandleSeamlessTravelPlayer
so it won't attempt to spawn Pawns or anything
I see
And is there a trigger/callback to notify when the new map has finished loading?
the departing PC upon loading map
calls NotifyLoadedWorld (locally)
then ServerNotifyLoadedWorld (Server RPC)
if the host/server has loaded the map by this time
it will call HandleSeamlessTravelPlayer, which leads to HandleStartingNewPlayer, which spawns the Pawn
if the server didn't load yet
it will call PostSeamlessTravel (GameMode) when it does
which will call HandleStartingNewPlayer for all PCs it has
HandleSeamlessTravelPlayer is where the PC/PS are reinstantiated, if not the same class
Alrighty, thanks a lot Zlo, amazing help 👍
Hmm, seeing that HandleStartingNewPlayer doesn't trigger for the host PC, would handling that PC on PostSeamlessTravel be a good decision?
it triggers
Yes my bad, it was just me checking the wrong logs 🤦♂️
In seamless travel, the PC would stay the same instance or a new instance is created with the same values?
Would references in the PC for UI for example still hold in a seamless travel?
your PC should have zero UI references
thats what the HUD is for
only exception to that is for widgets that have lifetimes outside the scope of a HUD object
like Menus and LoadingScreens
that should be managed by GI, a GI subsystem or something similar
I know what you mean, as the PC isn't only local so having references there for only local objects isn't really the ideal place, which is what the HUD is for
but x) omitting that, may I have the answer if you have it? Do references for local objects not relevant to the level stick?
off the top of my head, not sure, i don't have the same PC class on both ends of seamless travel
put a breakpoint in HandleSeamlessTravelPlayer
and see for yourself
if the controller isn't reinstantated, which im pretty sure it isn't
I use server travel while inside a session and it doesn't seem to work in PIE
references to all objects that are still valid will be valid
you can attach a debugger to the standalone
you can build a source engine, package the game with the source engine and run the packaged version with full engine symbols from VS
(as long as its not shipping)
That is way too much for simple testing tbh, I will just print the value of the reference and check from that. But thanks for the help
just attaching the VS via Debug-AttachToProcess while you're running standalone unpackaged is fine for this
you won't be able to see everything, but you'll be able to see enough
I know but as far as I know that only works for c++ breakpoints, no?
my project isn't fully in c++
the function you need to breakpoint is in c++ and not overrideable from BP
the reference is in BP
so thats hardly a problem
and that's what I need to check
just put a variable of same type/name in your c++ controller base
I'll just print it, it's fine 🙂
and replace all Variable_0s with Variable
in BP afterwards
which you can do just by dropping the Variable into broken Variable_0
but you can still see if new controller is instantiated or not
which answers your question
I mean the printed controller name is different which I would assume means a different instance
which is odd because it is the same class
Hello! I have a problem with the ReplicationDriver:
I'm in a "listen-server" world and the ReplicationDriver works fine, but when I call Seamless Servertravel it gives me that error:
[2021.01.26-10.17.13:018][415]LogNet: ReplicationDriverClass is null! Not using ReplicationDriver.
and the ReplicationDriver isn't working anymore. How can I fix that?
you trying to seamless travel yourself from a non ?listen level to a ?listen one?
uhhh, so I'm really nooby, but I set up a dedicated server which works as it should, and the last thing my project had compiled as Solution Configurations was "Development Server".
now, if I make just the smallest change in the code and compile it, it takes hours to get done compiling.
If I change the Solution Configurations to "Development Editor" I get compiler errors... any help?
?listen to ?listen
The interesting thing is that in my NetDriver InitBase doesn't even get called after a ServerTravel. However, CreateReplicationDriver is called. CreateReplicationDriver has its only reference in InitBase. That would mean that the UE specifically calls something in the UNetDriver instead of in my class.
your error at least implies that the provided ReplicationDriverClass is null, and so it failed to instantiate it
dunno, find the log, breakpoint it and work your way backwards from there
Is using listen servers on mobile phones a bad idea for performance?
@steel fox not sure that is even possible
due to actually connecting to other phones
Found it. It is because of the DemoNetDriver. My DemoNetDriver start after the seamless travel. That makes sense, but should the DemoNetDriver really have a ReplicationDriver? I mean then I have two ReplicationDriver. One for my NetDriver and one for my DemoNetDriver.
You can use a Phone as a ListenServer. The problem is just handling the Session stuff. Cause you can't just search and find Steam sessions or so.
Trying to make spectator for my multiplayer game
what am i doing wrong
when i use get player controller all player posses to spectator pawn
is there any other option to get controller
i dont know why this dont work=
Possess can only be run on server. That's what that little symbol means as well.
oo
The spawn of the spectator actor should also only be done on the server.
Hey guys, I've build small tool that speeds up compiling proto files into destination language, https://github.com/avdept/Protobuf-GUI-Compiler. Right now supports Go/C++/Ruby. Should simplify workflow
in a FPS game, whats the right way to keep the NumBulletInClip in sync with server. currently its Replicated and OwnerOnly.
I decrease the NumBullet when player fires locally, server changes it as well. so sometimes the older value (higher number) is replicated and overrides the local and because of that my gun fires more bullet than it has in its clip.
I didn't think of it, till today cause high fire rate and ping showed that.
It should be going not from local client but from remote. Otherwise client can cheat with simple memory changes
Use RPC to call some doShot() which then replicates to clients
For a multiplayer game, when clients are still loading in, what's considered best practice to blank out the client's screen until things are finished loading?
If you need it to replicate, GameState sounds most reasonable
@rose egret i override PreReplicate on the server, and i have a bool which forces the server to replicate the ammo when i set bRequiresLocalAmmoUpdate
this bool is handled by the condition that the weapon GA is not active. Whilst its active that bool is false, and does not replicate back to client, unless server rejects a bullet.
GameState for things that need to replicate, GameInstance for things that don't. IIRC GameInstance is persistent throughout the entire life time of the game. You can store difficulty there as well and put it on GameState if you need other players to see it.
Subtitles seems like more of a user setting thing to me
Hmm, if it's a permanent setting that persists when you close/reopen the game then definitely game user settings
@meager spade sounds a good idea. but where is that PreReplicate ? r u using GAS ? cause I am using my built in system that sucks. 🙂
I came up with this code but still doesn't work.
void ADezCharacterAlpha::OnRep_AmmoCount(uint8 pre)
{
if (CurArmState == EDezArmState::Fire)
{
// the replicated value is higher than the local one ? then dont change the local value.
if (AmmoCount > pre)
AmmoCount = pre;
}
}
its a function on Actor you can override
I finally answered my own question through throwing stuff at the wall and something stuck. PostInitializeComponents is the place you'd wanna turn your camera off so you don't see junk loading in.
{
Super::PreReplication(ChangedPropertyTracker);
bool bCanReplicateAmmo = false;
if (UKaosAbilitySystemComponent* ASC = GetPawnASC())
{
bCanReplicateAmmo = !ASC->IsAbilityActive(PrimaryAbilitySpecHandle) && !ASC->IsAbilityActive(SecondaryAbilitySpecHandle);
}
DOREPLIFETIME_ACTIVE_OVERRIDE(AKaosWeapon, AmmoCount, bCanReplicateAmmo || bUpdateLocalAmmoCount);
if (bUpdateLocalAmmoCount)
{
bUpdateLocalAmmoCount = false;
}
}```
server just needs to know the weapon is firing and not firing
when you stop firing, server can just rep the ammo it has back to client
@meager spade is it ok to call DOREPLIFETIME_ACTIVE_OVERRIDE on a COND_OwnerOnly property I don't remember it well . cause if I change it to COND_Custom it will be replicated to anyone.
yes
Has anyone else tried to get MoveIt and Able Ability system to play nice together?
maybe ask the MoveIt discord and maybe ask the Able creator
if I am setting up a dedicated server...how do I package the game without all the other assets...I mean its just the console
and if the dedicated server is controlling the game mode etc..then how does it work between the client and server? is it the same? Do I make a gamemodeserver and gamemode for client..or do I just have the one mode and do the server stuff normally
you need to package stuff
you can disable certain things from cooking in the disabled in dedicated server cook list
an no you do not have special game modes for server
Okay I didn't think so. Just wanted clarification
well, technically, all game modes are special for server 😄
I really need someone to work on the multiplayer aspect of my game. It makes me anxious to continue developing something and not have it properly setup..or easily moved over to multiplayer
considering your question in #cpp just now
you're probably biting a bit more then you can chew atm
Ive got nothing but time
still i recommend a learning project
if that is the game you have in mind
you're almost certainly going to restart from scratch at one point
but accounting for multiplayer structure at this point will just impede you from learning other stuff you need to learn
need to keep frustration at manageable levels, and starting with unreal networking is nothing but
I literally have hours to devote a day everyday to learning anything I need to learn. Problem is any information I find is sort of a mixed bag of arbitrary concepts
that is not likely to change, most tutorials are terrible
^
I can recommend a tutorial, wont solve your problems like a miracle in one day but I guess it will boost your learning phase, since its more of a "proof of concept" style tutorial
I'll take anything
Ah ya this guy
This stuff I can do
But I mean again this is all just basic foundational stuff
I need a real understanding
go deeper
Yeah sorry I didnt read the above
then read the engine code
over and over
everyone here with in-depth knowledge of networking got there the same way
1 - working with it
2 - reading engine code
this discord channel is closest you'll find to a comprehensive documentation, i think
its just a little bit unorganized, and stretches back years
Using search bar with keywords is working btw
I always end up useful things, from 2016-2018
and non useful stuff from me 😄
how can i change hud when player died and changed to spectator pawn
and when he respawned
after 10 seconds
Thats my hud blueprint
I'm using this method to spawn a character and possess it with an AI controller to replicate click to move. The issue I have is that when my character moves a certain distance in one direction, it moves out of relevancy and bad things happen. How can I attach the player controller to one of these actors?
How much packet lag is good to account for in a P2P game?
Currently I'm trying to get my game smooth at as much as 1000ms (I know that may be overkill)
ideally you should test at all varying packet lag values as well as packet loss values
also, make sure that the range is big enough to allow out-of-order arrivals
How do you increase the number of public connections in a session in 4.25+?
I thought it was just the following
PartyGame->GameSession->UpdateSessionJoinability(PartySessionName,
OutSettings.bPublicSearchable, OutSettings.bAllowInvites,
OutSettings.bJoinViaPresence, OutSettings.bJoinViaPresenceFriendsOnly);
SessionSettings->NumPublicConnections += DesiredNumSpectators;
SessionInt->UpdateSession(PartySessionName, *SessionSettings, true);
Which I did and worked fine in 4.24, but in 4.25 it seems to set the number of open public connections to the new number as well... which isn't right
This seems to work
Thats a solid 10 hours I'll never get back for something so simple
Is there a way to enable the debug camera client side?
yo yo anyone fimilar with scene capture 2d yanno like a sniper scope however for multiplayer, right now all clients see one persons scope im trying to find a way to create the matiral at begin play per each person..
You have to do something like this.
In your material, you need to make a texture parameter named "TextureTarget" as well.
Hey ppl, need an idea. I want to Spawn an Actor locally so it shows up instantly to the spawning client. But I want that same Actor to be spawned to everyone else BUT the owning client.
How would you achieve such a milestone?
are you talking about having the client spawn a predicted version of something and then everyone else seeing the "real" version of the same thing?
Pretty much, @vivid seal
you need to override IsNetRelevantFor on the projectile
and return false if viewer is the owner
projectile/actor/w/e
I guess IsNetRelevantFor is not exposed to Blueprints?
no
Gotcha. Thanks.
so in building my ability system i'm doing client prediction on a bunch of different things: resource costs, cast bar, global cooldown, visual effects of an ability, and the ability's cooldown.
i'm having trouble deciding whether to rely on RepNotify for each of these different states to rollback or confirm predictions, or to just have the server send an RPC confirming an ability use with all of these things included and adjust from there. the RPC is simpler to think about for me, but it could lead to issues where variables might replicate before the RPC leading to some weird predictions of state that never actually existed. the RepNotifies are more accurate for rollback but require me to add CastID as part of everything that can be predicted to facilitate rollback
do you guys not using GAS typically depend on replicated variables for each individual part of an ability, or do you just send a Client RPC confirming an ability cast and go from there?
It depends. In my situation, I don't care about cheating, meaning I first run a given ability on the client and if its validation succeeds (meaning, the client has the capacity to afford for that given ability), then I just call a dumb RPC transmitting it to the server which broadcasts to everyone else - without extra validation.
im doing additional validation on the server, so it is possible that an ability that the client used wont actually succeed in happening on the server
But I mean, that's always complicated. I personally don't like replicated variables because it seems way too obscure for me. I oftentimes get to that point of seeing something occurring and not understanding why - in the end, a given variable was set to replicate and boom, that's where my misery dwells.
lmao
That's why you want to rollback, right?
yeah and i understand the basics, like i need to store the last replicated state from the server separate from the displayed value on the client, factoring in any predictions that the server's state hasn't taken into account, then clearing out any predictions that the server has already included in its state
just wondering in this case where basically 5 different things are doing this but all tied to ability usage
i can make it work either way i think but both ways make me get a little bit of anxiety in the back of my mind about whether its really the "right" way to do things
and wont come back to bite me later lol
I guess this is a software development curse? Unless you're the mind behind GAS, you won't always be 100% confident of what you're doing, lol.
In my case, I "recreated" GAS using blueprints only and I'm pretty sure 90% of the things I'm doing are wrong, but you know, #yolo
yeah i have no formal education in software so i've just been slowly plodding along teaching myself stuff for about a year. i get that feeling constantly
I guess that's pretty much standard. I'm into Unreal Engine since 2014 and still have that feeling every day, even at the most basic stuff. As a personal advice, don't push yourself too hard. In the end, something an ex-boss of mine said, "an issue it's only an issue once it's an issue", lol.
But GAS specifically is tricky AF. That's why I'm postponing it. Not having control on what's going on under the hood gives me anxiety as well.
I know, right? Question - now, about GAS - does your game require it?
i'm basically trying to make GAS but simpler for my game
i dont think i need a lot of what it does
and i'd rather know exactly how the system works even it isn't as good
That's why I chose to skip it.
The thing that I hate the most that gives me fatigue is being stuck b/c I don't have a plain diagnose of what the issue is.
But I personally think if the eyes are fooled believing that things are working, then everything's alright lmao
Although 80% of the time I'm in a situation like this:
Besides, prediction is and always will be hard.
yeah
multiplayer in general everyone said was really hard and not to start with it, but i figured "it cant be THAT hard" right and here i am a year later with literally not even the combat system for my game completed
I feel you, my friend, I feel you lol. That's why I'm tired of over-engineering. 100% of my over-engineered projects were never shipped so 🤷♂️
But I believe multiplayer isn't hard. I believe MAKING IT 100% RIGHT is.
we're looking into GAS at the moment, I think my main concern is with it potentially resulting in a lot of overengineered stuff
Specially for us, mere mortals without endless budgets and the brilliant minds to cover us up.
@meager spade so this approach with projectiles is basically like spawning a fake projectile for the owner? And everyone else gets a replicated version? Would it be wise to tear off the projectile On_Rep as well to stop paying attention to it on each client to reserve bandwidth if it's going a constant direction/velocity or should the refresh rate be set to 0 and do a single force net update? Or... should you simply RPC to each client and make fake projectiles for them too?
We had this pet project that was released on Steam. It was going well. Then we started scaling it and were like 'oh, lets use GAS to handle all the mechanics and multiplayer repliaction for us'. We got stuck for 2 weeks. Then we gave up and moved on. Too much. Also, https://bravenewgeek.com/abstraction-considered-harmful/.
I don't think it overabstracts
You are right. It doesn't. I still have to implement my abilities and stuff by hand. But what it abstracts always seemed way too obscure to us. If something goes wrong, who can help us?
Same happened to us.
I'm pretty sure if you get the hang of it, it can be powerful and unleash your inner productivity. But until there, we felt it was a long road ahead.
Ive taken a quick look at GAS for my side project and it certainly has a learning curve
If you were in a studio setting you would want to use it across multiple projects just so that the time cost of having people learn it and only use it once wouldnt be a waste.
Because i could certainly see that if you didnt need (or want) to utilize it to its full potential, it could cost more to learn and implement than the end result could be via other means
Yep, agreed.
for fast-firing weapons how do you guys typically handle aiming? do you have the client send his aim with each shot? or just have him send what he thinks he hit
I've heard client authoritative shots with sanity checks for hacking on the server from a lot of people.
that's what we ended up doing, doing full serverside with lag comp is pretty complicated
though aiming is different from firing
i've heard that a few times, does anyone have an example of what a sanity check actually looks like without doing any rewinding of hitboxes? is it just "was the thing he hit within line of sight within the last x amount of time?"
If you send a timestamp the server could simply reject hits that have to much variance.
You could then bias it to accept the client 50% of the time if its outside the range minimally or something 🤷♂️ come up with anything you think might make sense
The problem of sending a timestamp, from my perspective, is that it is exploitable.
Actually... are we talking about projectile firing or linetrace firing?
trace
Yea those are two very different things. A projectile would be much easier to check.
You would just check distance of projectile from actual hit location on the server when u do the same sim and if it's within an acceptable range you accept it.
Line tracing... I don't know.
Well, your server knows everyone's position. At the moment the information your shot has arrived, get the instigator's location/rotation (plus the potential target) and do some math you judge would suffice as a sanity check.
There's no right/wrong answer - it all depends on what you're pursuing.
Yea that's a good point. Do the same sim on the server when the client calls hit to it and do a line trace to see if it varies deeply from the line trace sent for hit
Send up the line trace used to do the hit on client and do a comparison to the line trace for hit from the server.
If it varies too much, then don't count it.
I know this is not what you're asking for - but watch out, this might be quite expensive and lag would be easily noticeable depending on how stressed the network is. That said, make sure you give a good feedback to your client.
Lag is almost impossible to avoid, you can only do so much before shit gets weird.
that's why all our damage fx like blood are server authoritative
Yeah
That's why worrying with experience is important to me.
To me, no anti-cheating technique is capable of justifying bad experience. If your gunplay is bad, you won't sell.
I'd be that worried if I were like CS:GO or something but well lol
This is my life drama. I mean, we're doing something like Borderlands where the damage is displayed.
Oh god how hard it was to get it right - experience wise.
well we don't have hitmarkers or damage numbers, so the hit reactions and the FX is your damage confirmation
Is there any good resource for learning how to compress variables for networking? I dont know why/when I need to use it, just want to learn for curiosity
Well, I think I'd start researching for data types.
But as a rule of thumb, byte, enum, int, and the list goes on...
There's also this 👉 https://docs.unrealengine.com/en-US/InteractiveExperiences/Networking/Actors/ReplicationPerformance/index.html
Some tips for optimizing the performance and bandwidth usage of Actor replication.
is there a functional difference between checking for the autonomous proxy role and checking if a pawn is locally controlled?
i guess locally controlled would return true for the server
nvm answered myself
would anyone know why I get massiva rubberbanding when using extended cmc and I change directions like forward to rihgt/
or at least where that is controlled
Extended CMC...
Hmm
Well, there might have one thousand reasons here, specially if it's an extended CMC.
Does it work with non-extended CMC?
Yop. Not enough info to really help
@peak sentinel In short, when to use it highly depends. Compression is an extra step and means rewriting your RPCs or Replicated values and uncompressing them on clients when using them.
The simplest examples of this might be how FRotator does it. As you may know, FRotator is just three floats. Each float is 4 bytes, so a rotator is about 12 bytes of data total. But what if you never use roll?, and what if you don't care about perfect precision, just relative? You can compress a rotator down from 12 bytes to 2 if you don't need roll.
This can be done via turning a three float rotator into another struct that is just two bytes. You turn your rotators axis values into 0-255 values, and populate your two byte struct with the pitch and yaw from that, and then send that struct through your RPCs or Replication. It's worth noting that this is okay in some situations, for instance, pitch on a remote client doesn't really need anything more than 180 degrees total since it represents -90 to 90, and usually it's facing doesn't need to be perfect, so you get off easy with a byte. Since that's 256 angle points with 0.70 degree increments It works out okay for most aim offsets.
Depending on your game, this can be okay for Yaw as well, but some might want a bit extra precision for that. A 4 byte float is still overkill since you can use a short(uint16) which is 2 bytes. This can represent 65536 angles at 0.00549 increments between them. Which is more than enough precision for representing the directional facing of a character in most circumstances.
Even with a byte for pitch and a short for yaw, you're only at 3 bytes vs 12. So 75% bandwidth decrease for that value that likely gets replicated at minimum of 30 times a second. This kind of optimization should be done when you send that value very often. That or if you're planning on using a hosting service that will be cheaper based on bandwidth, then you pretty much want to compress everything to save money. But in general for prototyping, you can just do stuff normally and not worry about it. Make your stuff work first, then go back in with profilers and see what is your largest drains. It's pretty easy to define some new structs and redo functions with the compression in place once it's already working well. Since all you really need to do is change your function arguments and do an uncompress at the beginning of the function in a lot of cases.
Currently if players want to connect and play with each other the server has to have their 7777 port forwarded, the client side has to know the public IPv4 address of the host to join the game.
What I want instead is this:
The host doesn't have to have port-forwarding enabled
when the host creates a session, the public IP address should populate a public server list
the client can then join the server without having to know the IP address.
Constraints:
I want this to stay P2P as much as it can. I'm sure that I need to have a dedicated server running to populate the public server list but I hope that's all it has to do.
How would one go about this? I am looking for a super crude and affordable approach to this. Links to GitHub repos are appreciated too.
Oh yeah, the game doesn't have to keep persistent state and is entirely session based.
@kindred widget less unorthodox way to compress a rotator if you don't need roll is to turn it into FVector_NetQuantizeNormal (6 bytes)
and it will keep full precision
plus, all you need to do is convert the rotator to vector and back again
True, I was more just pointing out general compression ideology. Specially since I believe that FRotator is already compressed by default when used over network?
It's not
But there are some places where it's manually compressed, like replicated movement, and when characters send their control rotation to the server
What would be the safest way to reduce movement speed when moving backwards or strafing while moving backwards? Currently I'm simply clamping the input axis value the client uses to add movement input
In CMC? Override GetMaxSpeed
return different values depending on characters heading vs velocity direction
That's odd. What makes the rotator unwind on RPC or replication then? For instance if you pass a rotator with a yaw of 500.f through network, it sends it as 140. I just assumed that was some form of auto compression.
Ignore me, turns out it is compressed to uint16 on each axis by default.. that's news to me
But in multiplayer doesn't lag cause the max speed to be different on client and server causing minimal stutter?
If the MaxSpeed is deterministic then it wouldn't make a difference
And it would be if the max speed is based on the current rotation and velocity
Yeah but current rotation and velocity isn't always same on client and server because of the lag during direction changes etc
It'll always be the same
But I'll test if I can get something like that working well enough
Just make sure you are using the capsules direction, not the meshes
If you use the mesh then yes, the results would be very different
Okay
I suppose you could use the "Acceleration" property to make it more resilient, in case you have something else changing the characters velocity relative to it's rotation outside of the main movement simulation
We already are using the player ping to adjust the speed changes to reduce stutter
I'd bet that's causing more problems than it solves
It is not
Why would you change player speed based on ping? That makes no sense
I didn't way we change the speed based on ping
We adjust the delay it takes for the server to respond to the speed change
Keeping it better in sync with what the client wants
If you''re changing the max speed over time, then the change to max speed has to be done as part of the movement simulation. If you're doing it outside of the simulation, then you will always get stutter and corrections
If you had a max speed that interpolated over time, then the interpolation has to be done with the delta time of the movement
Where is the delta time of the movement?
It's provided as part of all the physics functions within character movement
The client tells the server what delta time to simulate moves wih, with each packet
The Server doesn't move the client at all between packets
The idea being that all movements are always simulated with the same delta time, regardless of what framerate each is running at
If you change some parameters that affect movement, but outside of the movement simulation (such as in characters' tick function), then it'll never work properly. That's usually the #1 cause of jittery movement - it's just because the parameters aren't being adjusted in step with the movement physics
Okay. Is there some ready onrep function that is a good place to do the adjustment?
That's not what I mean - what I mean is any changes you make to movement parameters, have to be done as part of the character movement physics simulation
You can't for example, change max speed during the owning characters' tick
Where can I change it then?
The physics has to be 100% deterministic to avoid jitter and repeated corrections
You could do it inside PhysWalking() for example
Do you happen to know any example code/project that has over time speed adjustment done?
I don't tbh
But generally you just want anything that changes the parameters of the movement sim, to also be updated in step with the sim
Not 100% sure, but I have a similar problem, partially fixed it by increasing tickrate on server, checked that all components are replicating. This fixed partially stuttering but I am still having stuttering on platforms moving , rotating
still trying to find myself more indept explanation on the character movements , positioning in network 🙂 since TPS default movement is great start however that jittering and stuttering in different scenarios id love to understand and fix 😄
That's probably because of animations
hi, im working on a multiplayer shooter and was wondering if anyone can help me with my problem. when i play singleplayer (host game & play solo) i don't have any performance issues, but when multiple people are in a lobby every player (host & clients) get a massive fps drop (like i get 120 fps playing solo and 50 fps with lag spikes of 20 fps when playing online). i can't seem to find the reason why there is a performance issue when playing online
@twin juniper please don't cross-post, and job posts belong in the jobs channels
@chrome bay they posted that in a lot of channels
I understand game mode only run on server, but what if i want to initialize settings for client from GaemMode but i don't want it to be replicated (just initializing it), e.g. time of the day so timer run on client side only.
or am i supposed to send all those information into GameState and each Blueprint on BeginPlay have to check information on GameState and update the owning client
now I'm thinking about, yeah that's not GameMode job to initialize variables that are not replicated.
please correct me if i'm wrong
Well time of day should be synched right?
so GameMode will have to tell clients the current TimeOfDay
yeah, i thought to optimize it by just telling client from what time to start, and then client can calculate the time on their side
which makes sense
GameState can hold this value
and set its replication to COND_InitialOnly
so it replicates once only
then client can handle it locally
server can keep it up to date, so when next player joins, they get the latest value
i see... yeah, sweet
OnRep_TimeOfDay can setup the timeofday manager
thanks for the help
Anyone here has guide for Dedicated Servers?
Hello everyone, I come here after hitting my head with a wall for hours now.
I have a UTask class which inherits from UObject. I've managed to make it replicate with a variable "UTask* Task" in PlayerState using IsSupportedForNetworking and ReplicateSubobject. However, it seems I can't make it work for "TArray<UTask*> Tasks". It just replicates with all NULLs.
Hey guys, steam is failing to initialize in some clients
has any 1 seen that before?
ive made sure steam is running
and turned firewall off aswell
@fast nebula whats your test case? OnRep_Array?
I'm reading the values in OnRep_Task if that's what you mean
thing is when you replicate an Array of UTask pointers
the array and the Task objects have to replicate for the array not to be empty or full of nullprs
i assume the same actor is replicating Tasks that has the array as a member?
btw you can only run one client per machine if you're using Steam.
What's the error? Have you logged into Steam on all the clients?
the log only says it sails to initialize
they were all loged into steam
LogSteamShared: Warning: SteamAPI failed to initialize, conditions not met.
LogOnline: Warning: STEAM: Steamworks: SteamUtils() failed!
LogOnline: Warning: STEAM: Steamworks: SteamUser() failed!
LogOnline: Warning: STEAM: Steamworks: SteamFriends() failed!
LogOnline: Warning: STEAM: Steamworks: SteamRemoteStorage() failed!
LogOnline: Warning: STEAM: Steamworks: SteamUserStats() failed!
LogOnline: Warning: STEAM: Steamworks: SteamMatchmakingServers() failed!
LogOnline: Warning: STEAM: Steamworks: SteamApps() failed!
LogOnline: Warning: STEAM: Steamworks: SteamNetworking() failed!
LogOnline: Warning: STEAM: Steamworks: SteamMatchmaking() failed!
I believe this:
Channel->ReplicateSubobjectList(Tasks, *Bunch, RepFlags)
is what is replicating the individual UTask
and the array is populated like Tasks.Add(NewObject<UTask>(this)) basically
did you search the source for the 'conditions not met' message?
There's a link in the source code: https://partner.steamgames.com/doc/sdk/api#initialization_and_shutdown
the question was is the array using the same actor channel as the task objects?
yes
have you added steam_appid.txt ?
so your array replicates before the tasks to
and its not a race condition, its deterministic in this case
will take a look now, i tried adding the txt but its the same, also its suposed to work when u package the game not in shipping mode
that would make sense, but I've got no idea how to make that work... will the OnRep be called after the pointers replicate?
you can verify by putting breakpoints in OnRep_Tasks and AActor::OnSubobjectCreatedFromReplication
ah i think i know what it is
very likely cure for your problem is just move the Super call in ReplicateSubobjects to the end of the function
Ensure that you own a license for the App ID on the currently active Steam account. Your game must show up in your Steam library.
i have to give them keys i assume
i was runnign the 480 application which doesnt need it
ah ok
are they your developers? or external qa or something?
might be better to grant them access via User rather than key
(which would cause the subobjects to replicate before the Actor's own members)
I'll check the breakpoints and invert the calls and see what happens
If it works I may just cry xD
it will work
fyi there is a more complex, but far more reliable container for subobjects, FFastArraySerializer
its documented in NetSerialization.h
and its capable of individual callback for add/removed/change
where is that done?
if its item has a pointer to a replicated uobject, and the pointer is null at the time add callback is fired
it will still fire changed as soon as the object's NetGUID is resolved
I did see something like that but I couldn't find it anywhere. I'll look into it later as well
personally I'd create a Group for this access level, give just the minimum access rights, and add new users to that group.
easy to manage then
i saw that but i am under the impresion that is used for a broader acess
Visibility Only access right just provides access to download and run the game
meh, i will just do keys its easier haha
might be easier now... 😉
true
but still, i am the sole woner of the game and i work with freelancers and rely on friends for testing it wouldnt make much sense
fair enough, key makes sense for external testers
users, groups etc is more useful when you have an Organisation registered with Steam and potentially multiple projects, users with different access per project etc
Is there a way to force the physics tickrate to be 60 hz on the client?
If clients change their settings to have different fps caps (i.e. 144 fps) then it causes the client and server simulations to be off slightly and cause small desyncs
Hm, I don't know the answer to that one. But I do know that actual physics simulation (excluding Chaos and what it could do) in UE4 shouldn't be network synced.
It's not build to be deterministic
for cli auth physics driven the best you can do is using substepping
and replicate back transforms, the only thing... you'll need to create a simple anti-cheat system
yeah we have server authority, but client prediction
so ideally the physics are deterministic
sounds like that might not be a real possibility though
Ouch
Ouch (x2)
Yeah I mean if you have something not controlled by clients that should replicate their physics stuff, you can hack some stuff together
But Player Input Controlled Physics, Network Synced in UE4?
Good luck ):
maybe I can just force the character movement component to tick at 60 hz regardless of framerate and that'll help
Given you want to be able to save the moves the player does and replay them if a correction comes in from the server, you will soon notice that you would need to save the WHOLE physics scene to make sure that you replay it properly
It's not really possible ):
well good thing is my characters are the only thing with networking/physics
I must ask though: why does it have to be actual physics vs faked vector math?
I made a fully functional hovercraft like pawn that was working just fine, based on vectors and adjusting rotation and location via the CMC.
Fully supported by prediction and what not
probably a large portion of it can, and I believe some of it is done that way in character movement component's code
so changing the CMC's tickrate might solve most of my problems
Hm okay
Not sure you can guarantee any of that though. That's what we use DeltaTime for
You can have someone play on a really shitty PC after all
The only thing you might have control over is your custom hosted dedicated servers
I guess I just set a cap on delta time then to 16 ms or something
if they have a trash computer, then they can deal with some miniscule server corrections
That won't make it tick more often though
but I don't want people to be punished for having a higher FPS
But sure, try it
Point is that if you only use vector math and acceleration/velocity etc. you wouldn't have those issues, because then it basically works like the character already does
right makes sense
And you can easily re-play moves etc. even use UE4's record stuff
So if you still have the option, try that
from digging through UCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iterations), it looks like it's almost all vector math driven purely by the deltatime in the CMC/saved move
Is there a way for me to have both client when testing in multiplayer to have normal framerate? The client that I'm on is always on the normal fps of 60, but the clients that isn't focused on has 1 fps.
https://gyazo.com/3a3999698ae387af264b77f8d73dbcf0
Yeah there's an option in the drop down next to Play in editor button
@silent valley can you help me find it? also im testing using Standalone if it helps with my case
Yop, they actually don't process a lot of code if you enable Physics on the character
and I don't have 2 computers to test each client
@teal sundial Edit -> Editor preferences -> general -> performance -> "Use less CPU when in background" turn that off
found it, I will give it a try

It did not fix my problem playing with Standalone :S
How can I pass data from one map to another? I have players join a server through an external matchmaking service and then select a character and loadout in a smaller level, then I want to move the server to the map for the match. How can I send their selections over to the new map so that they all get started with the necessary Pawn class and PlayerState info?
iirc Game Instance seems to transfer over maps
it doesn't destroy on loading other maps
So I would store that info on the GameInstance and then pull from it when the players join the new map? As far as I remember, the GameInstance isn't replicated over the network so what class's BeginPlay function would I pull that data from? Or would it be a run-on-client RPC function on the GameMode? I'm super unfamiliar Unreal Networking so sorry if that's a silly question.
You could start the server in the load-out map, then use Seamless travel to move server and clients to the new map. You can configure seamless travel to keep certain objects between maps.
This way pawns etc can persist.
An overview of how travelling works in multiplayer.
PlayerController will persist by default so you could store config on there for each player
Somewhat depends how you spawn your pawn - might make sense to keep it on GameMode for the server.
@unkempt wing
you could use the PlayerState, and utilize CopyProperties..
PlayerController does not persist
different maps can use different PC's
PS has copy properties
according to the docs for seamless travel they do persist, but your method sounds easier
we seamless travel and we change controllers
we do have different controller classes, so they have to be reinstantiated
but i think they would get reinstantiated even if they were the same, i just don't remember anymore
breakpoint HandleSeamlessTravelPlayer and check if interested
hello, anyone aware of any simple backend for turn based game, self hosted, kinda like nakama but more lightweight?
Can there be crazy lag when u are testing multiplayer on the same machine? like the virtual multiplayer in the editor?
only if you added it yourself
theoretical question for you guys. So say i'm making a game the scale of diablo 2 where the mobs(ai actors) are spawned in on server generation and are persistent throughout. What's the best way to approach this so that it doesn't lag the everloving hell out of everyone
i know there's built in network culling but is that enough? And will visual occlusion handle the gpu calls side of things?
they need to be dormant and completely disabled (tick, movement, BTs, everything)
until they are close enough to be relevant
so a world ontick event checking each AI in proximity to a player for instance?
why OnTick
well idk
yeah well i meant it that way. i wouldn't be calling it every single frame
but yeah like on a short timer
how would you turn an ai actor dormant though? You would disable it's controller but is that enough?
it doesn't even have to have a controller until it becomes active
it will just be standing still, off camera
you mean you just spawn actor on world generation but then don't give it a controller?
yeah they're ran on the server onyl
only*
ok but an actor without a controller still has animbp etc so you litteraly have to change the defaults to be absolutely nothing and only assign those when a condition is met yeah?
it can just keep idle pose
or play idle animation, doens't really matter
not off camera
ok because that's just gonna affect gpu calls only if it's on camera. gotcha ok
so long story short remove controller if ai is out of range
Hello, i got a problem. I cand find my session, when i try to create a session by passing engine default sesion name (NAME_GameSession) . But if i use othe name, like "Session" - it finds it (but doesnt update player amount) what do i do wrong with this NAME_SessionName
If youre making a top down rpg, where would it be best to store character stats like health, energy, agility, int and strength etc?
with multiplayer
depends, camera doesn't necessarily affect that
Pawn is a good place, as they are atomic to the Pawn really
and you can always pull the data for the UI via its PlayerState
Are there going to be conflicts if i put it in the base character blueprint?
wdym by conflicts?
just for simplicitys sake when players get replicated
considering separating attributes/stats and the mechanisms that affect it into an actor component might not be a bad idea
Okay so it might be my thinking thats incorrect but when you spawn in character so to say and its my char, other people doesnt get my character replicated as their own or does every player get their own character with separate stats and etc? if you know what im meaning
every player gets their own
the playercontroller is the thing that's not replicated
a pawn is just an object on the server, think of the player controller as the actual player. He's marionetting a pawn
and a character is a subclass of a pawn
okay thank you for the help
If anyone is making a joinable lobby then loading the game map afterwards, make sure your lobby game mode is not using seamless travel. It will mess up everything.
Out of curiosity, does anyone knows if a development server could accept shipping clients?
depends
if you didn't configure the version, no
UE default implementation will detect a version mismatch
Okay good to know!
That's wrong.
You must use seamleas travel for e.g. Steam
And it's generally adviced to utilize seamless travel when server traveling
If it messes stuff up it's because you aren't handling it properly
My game has 2 play areas (Spaceship and Land). They are somewhat analogous to Diablo's Town and Dungeon. I'm trying to architect my setup in such a way to be robust and responsive to the player state changes. I'm thinking the flow should be like:
- Player triggers transition
- Gamemode moves the character and sets bIsOnShip on its PlayerState.
- Repnotify for bIsOnShip handles the relevent logic
That sound about right?
You prolly want a more modular method of keeping track of state. (At least an enum)
I am not server traveling to my lobby, i am just joining the lobby session and server traveling to other levels once everyone has joined the lobby.
Ya if I ever have more than 2 states representing that dimension then I will.
What would the design be for an Interactable component, to have the actor implement bool CanInteract() for it?
REPNOTIFY_OnChanged
vs
REPNOTIFY_Always
I thought that it was always "on changed"
so is it literally replicating the variable constantly?
whenever its set
even if its not changed
x = 0;
x = 0;
will replicate 0, again?
good
oh wow there's only two conditions lol
/**
* Struct containing various parameters that can be passed to DOREPLIFETIME_WITH_PARAMS to control
* how variables are replicated.
*/
struct ENGINE_API FDoRepLifetimeParams
{
/** Replication Condition. The property will only be replicated to connections where this condition is met. */
ELifetimeCondition Condition = COND_None;
/**
* RepNotify Condition. The property will only trigger a RepNotify if this condition is met, and has been
* properly set up to handle RepNotifies.
*/
ELifetimeRepNotifyCondition RepNotifyCondition = REPNOTIFY_OnChanged;
/** Whether or not this property uses Push Model. See PushModel.h */
bool bIsPushBased = false;
};```
IsPushBased lol
* Note: While the theoretical gains for Push Model are good, in practice the gains seen haven't been as good as expected.
* More work may be needed in order to optimize comparisons, and have other systems buy in / use Push Model in order
* to increase gains.```
HMMM
If I add into an Animation Montage, special effects in there, does it show in multiplayer?
they don't replicate by default
so you need to either multicast them, play via a replicated property or play them on functions that get called on all clients
@meager spade what kind of game are you making?
The Red Solstice 2
no 😄
Are you using 200 CMCs in Red Solstice 2? Didnt see that much enemies in the trailer
Lol the company was founded in crotia tho
FCharacterNetworkMoveData I see you 👀
i've been at this for like a week now:
trying to get a World of Warcraft style channeled cast bar to replicate correctly with client prediction. I've given up on predicting the length of the cast bar (since i'd have to replicate every spell's cast time modifiers as well as global cast time modifiers or update every single spell's individual cast time any time any global cast time modifiers are calculated on the server) and just have the player start casting with an empty cast bar until the server acks the cast. however I can not come up with a good system for handling cancellation of a cast in progress (like if i want to cast a different ability, or I press escape to cancel the cast) with prediction and reconciling the server's cast state with predicted cancellations, new cast starts, etc.
on top of that, I don't know how to handle the "ticks" of a channel. originally the server was just going to call the tick event every time the correct fraction of the overall cast timer had finished (so for a 1 second cast with 5 ticks, it would just call the tick event every .2 sec), and clients would do the same based off the server's replication of the cast state. However, if ticks of a cast need their own predicted parameters (for instance, if my cast ticks every .1 second and deals hitscan damage, I would need the player's hit result every tick of the cast for use on the server and other clients for display purposes) then I am in a weird situation of possibly getting tick information late if any lag occurs, so I think maybe these "ticks" should also be requested by the player and not just automatically done by the server.
lastly, a cast can end by being interrupted, being cancelled, or by completing. Each of these has the chance for additional functionality (for instance, being interrupted could deal damage, but manually cancelling a cast obviously wouldnt), but I don't know how to replicate which of these happened when the casting state changes to NotCasting for clients.
as an example of what i'm talking about, how would you replicate the Mind Flay spell from shadow priests in WoW with client prediction/rollback. Thats a spell that is channeled for 3(?) seconds, but while channeling, every .5 seconds it deals damage and costs resource. Players can cancel the cast midway with no downside. If they are interrupted, they are locked out of shadow spells.
I know. On that ServerTravel from Lobby to other Maps is supposed to be Seamless
@thin stratus Yes the mistake I made is making the lobby seamless.
Goodday guys for the guys who have worked with playfab before is it possible to use host migration for a registered game ??
@vivid seal why aren't you using GAS?
Mostly to try and learn how it all works from the ground up
But also I was pretty far into my combat system before I knew GAS existed
World of Warcraft doesn't predict abilities I'm pretty certain
It does not. It predicts GCD and puts you in a “predicting cast” state so you can’t spam the spell
I am trying to make that style of cast work with prediction though
if you want to have a manegeable library that can handle abilities, take a lot at splash damage abilities plugin
there is a fork in piperift/
I will make an overhaul on it over time, but current version is okay
My suggestion, first of all get your time synced properly.
If this works, you can send the time from the client, when you have requested the spell and take this into account on server side (with some validation of course)
Well and then you have a prediction on client side and you can start your channel and when the server acknowledge the skill you can go on.
there are side implications on that
depending on the precision that you want you might need a better synced clock
the best you have in vanila ue4 is GS ServerClock
that is bad, I updated the GameState to sync UTC time
best thing you could do is implementing NTP
UTC isn't a suitable network clock either
ntp clock
You're just retrieving the time from the OS, there's no guarantee either machine is operating the same way. Bouncing RPC's from Client->Server->Client is the best way and tracking times
yep thats exactly part of the principles of a right ntp clock
well I use the UTC time from the server, send it to the client and do the diff to the local time
otherwise unbounce will kill you
if you use that delta to adjust your clock might be okay
The method we employ in SAS is based on delta adjustment
atm its close enough, and more precise than the default system.^^ but true, it still can be improved for sure
still, it depends on the precision you look after
I don't care for a small diff, its more to have buffs etc predicted close enough
that's something we gotta work on in SAS
in SAS buffs aren't predicted
only abilities
predicted = have UI blend them out correctly
yeah
- state affectors client side to have direct responsiveness... although -> rollbacks
but it depends tho... in overwatch you can notice rollbacks all the time if you play with bad ping
my buffs are replicated via a map of effects. the UI just gathers what was replicated and does some animation to blend out. if you have lagg you most likely will notice that, right now we don't have real prediction / reconcilation, its more like send a request to the server to ask for a skill and have the server accept or reject that.
Actually to learn^^ Started the project before I was in the industry and wanted to owe my skills. Now I still want to get better, so I keep improving on my system.
and I didn't like cooldown to be a buff xD
sweet :)
but be honest, did you start doing it because of the scale of GAS? (ie: too bulky)
actually I did it because I didn't want to have cooldowns as buffs xD
Dont suppose anyone can give me some advice how to start debugging this 😄
https://youtu.be/UOwinZ7ZWo0
https://youtu.be/_mLFiabqZmg
I tested my network movement with 2 clients and 1 server and 1 client.
Server sees everything fluently like he should , but the clients just dont see things as they should 😦 like that jittering movement
The platform itself is not replicating properly? It appears out of sync.
Anyone know how I can net serialize a float that has a certain range for extra precision within that range?
The jittering on downward movement
replication is set on players and platform
on platform
and player
just jumping on the platform while its going down seems to be causing lot of jittering on clients
same when it moves left to right
The character will be ahead of the server because it's predicted. The platform will be behind the server because it's replicated
where do you see that 😮 my eyes are sore atm 😄
I don't see it I just know that's the case
Essentially the client and server are out of sync when it comes to the platforms. Getting characters standing on moving objects and it not looking terrible is probably one of the most difficult things in MP
ya i can imagine 😄
i take it this is why im some games that are fast moving with mounts or vehicles there is that rubber band effect
totally. vehicles are even more fun because then you have physics engines involved
🙂
dont suppose you would have any suggestion that i could try to smooth this out? Since the platforms wont be more complex than moveing left to right , up and down 😄
Would I be right in assuming that GameMode is server only and GameState is on all clients?
Okay. I got a problem I posted in blueprint chat, the thing works if done on GameMode (though as expected, only for the host) but it doesn't work at all on GameState.
I'm trying to get a countdown timer to replicate and its just... not.
@mighty tiger I don't sorry, you need to sort of make each characters movement relative to the platform it's standing on, then also make sure those platforms stay syncronised. quite a complex problem
@sharp kestrel What is the timer? A timestamp or just a decrementing integer or something?
Decrementing Integer.
Though I've just done this in GameState and it doesn't print either.
Unless Unreal is lying about the Gamestate being set, I'm not sure what's going on.
Sounds like the gamemode you're using isn't using that gamestate
@mighty tiger I'm doing something like this right now for general physics objects
its ok 🙂 you gave me something to think about. I did see a Udemy MP course, they had a moving platform in it. I might download the project and see if they had any replication issues
It's not fun :P But I expect it to work once I'm done with it, I can elaborate if you ever feel like you wana power through it
sure 🙂
this JP MP test is just a intro, atm im a standard TDM game 🙂 so it wont really need moving platforms but i wanted to see if making a jump level would be fun
😄
so many multiplayer games usually have static worlds because of this type of problems 
yea i figured after i read Jambax comment
makes sense why back in the day it was so funny to try and implement things like this in quake 2 mods or even half life 😄 and it always sucking and never realized why
Oh what half life games/mods did you try at?
we made small mods just a group of 5 friends 🙂 never published em, but we made a clone of CS that was on an airplane and one with a hot airballoon 😄
and i recall when the balloon or airplane was in motion the game just bugged out like mad 😄
yes 
Apparently my issue was due to using a gamestate and gamemodebase and they are incompatible.
._.
Ah yeah, makes sense
its why its worth checking the output log, it did scream at you about that
Screaming back at your log is always a good development strategy
also just unrealted to previous question 😄 looked at Smart Poly dedicated server browser video 😄 but idk how to transmit the server name, playercount ping data to my clients server browser xD is there any more detailed guides out there for the browser setup 🙂
I believe... maybe mordentral has something regarding the matter
yeah
thank you very much 🙂
🙂
If you want to overengineer it, you could keep the state of the 3x3 board in the GameState, replicated (e.g. an Array with 9 entries) and have the "rules" in the GameMode.
So if you make a move as a Player you perform a ServerRPC in e.g. the PlayerController saying "I want to put an X on location 5." and then the ServerSide of the PC tells that to the GameMode.
The GameMode gets the current board state from the GameState, checks the rules and either updates the board or not.
You could also leave it in the GameState entirely. Maybe you want to check localy too before even sending the RPC, then you could place that logic into the GameState.
But you'll need the RPC to actually change the board anyway
Anyone know the easiest way for a Server to send a message to all clients without using AActor?
It is for my automated tests, and I have a World which all the clients are connected to, can I send a message using that somehow?
Can anyone give me the words I need to search for? 🙂
Maybe a FNetControlMessage...
Fairly sure you have to make engine changes to use FNetControlMessage
That's a much more low-level thing
yeah.. see DataChannel.h
AWorldSettings replicates. Might be able to send a NetMulticast RPC through that.
Would need to define your own world settings class though
Yeah datachannel needs to modify Engine...
WorldSettings might work - was hoping to keep the tests minimally intrusive.
I am investigating OnlineBeacon - but maybe just spawning a replicated actor on the server will be enough...
beacons are actors anyway, so you might as well just spawn an actor
And they require a lot of setup
ok, thanks, I'll try spawning an actor 👍
****************************************************************
* Examples
****************************************************************
*
* NOTE: Struct and Object markup excluded to prevent issues from UHT.
*/```
why is the 'examples' section of PushModel.h just blank
lol
is there no examples?
oh
im stupid
Scroll down 😄
Most properties in AActor have been setup for push model now IIRC
So if you look at all the default replicated properties of the base actor class, you can see most of them area "push model ready"
as in, they've been wrapped in functions that mark them dirty etc.
yeah
There's not really much to it. If you've always had decent enough encapsulation it should be pretty easy to adopt
wow tho this is a lot of extra work 😄
sadly, i dont have any professional experience in unreal engine
so like, i feel as though my organization of classes and such is probably pretty messy
But given Epic said they saw incredibly minor differences with it on or off, it's probably not worth it unless your servers are incredibly tight on CPU time
yea
idk like
i need to find a professional team to do ue4 dev
i feel like unreal is bloated
lol
it's just a massive toolset
I do enjoy seeing the word 'Fortnite' a whole bunch of times in my server output log
lol yea
This works great, even though an entire AActor just for a replicated bool seems a bit heavy 😂
Can you tell me the best solution for creating interactive foliage in Multiplayer.
- Make Custom InstancedFoliageActor
- Make Actor for each class (Tree, Rock, etc)
yea
so i can tell you
i've done this before
You can use Instanced Static Meshes
so the InstancedFoliageActor has a HISM for each foliage type that you create on it
by default, this actor is not replicated
nor are HISMS
you will need to create both a custom HISM and a new InstancedFoliageActor @gritty pelican
if ur trying to create another survival game though
please come up with some unique features 🙂
there's too many clones lol
Also
HISMS are made using what's called InstanceBodies
you will need to replicate each instance bodies current state to the player
Hey, have anyone know there is any node to show all players already spawned after started?
@steep terrace you can get a list of players connected
from the game state
there's a "PlayersArray" variable
Or PlayerArray actually i believe is the name
Something to note:
- Holds playerstates
- From a client point of view, this variable would display only the relevant ps's for that player.
- From a server point of view you'll have all the players.
I found it . I understand more about it. Thx a lot 😆 👍
Can you exclude owning client from a multicast?
you can loop through your controllers from the server and do a clientrpc excluding your local client
or.. if you just don't care about security, just add a condition in the multicast rpc functionacall
was mostly just looking to prevent sending unnecessary data to a client that will have already predicted the event locally
you cannae do that unfortunately
oh well, hopefully not that big of a deal
^ that works for me
Why is that? If i use engine's name for session - it wont find my session, but if i use anything else - it will, but doesnt update player count
does anyone might have idea why Controller is not replicated after possessing pawn on server ?
@fast arrow i think you should set default value ?
or ok controller is replicatred, but OnRep is not called
not sure if this is the place to ask, but has anyone had an issue in which when trying to open the game via standalone you get a warning from steam "[GameName] is attempting to launch with the optional parameters shown below"
" "C:\ProjectFolder\Game\Game.uproject" -game"
i cant seem to fix it
opens two copies of the game, standalone with no steam and the normal one with steam
What do you mean by default value?
the defaut value is, as i understadn, is NAME_GameSession
I think Name_GameSession is a string variable and its Empty need to be set or have a default value @fast arrow
Name_GameSession is a EName. not fully sure but this thing is an enum which linked with a name. kind of global const. I dont fully understand how this thing work but it has a value of "GameSession"
EName is just a shortcut to hardcoded FName indicies. NAME_GameSession results in an FName of "GameSession"
you can think of it as a global constant version of FName(TEXT("GameSession"))
Anyone versed in NetDriver stuff know what this means?
unreal engine Error: Ensure condition failed: IsKnownChannelName(NAME_Control)
[2021.01.28-22.51.45:774][257]LogOutputDevice: Error: Ensure condition failed: IsKnownChannelName(NAME_Control) [File:D:/Github/UnrealEngine-Custom/Engine/Source/Runtime/Engine/Private/NetworkDriver.cpp] [Line: 432]
[2021.01.28-22.51.45:774][257]LogOutputDevice: Error: Control channel type is not properly defined.
[2021.01.28-22.51.45:774][257]LogOutputDevice: Error: Stack:
[2021.01.28-22.51.45:774][257]LogOutputDevice: Error: [Callstack] 0x00007ff84e7f6c29 UE4Editor-Engine.dll!DispatchCheckVerify<bool,<lambda_f97c0e9ce0ad139bfd8fc9a7b66b01b1> >() [D:\Github\UnrealEngine-Custom\Engine\Source\Runtime\Core\Public\Misc\AssertionMacros.h:161]
[2021.01.28-22.51.45:774][257]LogOutputDevice: Error: [Callstack] 0x00007ff84d9bc3e4 UE4Editor-Engine.dll!UNetDriver::LoadChannelDefinitions() [D:\Github\UnrealEngine-Custom\Engine\Source\Runtime\Engine\Private\NetworkDriver.cpp:432]
[2021.01.28-22.51.45:774][257]LogOutputDevice: Error: [Callstack] 0x00007ff84d9c465e UE4Editor-Engine.dll!UNetDriver::PostInitProperties() [D:\Github\UnrealEngine-Custom\Engine\Source\Runtime\Engine\Private\NetworkDriver.cpp:387]
[2021.01.28-22.51.45:774][257]LogOutputDevice: Error: [Callstack] 0x00007ff83e15e7f3 UE4Editor-OnlineSubsystemEpic.dll!UNetDriverEOS::PostInitProperties() [D:\Github\ProjectCoreUE4\MainFiles\Plugins\OnlineSubsystemEpic\Source\OnlineSubsystemEpic\Private\NetDriverEOS.cpp:519]
stupid question. if a pawn replicates, would the floating pawn movement component replicate too?
if its replicated, but you won't get smooth movement
ahh okay. I'm wanting to make a ship combat mode and this is my first time taking a wack at movement other than character movement components in multiplayer so i'm not quite sure how I'm going to approach it
is there any way to replicate an array of delegates? i've been using delegates as conditional modifiers to an ability's cost (for example, a modifier that says "if you are under 50% health, this ability costs 50% less mana"), and this works fine on the server. However, I wasn't applying these things on the client, but now that I am working on predicting ability use, I want these available on the client so I can display when abilities are usable
you shouldn't replicate the delegates
they should be bound client side separately
as for is there a way, in theory yes
i don't see how it would ever be "safe" though
@eternal anchor OnRep is only called on clients. You have to explicitly call the bound function for the server
OnRep is called only on clients in c++, server will call the BP OnReps
calling OnRep manually is just sloppy, makes debugging harder later on, and should not be done
Hello guys, I'm using the GASShooter example and I'm feeling stuck using a linetrace when rpc.
So just to narrow down options, the linetrace works perfectly in for example the pawn class, but when used as a GSGameplay ability and as a client, only the local result is correct (the traces looking up), the server however prints a line always horizontal (so the location from the camera is correct but not vector).
I checked in cpp classes and nothing grabs my attention in the camera component. The game ability class is subclassed from his and all is by default.
Reproducing this in other projects with GAS the line trace matches client and server.
Any clue where to look at?
Thanks a lot!
Hey @rugged scarab I've been pointed to you as the one who made it, it will be really useful to have a hand on this 🙂
#gameplay-ability-system @olive kraken
and the issue, i can already see why its failing
Your camera will not be in the same location on server as client, as its not replicated
the proper way to use GAS is to send target data in, and having the server trace with that target data for validation.
Hey @meager spade thanks for the answer.
I kind of checked different options around that, and replicated the camera both in cpp or bp for sanity, etc.
What I still don't get is why traces work just fine other "blank" GAS templates or with way less functionality.
camera is in good locations since inherits from character movement or pawn.
this is not the GAS way to do things tho
#gameplay-ability-system we can discuss it
Can someone point me in the right direction of creating replicated spaceship movement? all the methods I have tried dont quite replicate propperly
Can you not use the character movement component?
Since it is a space ship moving in all 3 axis I thought would use a pawn rather than a character. the ship is a pawn so I cant quite get to character movement xD
Character is a child of pawn. It also has a bunch of replication stuff already setup. I would just re-parent it.
character movement has set movement for humanoid-isk 'characters'
@terse prawn In learn.unrealengine.com search for Gamedev.tv Multiplayer Course
They have a movement replication tutorial
They make a vehicle movement component there from stratch
It takes something like two weeks to one month to really understand the how it works, you can use the same method for your flying pawn
I made my own Floating Pawn Movement replication thanks to that course, and I also had some other resources but it teach me so much things
You are actually more lucky than me because spaceships are very similiar to vehicles
Altering the current Floating Pawn and implementing the method was harder 😄
really? I thought that using floating pawn movement would make things easier
It is easier but replicating it is harder
ahh okay.
In the tutorial they are creating a new component, you should also do the same if its a flying component
Thank you for the help, I really appreciate it!
I'll go check that out, again thank you
No problem 👍
What's a good way to have a sound of nature in the world? in multiplayer... just like a 2D sound on the player? or is it ok to just drop a big sound in the world and maybe theres some setting to just have it be unbound?
@strong vapor There's an ambient sound actor
yes.. im looking at that in the docs.. it says its generally used for sounds that get louder as you get closer
im kind of just thinking like... PUBG.. you just hear the wind and stuff always
it doesnt really get louder or quieter
the way i did this before was just putting a 2D sound on the player's character but i dont know if thats the most efficient
and if i do that i dont think i can do like.. audio occlusion
which would be nice when going inside
ambient sound without attenuation does not get louder/quieter based on location
so.. ambient sound actor?
oh cool
Just make an attenuation setting for stuff you want to be global.
I actually found issue and.. the Controller is replicated twice. Once as property and once by RPC, the RPC sometimes make it faster than property and that particular RPC does not call OnRep_
reported it as bug on UDN thogh
Controller is an Actor, it is not replicated twice
it is
then you would have 2 identical controllers client side
no
because it only happens when you already have controller and posses different pawn at runtime
there is a difference between a controller being replicated and a pointer to controller being replicated
for OnRep_Controller in PAwn it is no different, just that RPC set it faster sometimes and Networking assumes there is no need for calling OnRep_ since property have the same value at the end of frame
replication doesn't evaluate properties as they are set, but at a different time during a frame
and it usually won't replicate all actors being considered all at the same time either
if you spawn a new pawn on server during runtime and possess it in the same frame though
you have 2 separate replications going on - one is a Pawn itself, and the other is a replicated pointer to Pawn in the Controller
both need to finish for you to have a valid pointer to the new Pawn
it is usually more elegant to use SetPawn then OnRep_Controller btw, as that one is called on both server and clients
and it has a valid new Pawn
Yeah SetPawn ftw
Hi all, i wonder if anyone can help me here, i am using Blueprints and using the "Advanced Sessions Steam Plugin" and i see on the steam partner site it says they don't return full servers.
we will not return lobbies that are already full
how can i get around this? i would like to list all servers full or not.
By default, we will not return lobbies that are already full
Then a few lines down:
ISteamMatchmaking::AddRequestLobbyListFilterSlotsAvailable - Filters to only return lobbies with the specified number of open slots available.
Since you're using the Advanced Sessions Plugin, though I'm not familiar with it, I'm guessing you're using the FindSessionsAdvanced function? In which case there is a Min Slots Available input parameter which I would imagine setting to 0, or perhaps -1 would allow you to get full servers.
Thanks for the message.. here is the node for Find Sessions Advanced. i have tried both 0 and -1 with no success...
How should component creation be handled when it is replicated?
Same as when it's not except only on server
@winged badger @chrome bay set pawn + ownership rather than using the possession system?
Possess calls SetPawn
so does OnRep_Controller
so it makes you branch the logic far less between server/client
its also the only place where you can actually bind and properly clean up Pawn delegates if you're changing possession at runtime
well, not only place, but only convenient one
as you have both the OldPawn and NewPawn
Can you have WithValidation() for replicated properties?
WIthValidation is a UFUNCTION specifier
that adds the _Validate function
to a Server RPC
it doesn't work for server => client
Gotcha
wanted to have the same behavior
Kick a player if a replicated var was outside normal parameters
you can easily do that
you check the variable range during its Set function
and you just call a server RPC with _Validate that returns false if its outside the range
probably server RPC carrying const FString& with KickReason as payload
so you can log it along the way
you can also detect the discrepancy in OnRep callbacks
if you use a UFUNCTION() void OnRep_MyVariable(MyType OldValue); signature for OnReps
kicking the player is easy, elegantly detecting them cheating is not
Hi guys, is it possible to somehow determine if an overlapped actor is server or client?
(the actor is a character)
im guessing what you really want is to determine if its a local player pawn - IsLocallyControlled()
I'm not sure what you mean, i have 2 players, one is server and the other is the client, i want to determine if the server entered the overlap box or the client
or if you have an idea how to cast to the overlapped actor, that would help as well
Well you can cast the overlapping actor to what ever actor derived class you want and check if its is not null. Then you can do what ever you want with it.
you never want to branch the logic depending on if its the hosts character or clients
you are usually only interested if the current instance is server or client
or if the overlapped character is local (clients character on client, servers character on server)
Ok, let me explain my problem a bit maybe it will make more sense - both characters spawn in the world in different locations, whenever they overlap the overlap box they are teleported back to their spawn location, however, because the overlap box can't cast to them it can't determine what is the right spawn location for them, how would you suggest to go about this?
i would stash a pointer to the actor that is my spawn location inside the Character
at the time of spawning
then run the same logic (teleport to spawn point) on overlap
Sorry, but what do you mean by pointer? I'm doing it on blueprints
But if the teleport command fires from the overlap box and not from the character, how would it know to which spawn point to teleport the actor to?
because the character (or controller, or playerstate) knows its own spawn point