#multiplayer
1 messages ยท Page 452 of 1
you go to Debug menu -> windows -> Locals
then you can see every variable in scope, and its value
so you expand the PawnToPossess, you find its Controller variable, expand that down the inheritance chain till you get to UObjectBase
and then you can see flags on it
thanks for your help mate, i'm learning something today ๐
oh my
I think I may have it
(this helped me: https://stackoverflow.com/questions/25893840/how-to-avoid-unable-to-read-memory)
I didn't initialize the values in my info array with nullptrs
now I have another error, but I'll try myself first. thanks to everyone helping!
@north swan i did say you need to clear the controller from the pawn
that normally happens when you call Detachfromcontrollerpendingdestroy
{
if ( Controller != NULL && Controller->GetPawn() == this )
{
Controller->PawnPendingDestroy(this);
if (Controller != NULL)
{
Controller->UnPossess();
Controller = NULL;
}
}
}```
controller is still pointing somewhere so its not invalid (not a nullptr), but its pointing to garbage
@meager spade I'll try that tomorrow, thanks!
you guys mind if I ask blueprint related multiplayer questions in here? ๐
I'm calling the same function on a bullet kill as I call from a melee kill, only thing that changes is launch velocity (for the dying character) but for some reason the server and client don't match only on a melee kill
https://gfycat.com/pinkeasygoingbrocketdeer
(Left side server, right client)
Has anyone done something like PredictProjectilePath but for character movement?
What for? Jumping?
Characters change direction with input, projectiles usually are more.. predictable
I'm working on a melee that lunges at the enemy. I'm trying to make it not attempt the lunge if it is going to miss (because of collision, the target moving, etc)
So I want to run a prediction simulation ahead of the real melee
Trace to the enemy, where it would hit, find the distance, find how long it takes to traverse that distance (based on anim speed, I guess), tick forward the enemy, offset the trace loc by the difference between forward/current ticked enemy, see if it still hits? & tick them back after..
Roughly
MP sometimes sucks
Anyone know why this would be happening when attaching to a socket on server?
You never know if the enemy is going to change direction into something that would result in a hit, though
But if it all goes down fast enough, you can just provide them with the hit if it was predicted to hit, if you want to be sure it never misses
Yeah, that's what I'm going for. I don't want it to ever miss if it performs the lunge
Because it tracks the player and lunges at them per tick
I've never tried ticking forward a character though, they're reasonably complex, you'd only ever do it on server and rewind it instantly after, definitely needs testing
If not then just draw their hitbox based on velocity/time to hit
Well, nevermind the part about only doing it on server
You definitely gotta test that first ๐
If you tick them forward then restoring their state might be troublesome
TBH probably less complex to draw something based on velocity and time to hit
So if you know the point in the animation when it connects, the start->that point is the time to hit
Then take the enemy velocity (optionally factor their acceleration to predict if they'll slow/speed up later), find where that places them 'time to hit' seconds in the future, and see if they'll still be in the lunge trajectory at that time?
Right, yeah I've been trying to think about how to do the prediction
If you want it to initiate on the client you're going to also need to factor in latency
Right, yeah I am initiating on the client
Personally I would store each player's positions for a time
And rewind them on the server based on the latency of the instigator
And then predict them forward based on the lunge
Only thing is potential error between server/client, esp. with enemy players changing direction mid-lunge
That the local player wouldn't be aware of and the server would
But the rewind should help with that a lot
Just be prepared for some rare edge cases I guess ๐คท
Though those should only occur if their latency is very high and outside of whatever compensation threshold you set
Yeah that makes sense. I'll try to put something like that together
Do players need to manually open ports or other custom work if joining a friend via steam, or does UE4 / steamworks handle that automatically?
Peer to peer btw
Great thank you
Is it much work to use / implement steam sockets, or can it be picked up fairly easily?
I understand networking inside of UE4 very well but when it comes to external stuff I'm lost quite easily
Me too somewhat. I'm fine being a gameplay dev and leaving other stuff to other people. Don't have the time to learn everything
It's definitely not possible without a lot of extra effort and time
That said I'd like to at least be able to understand it- imagine launching an MP game based on code you don't really get in order to link steam players- would be a real shame if the game kicked ass but there were issues there
Yeah of course
@grizzled stirrup Well the whole NAT Punch Through stuff happens without any implementation of SteamSockets on your end.
iirc wwhen you use steam subsystem, and sessions, it connects via the steam stuff.
I suspect it does when you use the Steam net driver
Which is required for Steam OSS
It should still need to perform the NAT Punch Through
Cause even the Steam Socket stuff is using a Port that might not be open on the host
Doesn't Steam handle the NAT punch ?
Yeah
But that's why you would need to use Steam or any other subsystme that does that for you
Yeah, I guess if you want to do your own OSS, NAT is the least of your problems
Well if you create a backend for ServerLists
And you want to support ListenServers
Then you need NAT PunchThrough
Sorry, let me rephrase
If you're making a MP game today and don't want to use Steam OSS or the upcoming Epic OSS, you probably have more work ahead of you than just NAT punch - needing server lists, friends, etc
I got a quick question,
If I have a function that I only ever plan to call on the server, should I still mark it as a Server RPC in the UFUNCTION macro to prevent clients from calling it or should I just leave it out.
You don't use RPC macros for that
You would do an Authority check at the start of the function
I totally forgot about that
Thanks for reminding me
and there is also BlueprintAuthorityOnly too isn't there
That is to mark them as Authority only in BPs
They get that little node
Idk if that ever stops clients from calling it
apparently OnlineSessionAsyncServerSteam changed, and now lets you define UE4_PROJECT_STEAMPRODUCTNAME and similars on the target.cs of your project
does anyone have a cs example for a 4.22 steam config?
I don't want to miss anything (just in case)
When I set my Play button to Standalone and set multiple players, it won't work for me anymore
I just get 1 player
do you know why this could happen or if it can be a 4.22 bug?
What happens exactly ? No second window opens ?
yep
That does sound like a bug
What happens if you check that and start MP ? 2nd player is spawned but no viewport ?
And then specify the Editor Multiplayer Mode
No it only spawns one player/viewport with it checked
Will try it thx
np
Back with my lobby issues. I rewrote the whole thing, and I still experience the same bug: map doesn't open when joining. I finally saw something in the logs:
Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor BP_OSA_GameState_C_0. Function ServerChangeMap will not be processed
basically: clients do not travel, and the BeginPlay event on the level that is supposed to be loaded... doesn't.
blank screen.
Don't need to
I guess this is a ServerRPC
Inside of the GameState
That doesn't work
GameState isn't owned by Clients
is there a function I can override where a player disconnects but I can still get his old GetPlayerNetworkAddress(); ?
if I try to get it on GameMode->Logout() the playerController is valid but his network address is already gone
So ServerRPCs won't work in there, neither will ClientRPCs. Only Multicasts. @ember needle
@north swan Is it gone before the super::logout call?
Why don't you use UniqueId instead of NetworkAddress?
does uniqueID persist between disconnects and reconnects?
yes
oh damn
In CopyProperties
void APlayerState::CopyProperties(APlayerState* PlayerState)
{
PlayerState->Score = Score;
PlayerState->Ping = Ping;
PlayerState->ExactPing = ExactPing;
PlayerState->PlayerId = PlayerId;
PlayerState->SetUniqueId(UniqueId.GetUniqueNetId());
PlayerState->SetPlayerNameInternal(GetPlayerName());
PlayerState->StartTime = StartTime;
PlayerState->SavedNetworkAddress = SavedNetworkAddress;
}
yeah, it's always easier to check the source ๐
@thin stratus yeah no that's not it, not an RPC. This is called on the server.
- When game start, level
OSA_Menu_Level_Mainis open. GameMode isBP_OSA_GameMode_Menuand hasUse Seamless Travelset totrue. Server starts in host:
https://gyazo.com/a7574a091ee4dce663bdae21a4fd9ff1
So server is now on level OSA_Menu_Level_SlotSelection which has the same GameMode.
- Clients starts, so level
OSA_Menu_Level_Mainopen with GameModeBP_OSA_GameMode_Menu. It finds available hosts with:
https://gyazo.com/5ce949077b928be603f179daede1d883
- Clients connects to host with:
https://gyazo.com/ea24e604fdfd87a953a5775d3724cb79
- Server can see the Client in the list of players in the Lobby. Client sees either a blank screen (
BeginPlayeven is never called for theOSA_Menu_Level_Mainlevel), or it sees the level but everything is disabled.
It's obliviously something I am doing wrong
- Menu GameModes shouldn't have SeamlessTravel. OpenLevel is a HardTravel, so it makes no sense to set it to Seamless.
And "SlotSelection" should not have the same GameMode as the Menu.
-> it is like this so you can travel back from a game to the lobby.
That has nothing to do with that
I can go from Game to Lobby just fine with my GameMode setup
without having players disconnecting...?
Your Menu has nothing to do with Multiplayer?
it's only for multiplayer
it's the lobby
where players chose their role
which is saved on the playerstate
@jolly siren wait, can't i just override PlayerState->CopyProperties() and add the other actors I want to save? that would make my life much easier. is it usually done this way?
MainMenu is both for menu and the lobby
AH
so I need 3 gamemodes? 1 for offline, 1 for lobby, 1 for game?
Level MainMenu: GameMode_MainMenu. No Multiplayer. No SeamlessTravel.
Level Lobby: GameMode_Lobby. Multiplayer. SeamlessTravel.
Level Game: GameMode_Game. Multiplayer. SeamlessTravel.
GameMode_Lobby and GameMode_Game can share a parent
GameMode_Gameplay or so
Or GameMode_Online, whatever you like
you think that could be it?
yes, CopyProperties is how you persist things across disconnects. I'm not sure about pointers tho
interesting
Well, it#s def not good to fight the framework
@jolly siren could work If I keep the objects alive after the player disconnects
So I wouldn't use a Menu GameMode for offline and online
Neither would I mark it seamless
@north swan Correct. Just remember that it also happens during seamless travel
this is on playerstate
It has nothing to do with reconnecting
understood
For players disconnecting and reconnecting, you use OverrideWith
ok so still 1 playerstate
3 gamemodes, only the lobby and game ones with seamless
will try this
@thin stratus is the PlayerState->UniqueId still the property I can identify a player who's reconnecting with?
I would have the online modes share parent classes
understood
Even PlayerCOntroller and PlayerStates
Then you can easily move data between those
PlayerControllers persist in SeamlessTravel via OnSwapPlayerControllers in the GameMode
So everything that both PS or PC have (like selected character) goes into the parent class
ok will first refactor gamemode
Right
@north swan The UniqueID comes from the underlying subsystem
If you use, e.g., steam, you have a uniqueID, the steamID
i hope i'll make it work. otherwise i'll find a contractor to fix this. 14 months of work are blocked unfortunately.
should be the stupidest thing ever
Hehe, I fix this stuff for a living
If you need a kickstart, my Lobby System is on the Marketplace ;)
i'm not a company... probably can't afford you but will write to you an MP...
Might actually be on sale
I don't manage our companies sales
Let me check real quick
salty?
Yeah
Yop
4.20 upwards is the refactored version
@north swan I'm pretty sure Epic already does exactly that to give you your old PlayerState
PlayerStates go into inactive mode if a player leaves
Allowing to get their stats back if they reconnect in time
The lifeTime can probably be extended or set to 0 to be unlimited
Think that's a setting in either the playerstate or gamemode
That's what the OverrideWith function is
I found that so useful that I exposed it to Blueprints for Epic
Specially CopyProperties
No idea why that wasn't exposed
CopyProperties can be used for persisting across disconnects too.
AGameMode::LogOut -> AddInactivePlayer -> Duplicate -> PS::DispatchCopyProperties -> PS::CopyProperties is the call stack
I thought that is one and the same o.o
Weird, how do you know if it's called from a travel or to save data?
maybe there is data you don't want to save on travel, but on reconnect o.o
That is what Reset() is for
Guess you can also check if that PlayerState you are in is inactive
I actually never setup a reconnect system. Just knew the OverrideWith was called
You can set the properties back to default in Reset if you don't want them to persist across travels
but do want them to persist across disconnects
Fair enough
It's just different approaches. Really either way will work
Yeah there is so much knowledge in our heads by now, we could never stop typing haha
haha yeah this channel is my home โค It's good to cross pollinate as much as we can here.
You know that I constantly picture you sitting in front of the desk with exactly that smile?
It's really weird
Imagine that person, that is always just smiling, with exactly the same face.
No matter what happens
Creepy, yet funny
:D Not calling you creepy haha
lmao ๐คฃ
My brother would always have a huge smile on his face when we would game together growing up. I would look over and start laughing at him.
did any of you two guys played around with steam on 4.22. Apparently (finally), we can now define things like UE4_PROJECT_STEAMPRODUCTNAME on the target.cs file. (That's what the docummentation claims). But there is not a single example out there D: ~
I'm on the process aswell, however I'm in that step of editing or not the source code of the engine
haha it seems I don't need to on this version
rofl
Okay, enough, sorry
๐
Yeah I read it too
The new target.cs exposed stuff
Did you just try doing it?
/* Server values needed to advertise with Steam (NOTE: Steam expects UTF8)
*
* Specify these in your Target.cs files for your project.
* Make sure to escape the strings!
* If these do not match the same values on the Steam partner backend,
* matchmaking will not work for your dedicated server
*/
#ifndef UE4_PROJECT_STEAMPRODUCTNAME
#ifdef STEAMPRODUCTNAME
UE_DEPRECATED(4.22, "The Steam Product Name Macro has been updated to be configurable from your Target.cs file. Please change STEAMPRODUCTNAME to UE4_PROJECT_STEAMPRODUCTNAME.")
#define UE4_PROJECT_STEAMPRODUCTNAME STEAMPRODUCTNAME
#else
#define UE4_PROJECT_STEAMPRODUCTNAME "unrealdk"
#endif
#endif
thing is I don't know how to - but don't say it out loud, I suck with cs files I always end up copying them and editing them looking at examples, it is something I really need to... hum improve
To translate that: if UE4_PROJECT_STEAMPRODUCTNAME is not defined already by you
And you have STEAMPRODUCTNAME
IT corrects you but still uses STEAMPRODUCTNAME
Which I didn't even know existed
nono I understand, thing is that you need to make it on the CS
which is c#
not c++
oh
Wait a second
Can you check if this works
AddDefinition("UE4_PROJECT_STEAMPRODUCTNAME=YourProductName");
Something like that
I know it works in the Build.cs
the answer will be delayed, but I think I can, I'll keep you guys posted in case you all want to transfer everything to 4.22
anyways, compiling 4.22 thank you for the heads up!
I guess I'm doing something wrong: just to test the uniqueId stuff, I saved the playerState->UniqueId in a variable upon first connection.
when the player disconnects and reconnects, the new uniqueId is not the same as the old one
did I forget a step between?
You are using Steam or so?
nope
oh
You gotta have a backend with unique users :P
okay I'll implement steam and try again, see ya in a week
hehe
jk haha, i'll see ๐
@thin stratus unfortunately that wasn't it. So tired, it's been months.
If I record the thing with Gyazo (screen capture) then IT WORKS. If I don't, then no.
I start with these options (standalone mode):
https://gyazo.com/629cdd563511006e110e14cf97d14175
when I do that, then one window is blocked until I close the other one
that's when just OPENING THE GAME...
Either start htem by hand via the uproject file
Or stick to one process for now
Make sure to toggle off auto connect though
I cannot toggle it if I set Do not run in a single proc
So.. I start it with a script:
start "" "C:\Program Files\Epic Games\UE_4.21\Engine\Binaries\Win64\UE4Editor.exe" "D:\UNREAL\OneStepAhead\OneStepAhead.uproject" -game -NOSTEAM -windowed -ResX=1024 -ResY=768
start "" "C:\Program Files\Epic Games\UE_4.21\Engine\Binaries\Win64\UE4Editor.exe" "D:\UNREAL\OneStepAhead\OneStepAhead.uproject" -game -NOSTEAM -windowed -ResX=1024 -ResY=768
That's why I said
Use single process
OR, rightclick the uproject file
And hit Launch game
and then I experience what I tell you: the blocking happens when the client tries to open the map
So your Menu Gamemode is now not seamless travel anymore?
correct
The right one is the client?
BP_OSA_GameMode_Menu_MASTER has two children:
- BP_OSA_GameMode_Menu_Offline
- BP_OSA_GameMode_Menu_Online
the first one is not seamless travel, second one is
both
no server yet
is there anything I can try. I know this will now die here, again.
it's the stupidest setup EVER.
If you press play
You already have that blocking window?
Not even clicked anything in the game?
Which one is hanging, server or client ?
Client should hang at connection when connecting to the lobby at first
Server shouldn't hang at all
i have question: currently my client is connecting on dedicated server with ip adress, and for now, i dont want to use steam subsystem. Can i create sessions with subsystem null in ue4? i mean is that possible without using any other subsystem?
they are launched in standalone. noone is the server yet.
@real yacht Online subsystem null is LAN only, for debugging. If you want sessions and avoid IP addresses you need Steam, GOG, or the upcoming Epic subsystem, or your own service
okay, thnx
anyone got a ue4-steam-dedicated server "guide" thing for 4.20 or newer?
Hello everyone. I'm learning multiplayer with UE4. Already did Tom Looman's course where we did shooting with Replicated UPROPERTY and OnRep function. Now on my own prototype I'm using RPC multicast and end result is the same. So my question is, is there a "proper" way doing this? Which one should I use, RPC multicast or OnRep ?
OnRep is meant to trigger on replication of values, and only works server to client
RPC works both ways and is easier to understand as an event
But overall it is up to you
so way i look at it is
RPC should be for instant relevant stuff
OnRep should be used for persistant states etc
say i have a chest
it plays particle when chest is open, that would be RPC
In the Tom's course, the OnRep was "triggered" by some aim values, so it didnt work if I didnt move at all, but i fixed it by replicating int32 TotalShots, so now I'm just using telling the server that I wanna shoot and it handles the rest and multicasts
but the lid being opened would be a OnRep notify
so clients not relevant will see the lid open, but not see the particles
of the chest opening
when they become relevant
I would draw the line at RPCs for "events" that happen once in a while like firing, and onrep for regular, constant flow of changes like aiming
You can actually put it in these two categories:
- Fire and Forget
- Late Joiners
Fire and Forget are events you don't care if someone gets them
Late Joines are people that join late or just come into relevancy range and you still need them to see the event
Usually States fit into the Late Joiners category
Cause they need to know the new state
Is the door open? is the chest open? is the weapon firing? etc.
yeah, so with the chest example, Lid Being opened would be a OnRep, meaning anyone not relevant, when they become relevant will see the lid open. Playing the particle of the lid open should be a RPC as you want that instant, and if someone not relevant become relevant, you dont want to play the lid opening particles again for an already opened chest
i think the content example has an example of that
Actually, this is a weird example
and is def worth checking out
Cause you'd play the particle as part of the animation
Which is triggered by the OnRep
i wouldnt want the chest to play the particles when someone becomes relevant
if the chest is already opened
What particles are we talking about?
like a opening effect particles
Ah, I thought you meant activating a glow or so indicating there is something in the chest
Okay, thanks for the examples, it makes sense. My proto is going to be lobby -> then start match and nobody can't join during the match, only in the lobby
If you want to make it perfect
You might actually use two booleans
One that states if it's openeing or closing for example
And one for the state itself that is replicated only initially
Cause the Opening one sets it otherwise
so i always categorise RPC vs OnRep as, OnRep is current state, RPC is instantaneous
There is like a thousand tricks you can do
COND_InitialOnly
Yop that's for the open state then
yeah, currently I'm doing one feature at the time, first testing server+client as one player, then testing with 2 players, then testing with dedicated server and make sure it works correctly on all
thats fine if you only want to do it the once, but if you use a single bool, that would be no good
like bChestOpened
i'm coming from Unity so I must say Unreal multiplayer feels 1000x better ๐
To be fair
If you are in relevancy range
You will get the RPC to open the thing
Which lets you set the boolean yourself
If you aren't ,you will just get that boolean, initially, and that's it
That way you use one RPC and a oneTime OnRep
RPC handles that if you are in range
InitialOnRep if you come in range
Initial doesn't mean ONCE
It shouldn't at least
it means initial in that relevancy?
It should call whenever the actor starts replicating for you
Yeah if you run away and come back it should call again
If not then well
one more question about shooting.. if I have automatic weapon with really high fire rate, I propably should do it with just two RPC's? StartFire and StopFire instead of calling RPC every shot ?
depends what you do with those RPC's
i never rpc start fire and stop fire
its done locally
just spawn some muzzle flashs and sounds on clients, server does tracing
and the hit results sent to the server for validation
and i kinda hacky use a OnRep notify for the muzzle flash
which is basically a uint8 which increases by 1 for every shot
actually right now the server does all shooting logic, but that sucks when playing with high ping because you can't hit anything you want
thats bad
yeah, so I think im going to just make client do the tracing and then check in server if its even possible and if it is, deal dmg
i have the server and client do the trace
but it's going to be co-op, not pvp game so I don't need super cheat proof solution I guess, atleast not for prototype
but you also still dont want people to have delayed shots
cause it will ruin the experience
Iirc I use an int for that
If shooting, Int+1
If not int = 0
It's onRep
If int > 0 spawn effect
If = 0 stop
thats pretty cool
Just make sure you skip from 255 to 1 ;)
what is the best way to get a PlayerArray OnRep event (GameState)
my guns dont fire more than 255 rounds
int is 8 byte tho, uint 8 is 2 ?
(They had Gandhi at Conflict Level 1, which was the lowest. Unlocking Diplomaty lowered the level by 2. They didn't check any min value. Tada, Gandhi sends atom missiles)
changing the dedicated server to use steam subsystem is a ton of work.
is there a less convoluted guide or info than
https://wiki.unrealengine.com/Dedicated_Server_Guide_Steam
?
I just want some barebones stuff
uworks is a good plugin
to help with steam intergration
it exposes everything you could need ๐
and its on sale right now.. so
which one should I get? probably not singleplayer
i got the full version
is it the one on the right?
yeah the more expensive one, but it has everything MP, SP and Subsystem
it doesnt use the UE4 steam subsystem
oh ok
not the subsystem but still uses steam
"In 4.20.0, Epic has hard-coded their built-in subsystems, therefore making custom subsystems impossible to register without modifying the engine. You can read more about this issue over here. Until this is fixed, only the NetDriver, the Core/Web modules and the example project will work work out of the box."
so this allows you to use steam, however with a custom solution (not the one in UE4). correct?
what are the advantages of this other advanced sessions plugin
we use both
ok so why did you get it...
because of all the functionality it allows without having to write it all ourselves
hence my question: what advantages? is this related to stats and so on?
Stats, achievements, lobbies, UGC, almost everything that Steam offers can be used directly either in BPs or in a UE4-specific C++ (i.e. delegates)
If you find a function in the Steam API reference ( https://partner.steamgames.com/doc/api ) it's most likely accessible through UWorks.
And you use the API alongside the Steam guides ( https://partner.steamgames.com/doc/features ) to achieve whatever it is you want to achieve with Steam.
UWorks functions and structs have the same names as their Steam SDK counterparts in order to make it easy to follow Steam's guides while using the plugin.
LogNet: Warning: Travel Failure: [LoadMapFailure]: Failed to load package '/Game/Maps/ThirdPersonExampleMap/UEDPIE_1_ThirdPersonExampleMap'
LogNet: Warning: TravelFailure: LoadMapFailure, Reason for Failure: 'Failed to load package '/Game/Maps/ThirdPersonExampleMap/UEDPIE_1_ThirdPersonExampleMap''. Shutting down PIE.
PIE: Warning: TravelFailure: LoadMapFailure, Reason for Failure: 'Failed to load package '/Game/Maps/ThirdPersonExampleMap/UEDPIE_1_ThirdPersonExampleMap''. Shutting down PIE.
I get that error when trying to connect to a PIE listen server through another a PIE window on another PC using ip
it works fine with a dedicated server or a standalone
does PIE not support 2 PIE instances on different computers connecting?
play in editor does not support that kind of stuff, as far as I know
gotcha, thanks!
Is it possible to have very relaxed movement component correction? (where the movement of another player isn't extremely important to the experience and buttery smooth clientside movement is more important than accuracy?)
I am using the launch character node and on 0 ping it works fine with the client but when the ping starts rising it jitters quite a bit
Takes away the satisfying smooth feeling
I'd just want the server's view of the client to interpolate to where the client actually is but the client himself never being corrected
So instead of the client saying "server please jump, while I jump locally and interpolate me to my location on the server" it would be "server I jumped, I'm here now, don't correct me but move your view of me to where I am"
Is ShooterGame's ClientSideHitLeeway just a poor man's lag compensation?
Since they don't do server rewind or anything like that
So instead of rewinding they just give a really big leeway to hope that covers the latency?
Okay cool, just wanted to make sure I was sane reading through this ๐
๐
Thank you for confirming
That is a good question kyle
There is a ClientAuthorativePosition on CMC. That might be a good place to start
You could try flipping that on to true while doing the launch and see where that gets you
Thank you very much, I'll give that a shot
There is also bMovementTimeDiscrepancyForceCorrectionsDuringResolution
big name lol
/**
* Whether client moves should be force corrected during time discrepancy resolution, useful for projects that have lenient
* move error tolerance/ClientAuthorativePosition enabled.
*/
UPROPERTY(GlobalConfig)
bool bMovementTimeDiscrepancyForceCorrectionsDuringResolution;
Please let me know if you solve it, because I'm interested in the answer as well
Amazing thank you very much, will try that out now
@jolly siren i wonder if there is that much difference between leeway and rewind used in UT5
UT4*
I would also love to see a comparison of the results
Leeway is obviously much easier to implement. But I assume rewind gives much better and controllable results, and also protects against cheating better.
yeah im still on the fence about how to handle prediction
tbh i am also kinda trying to work out how to reduce RPC calls during weapon fire
but im struggling to come up with a kinda batch RPC system
where a fast firing gun will batch the rpcs during frames, and then send them in one go
What are you rpcing?
You said earlier that you don't rpc start/stop. So are you talking about hit/miss events?
@jolly siren maybe this is crazy (just thinking of any other options before making a custom edit to the CMC), but since the other player's accurate position REALLY doesn't matter (just needs to be generally in the right position and playing the right FX when shooting / playing the correct anim)- could I maybe just literally tell the server to update its location of the client at a fixed rate (like send and set a vector 10 times a second) and lerp between the current update to the next?
Then replicate all other stuff like gunshots and such from the client as usual?
Isn't that basically what Fortnite does for simulated proxies that are far away ๐
No clue but maybe it could work for buttery smooth client movement?
Disable movement replication and just update manually
Worth a try
That isn't what its for
It would be to avoid the computationally expensive simulated movement
Yeah for sure but in this case maybe it can work to get the smooth client gameplay I'm looking for?
Its only used for players that are too far away to really interact with
Yep but in Fortnite the position of the players is extremely important
So the server has to correct them up close
In my game the client should go wherever and the server just needs to visually see where he is generally
How can I replicate from the client to the server?
That's what I'm trying to do
Then you do need an RPC but this doesn't sound like something appropriate
I just need the server (listen server host) to get a general approximation of where the other client is while giving the other client authoritive (and therefore super smooth) movement
To avoid any corrections since they don't need to be corrected
The players are playing together against AI
So there's no need for their positions to be extremely accurate
But there is a need for clients to have smooth and satisfying movement that is often corrected under default replicated movement at pings greater than 100ms
So basically you want client authoritative movement
Yes
And have the server just see where the client is
Replicate everything else normally (gunshots, FX, anim state)
OK so turn off replicate movement. Have players send a server RPC. Server stores that as replicated with COND_SkipOwner, and OnRep updates simulated clients
It will send a struct containing location, rotation, anything else you need
That struct replicates
Etc
Is there a need for the struct to replicate or can I just have the client call a server RPC that sends the struct that would then (within the RPC call) update the position of the client from the perspective of the server?
Oh of course it has to replicate to other clients
duh
So the struct is a Repnotify variable, it skips the owning client and via the OnRep function updates the position of the owning client to other clients and the server
I wonder if I limit my game to 2 players (which is the intended experience anyway), could I get away with not even having to replicate that struct and explicitly just call a single server RPC to update the other player's position on the server?
Your better off using a Replicated variable.
Even in the case of 2 players listen server?
Always favor replication over RPCs
I'd still have to call the rpc for the client to send his location (client authority over movement)
Thank you both very much for responding btw
Sure
So in the case of client sending his movement via rpc, I'm not sure how replication even fits in?
Since the client can't replicate to the server
And the server doesn't need to replicate the data back to the client
He just needs to update the position of the client on his screen
Replication is being used when the Server needs to tell the other Clients what happened, thats all.
Sure, but in this case, I just want the client to say "Hey server, I'm here, update me on your screen"
But he has full authority over his movement (no corrections from the server)
So I assume it'd be best to just send a single RPC with a struct that contains location / rotation once every second and interpolate?
"Update me on your Screen" is what the Server is doing when you do the RPC
Replication is updating the movement on other players screens
Yep, but in the case of 2 players on a listen server (one being the server), this wouldn't be necessary, correct?
Sorry for being difficult haha just trying to get a better understanding
Ah right, yes on a Listen Server correct. You would skip the RPC part for the Listen Server Client
However its still relevant for connected Clients
You'd skip the replication rather? The RPC would be the necessary way for the client to tell the server where he is, right?
And yes definitely relevant for more than 1 client
1 of the Clients is the Server so he doesnt need to RPC his own movements to himself.
He does need to Replicate the movement to other Players though.
Yes
Ok yep perfect
The Host can skip doing an RPC because really thats not going to do anything anyway.
So he'd have to replicate his movement down to the client (either the default way or else the same way as the client is doing it, just not an rpc)
In that case I could probably just set bReplicatesMovement to true for the server and false for the client
So the client sees the server, the server gets updates on where the client is and can see him
Everyone is happy
Is there any reason that when I uncheck replicate movement only on the client of a listen server and not the server (host), no movement is replicated in either direction?
When both are checked, I see movement replication of both client and server
I just want to see the server's position replicated down to the client but not the other way around
My question is, when you step over the relevancy distance, then after a couple seconds move back, it may happens the replicated actor's components become pending kill, and won't gets recreated again - they actually will be missing. Have anybody noticed such issues with replication before? 4.20 PIE
How do I set these macros on .Tartget.cs file? Do I also need to set them on Server.Target.cs as well?
I'm completely stumped by my screenshot- is it really not possible to have a client not replicate movement but the server replicate down to him? I feel like there's something extremely basic I'm missing
if you want clients to replicate movement to other clients directly, you can't do that using unreal networking. I believe you'd have to use another networking layer which is not really recommended
Client does not replicate movement to server, unless you are thinking about the Character Movement Component which is a different case.
It's a 2 player game so I just want the host player (server) to replicate movement normally down to the second player (client) , but I want the client to not replicate movement at all and instead send the server updates
I have the client sending updates perfectly but whenever I tell authority (host) to replicate movement and the client player (remote) to not replicate, I don't see any movement from the host
It would make sense to me that if I'm the client and the server is replicating movement, I'd see him move?
And yes it's the character movement component
But I'm setting Replicate Movement on the actor
Not on the CMC
I think you can individually adjust the CMC replication props. The actor's replicate movement would be a setting to sync from server to client the transform of the actor. I'm surprised that it would severe the movement of the character but maybe it does.
Ok thanks I'll try that
Setting any combination of replicate movement to false only on the client but not on the server either results in the client still getting corrected or the server being motionless
I really thought it'd be as simple as saying "Server - yes, Client - no"
When you enable the replicate movement on the actor, but disable the replication of the CMC what exactly is the outcome of that?
@rotund sapphire there's no change- the movement is replicating and the client gets corrected
The CMC has a "component replicates" flag of false by default though
So I'm assuming the actor "Set Replicate Movement" is what actually causes the CMC replication
Also in the case of interpolating the positions of multiple remote clients on tick for smooth movement, how can you do it so that you are interpolating client X to this value but client Y to another?
The on rep would set the target location but I'm not sure how to then smoothly interpolate multiple different simulated proxies
I guess you'd have to store an array of other players and set their positions individually on tick....
You can maybe try it this way, sometime after begin play. It's possible that Character class will enable this internally, but you should be able to disable it.
Yep that's what I was disabling- no change
If you see it's actually false already
But it also possible that Character class takes care of the synchronization of CMC which could be an unfortunate case for you
So it would be either all on or off for a certain actor?
Character is a different case from Actors, it's a super complicated piece of code.
Thanks for your help, I'll try to find an easier alternative
You can maybe try to use Pawns, that is less cluttered. And it doesnt replicate stuff, that's a good start for you.
Thanks, might have to move back to pawn and implement a basic movement system
The on rep would set the target location but I'm not sure how to then smoothly interpolate multiple different simulated proxies
Either it's a server or client you want to interpolate, you can use the Tick() and simply lerp'ing the transform between current loc and target loc, on a rate of your choosing that is in sync with the timing of the replicated information.
For instance, if the transform is being replicated once in a second, then you can simply use the tick delta for the lerp alpha, and it will arrive at target loc at the moment the new information arrives, so it can continue move on his path. It will be a second late of course, but that may not be an issue for you. Or is it?
If you wish to keep them in very strict sync with server locations, then you have to think about movement predictions (extrapolated from ping/updaterate/velocity etc information)
hey, when i test 2 players in editor, not dedicated server, both are using the same player controller (same name, not an iteration of the same name). shouldnt they be different? wondering if this has to do with my spawning weirdness.
A playercontroller can only posses one pawn at a time, so i think you got confused on something else.
makes sense. but as per this screenie, printing the player controller name of both active windows gives the same name
that is the result of:
@rotund sapphire Thank you for the detailed response! I'm a bit rusty on netcode in general but how do I know which client I'm lerping on tick if there's only one current loc and target loc var on the character? I have it lerping fine when I am interpolating a specific actor but for more than one I'm lost
I know that each client has a copy of each other client's properties, but I'm confused on how to nicely interpolate all other clients
I definitely don't need a strict sync
Just need all clients and the server to be generally where they are on their local screens
kylekatarn, all clients have their own copies of the pawns running individually, and so the logic you implement on tick will interpolate there individually as well. They are called Remote Proxies btw.
So on tick if I do a branch to check if their local role == ROLE simulated proxy and then do the interp stuff, it'll do it for ALL other clients with their individual locs?
I assume the target loc and rot need to be repnotify vars?
the_hack, you can perhaps try print out object name, maybe is has the instance flags in the name too. But don't worry they are individual PC's i can tell you already that much.
Yes kylekatam i think that should work. But you don't have to create a system here that will iterate all clients. Like i said these remote proxy pawns will run their own ticks, so all you have to do here is just rep the loc and rot, and just let them fly on their own.
Ok that's awesome thank you very much
Maybe because playercontroller(0) is the PC of the client, so it will be _0 on client side always. You can perhaps access some different information, such as the player index from the playerstate that should be different.
ah ok. thanks. i'm trying to work out why the focus/control switches from the server player to the client player window when the server frags the client. this is helping even if its not the reason
Testing in PIE comes with some mess in window and focuses, but you can maybe run your game in standalone mode. Does that makes any difference in this issue?
Sorry Robert, one more thing- what would you put in the OnRep function in my case? Setting the target location variable even though the onrep struct with location could be directly plugged in to the interpolate?
I don't think you actually have to use onrep at all. You just replicate the value, and run the tick all the time to interpolate the pawn to whatever the replciated loc/rot have at that moment. By using the delta for the lerping it can run continously. It should be easy to setup this way.
Perfect thanks a lot!
I have the server replicating nicely down to the client now by checking if local role == simulated proxy but finding it hard to have both server replicating to client and vice verca- might just be a combination of role checks
Yeah i have a bit of a hard time comprehend what exactly you are willing to do here. But i just hope in the end your idea works out for you. :P
No problem thanks a lot for the help!
So why do you want client to move on it's own freely, but also the same time receive updates from server as well?
Or you want to send the information to server? But then what do you wish to replicate from server to client?
I want the client to have authorative movement for ultimate smooth gameplay but I want to still see the position of the server
I tried disabling movement replication only on the client but it didn't work
So now I'm trying to manually send the data
And interpolate
Replication only works from server to client. You have to use RPC to send the location info to the server.
Yeah it's working great with an RPC but the server doesn't move on the client
So now I have the server moving on the client but the client not moving on the server haha
I had both working at different stages but never both together (the server sees where the client is roughly, and the client sees where the server is roughly)
Doesn't need to be accurate they just both have to be sending updates to each other at some rate
Ohhhh I got it!
On tick check if the remote role == ROLE Autonomous Proxy (Client movement on server) OR if the local role == ROLE simulated proxy (server movement on client)
That's the winning combo ๐
Every second the server either sets his replicated loc and rot struct or the client does an rpc that sets that struct
But at some point, som of these guys have to decide who is the authoritive here.
Because, once you introduce a bit of network latency to this equation you will see them twitching dancing around.
It's 200ms atm
There's no correction so and the server is still the authority
He just doesn't care about the client movement
He just needs to know roughly where it is
I usually roll with this tool, never cheats on me. https://jagt.github.io/clumsy/
Oh really cool!
I'll check it out
Usually net pktlag = x works great though in PIE
Ah i see what you mean. So the server won't apply the movement data, but receives it for stats only.
That's alright i guess
Yeah it's a giant hack really but I just want it for a game where you play together with a friend and the movement should feel great
Not rubberbanding and being corrected
Is it terrible practice to be setting the mesh positions on tick and sending a rot and location a few times a second, or is it quite ok seeing the circumstances?
Rubberbanding and network latency are comes hand in hand. In my experiences.
Well. At the rate you send the updates, plus the time it require to arrive at location, the client will be a bit of a desync / late. In your case it would be 200msec + replication tick rate msec latency. So that could be an issue in certain gameplays.
But updating the mesh location on tick rate should be fine.
Keep in mind in this game you just fight AI with your friend so as long as he feels you are nearby and sees generally where you are, no one would be any the wiser
And great, that's awesome to hear
All other movement replication is turned off too so probably saving something there
Proxies are all smoke and mirrors anyway I guess
I'll then just run RPCs for important events like shooting or impact FX
And it'll feel like he is there but the client will have buttery smooth movement
Character Movement Comp also takes care of packet loss and such issues, helping with synchronizing the characters and events etc. This may be a missing part, but not neccessarly required for you as i understand.
Yeah CMC is great for games where accuracy matters like PvP shooters
But I imagine even if you dropped packets, with my tick system it'll just interpolate when it can
And melee fight too.
Yes the tick will help the character to arrive. But it will be moving a bit faster than usual. From the perspective of the other player.
Like for instance, the CMC does something like, when there is no update of location, and no update in movement changes, it will allow the character to run forward, until it receives a new data to do something else. Like stopping.
CMC is efficient because only send updates when required.
Ah yeah that is very nice
Very efficient
It still probably updates something on tick right?
Like the location / rotation, even if it's using old data
Probably in a more clever and optimized way
However since there'll be max 4 players in my game I think it'll be ok my way unless I am missing something
4 sets of location and rotation vectors 10 times a second seems reasonable
If only I could tell it to not correct the client ๐
Then I'd be able to use it
Just let the client do whatever but tell the others where he is
One thing I'm noticing with my setup is that when the client sees the server moving it's buttery smooth (interpolation), but when the server sees the client moving it's quite choppy
Not sure why this is (almost like the proxy has a lower tick rate)
It's not extreme choppiness but about 1/6th the frames
for the default character movement, this happens because the server only simulates the player when it receives inputs
There are some settings for the CMC interpolations, but it is indeed going to be bit choppy here and there when the ping is fluctuating. Which is it does in real case.
Thanks again for the amazing help
One LAST question- if I wanted to continue the client authority trend for things like animation bools- should I be sending server RPCs with a bool such as "jumping" that is replicated but with the skip owner condition?
So that the client will always be the one that sets it but it'll update on the server / other clients correctly
I'm not sure whether the replication conditions work properly in blueprints. Maybe they fixed it in 4.21+.
yeah I see the skip owner condition is broken in issues ๐ฆ
Would this be the correct approach though?
I can move it to C++ if needed
Yes that's sounds right. You can maybe replicate the bool as a variable with a notify, and apply the jumping when the bool changes. But it will only replicate when the bool is changed.
You can also move the thing in c++ indeed, or just check on the event whether the modification arrived back to owner, and skip manually. In blueprints at least. That's maybe works better with multicast rpcs to avoid conflict with the bool value.
@grizzled stirrup RepNotify in BP acts more like a setter then a replication callback, if you set a RepNotify variable locally on a client, its RepNotify will fire
c++ does not have the same issue
regarding my issue above, in a networked (steam) game, client and server players have the same player controller names (ending in _C_0 ) ๐ฎ
ah. thanks.
I have a bug that happens often, but not 100% of the time. I have two player start actors in my map, and two players. around 50% of the time I start my game, both players try to spawn on the same player start actor, with the funny effect of jumping on top of each other's head. Anyone ever saw something like this or has any clue?
Yeah happens to me all the time. In theory it shouldn't happen but it seems the engines native code for choosing a player start doesn't check collision properly.
I just built my own system where each player "reserves" a player start, then it can't be used by others
oh ok
I have to go and override the chooseplayerstart then
too bad ๐ญ
I'm reading the code
I guess it's a problem that happens from concurrency
when there's zero latency
between clients and server
Well in theory what should happen is one player is spawned at one player start, then when it's the next players' turn that one is occupied by a colliding actor so it shouldn't consider it - but for whatever reason that doesn't always happen
Been a while since I've looked at that code though
I have a couple of buttons, when a player presses the correct one it turns green. These buttons are server-owned. How can I make the button only green for the clicking client?
So that the other clients can't see the button turning green?
pointer to the playerstate/PC which should see it as green is my first guess
Or a bitmask of some kind if you want multiple players to see it as green
How does one get the ViewLocation of a Client again?
Got a CameraActor that is spawned locally and set as ViewTarget.
Server obviously doesn't have that and struggles to perform linetraces based on the camera of the client.
Is it managed by the camera manager? Or an entirely separate camera than the players?
Entirely different camera
I could move all of the camera logic into the manager
But hm
The ControlRotation exists on the Server, so that is already okay
But the location offset from PC/Pawn to the ViewTarget is missing
The Camera is also driven my user settings for distance to pawn and and height offset.
Even if I do the math on the server too, it would be missing the differently set variables
Isn't there some replicated vector somewhere that can be used already?
Does switch have autority fire both the authority and remote outputs for a host of a listen server? (hosting but also playing)?
Might explain why I couldn't enable movement replication only for the listen server host and not other clients
Hmm I'm so confused as to why it doesn't seem to work (setting server to replicate movement to the client, but the client NOT to be corrected / have movement replication ticked)
Just using switch has autority as a branch on begin play
PlayerController's send a ServerUpdateCamera rpc every tick by default, which sends the client camera location and the camera pitch and yaw to the server. But I'm not sure about non player based cameras.
I'll see if I can hijack that, thanks!
no problem ๐
APlayerCameraManager::UpdateCamera
I guess with the issues regarding replication conditions in BP and the repnotify issue someone mentioned above, I should use C++ for at least the networking setup?
It seems the conditions work in PIE but not in packaged games
Bit of a shame as BP is great but it is what it is
@jolly siren This is tight into the CharacterMovementComponent
You gotta hate the CMC one way or another
float AUTPlayerController::GetPredictionTime()
{
// exact ping is in msec, divide by 1000 to get time in seconds
//if (Role == ROLE_Authority) { UE_LOG(UT, Warning, TEXT("Server ExactPing %f"), PlayerState->ExactPing); }
return (PlayerState && (GetNetMode() != NM_Standalone)) ? (0.0005f*FMath::Clamp(PlayerState->ExactPing - PredictionFudgeFactor, 0.f, MaxPredictionPing)) : 0.f;
}
lol okay UT you aren't dividing by 1000
magic
o.o
Do you use ootb ExactPing for your prediction calculations or do you roll out your own ping system like UT's ServerBouncePing, ClientReturnPing, ServerUpdatePing, etc?
I guess ExactPing is really an average across 4 seconds
I use the same stuff the CMC uses atm
So it doesn't change quickly enough
For server rewind prediction stuff? Like bullet fire?
void APlayerState::UpdatePing(float InPing)
{
// Limit the size of the ping, to avoid overflowing PingBucket values
InPing = FMath::Min(1.1f, InPing);
float CurTime = GetWorld()->RealTimeSeconds;
if ((CurTime - CurPingBucketTimestamp) >= 1.f)
{
// Trigger ping recalculation now, while all buckets are 'full'
// (misses the latest ping update, but averages a full 4 seconds data)
RecalculateAvgPing();
CurPingBucket = (CurPingBucket + 1) % ARRAY_COUNT(PingBucket);
CurPingBucketTimestamp = CurTime;
PingBucket[CurPingBucket].PingSum = FMath::FloorToInt(InPing * 1000.f);
PingBucket[CurPingBucket].PingCount = 1;
}
// Limit the number of pings we accept per-bucket, to avoid overflowing PingBucket values
else if (PingBucket[CurPingBucket].PingCount < 7)
{
PingBucket[CurPingBucket].PingSum += FMath::FloorToInt(InPing * 1000.f);
PingBucket[CurPingBucket].PingCount++;
}
}
This is what the engine does for ping calculation
Currently only the pawn itself is predicted. Haven't done anything about rewinding bullets yet
It looks like UT wanted ping values that updated more quickly for prediciton
Wouldn't really know where to start there anyway
Ahh okay gotcha, saw that you were talking about the same GetPredictionTime magic numbers with Moss a couple years back in the chat history
(camera bug is solved now, thanks!)
Yeah Moss might know more
Or TheJamsh
I only scratched that stuff
Yeah I was missing this:
APlayerController* PC = Cast<APlayerController>(HoverdroneOwner->GetController());
APlayerCameraManager* PlayerCameraManager = (PC ? PC->PlayerCameraManager : NULL);
if (PlayerCameraManager != NULL && PlayerCameraManager->bUseClientSideCameraUpdates)
{
PlayerCameraManager->bShouldSendClientSideCameraUpdate = true;
}
In my MovementComponent
Right after ServerMove
Yeah thanks, would have never found that without the ServerUpdateCamera tip
@chrome bay Any chance I could sneak a peek at your GetPredictionTime? ๐
UT's has a bit of magic numbers going on. I'm wondering if you have dived into prediction for things like weapon fire much.
UT Prediction / compensation code ๐
It's crazy
Tried to implement something similar a while back but it's so tricky
The saved position bits are all pretty simple. Their prediction time though is a bit wonky. They have their own latency rpc system for tracking more accurate ExactPing. And then GetPredictionTime itself is a bit iffy. I'm tweaking values now to see what works best here.
float AUTPlayerController::GetPredictionTime()
{
// exact ping is in msec, divide by 1000 to get time in seconds
//if (Role == ROLE_Authority) { UE_LOG(UT, Warning, TEXT("Server ExactPing %f"), PlayerState->ExactPing); }
return (PlayerState && (GetNetMode() != NM_Standalone)) ? (0.0005f*FMath::Clamp(PlayerState->ExactPing - PredictionFudgeFactor, 0.f, MaxPredictionPing)) : 0.f;
}
I don't know how they determined what PredictionFudgeFactor should be. Or .0005
yeah mine is the same but I've got rid of the fudge factor, I think that's there just to get around server-side processing time
But.. so far it seems close enough
i've split off from what UT's doing a fair bit though
ahh okay that makes sense. I'm actually not including server side processing time in my ping via PingExcludeFrameTime. So that would explain why I see better results without the fudge factor
โค
Yeah I tried to ask about it but never got a reply ๐ข
That's all I can think of is processing time
I am also experimenting with .001 instead of .0005 as the magic sauce lol
Since the comment says they are dividing by 1000
Where did you ask at? udn?
But yeah that makes since that the fudge factor would be the server side processing time
nah I tried to harrass pete on twitter but he's gone quiet since FN BR ๐
but yeah ping is in ms so divide by 1,000 to get it in seconds for delta time
or mult even..
Makes sense, yeah I don't know why they divide by 2,000
half ping time ๐
ping = RTT
for some bits you only want half of it
e.g. from serv->client
It is a bloody minefield though
ahhhh
Yeah that makes sense now
I'll try with .0005 then and without the fudge factor since I'm not including processing time in ping
Thanks for the help James
nps!
It seems like there should be a better solution for getting client's ping on the server without having all these rpcs like UT does.
ServerBouncePing, ClientReturnPing, ServerUpdatePing, etc
Good time of a day ue4 multiplayer connoisseurs. I have a pretty bad performance playing multiplayer on android. Main issue are lags whenever my characters are moving across the scene and whenever launch character is executed from server(game is heavily based on launching and throwing characters around). Characters use standard ue4 char move component. I've gathered netprofile datas from devices but didnt get much information from there. Outgoing bw is averaging at 1.5kb/s across various devices. I have very little amount of replicated variables and only 4-6 players. Also there are no other replicated actors in the map. What should I consider in order to get smooth gameplay.
Game is run on dedicated server at my home network, however I've tried different routers without any successful results
@humble comet character movement is quite pricey, but to be honest 1.5kbp/s is really not a lot
Otherwise, keep the net frequency of your actors as low as possible
@chrome bay max seen accross devices was 2.2kb/s as on screenshot
Use ForceNetUpdate when changing properties. Useful for actors which don't change regularly
I think 95% of our replicated objects in HLL have a net update frequency of 1
default is 100
current is default 100, what numbers should I aim
Same here, I go with 1 a lot and just use ForceNetUpdate
We also use proxy replication sometimes, e.g. only sending 30 player states at once
Event based instead of having the server spin it's tires
only for special cases though
yeah
even 2.2kbps isn't high though
at least I don't think so anyway
I've cooked same game for pc, and have played with my friends, there are no noticeable lags, but movement was little bit jittery though
Have you worked with LAN James? I've ran into an issue when using ForceNetUpdate and NetUpdateFreq of 1 with it. For some reason things are delayed with LAN listen servers. It's strange and haven't figure it out yet.
I suspect packet loss is probably high on mobile
especially on wifi
@jolly siren not much LAN experience with it so far!
so should i test it on some online server?
okay, I'm sure I'll figure it out
How can I check if an actor spawned on the server is ready and spawned on the connected clients? Basically I'm sending a reference of a newly spawned actor from server to clients using multicast, but the reference returns invalid because the actor is not yet created on the clients when the multicast is called from server. Adding a delay fixes the issue but is of course not a reliable option. How can I do this in a better way?
You can't really. You can never guarantee any actor is valid on the client at any time
What are you trying to achieve with it?
I'm spawning a child mesh in an actor. I want all of the replicated copies of the parent actor to hold a valid reference to the child after the server has spawned it.
Then the parent actor should just hold the reference as a replicated var
Not have it set via a Multicast
You still can't guarantee that the child will be valid before the parent has replicated that change
but reflection will match up the pointer when the child replicates
yeah but that's not really an issue, as the code that requires the child reference is never executed shortly after the child's creation
So the parent may resolve to a nullptr on the client initially, but it will be corrected once the child is created
and with an invalid check the worst that can happen is that the code doesn't fire
which is just a cosmetic effect
so not an issue really
GG
simplest approach is sometimes the best ๐
Yeah but sometimes I overthink the issues way too much ๐
Hmm I wonder if that fudge factor was actually for interpolation delay
Anyone know how to calculate CMC interpolation delay?
@humble comet your first step is to determine when does the movement feel jittery, server, client, does client see other clients smoothly, and only his pawn jittering (most likely case, CMC autocorrecting your movement, but can be something as simple as you setting and replicating rotation to server, then replicating it back to the owning client because you did not use SkipOwner replication condition)
if i use SpawnActorDeferred() and set an OnRep variable before finalizing the spawn, will the OnRep function trigger?
@graceful cave Wait, were you talking with me?
@graceful cave no
Thats good to know
listen server was roughly showing the same issues
Ik i dont know crap bout mp but recommendations on best hosts for game servers for my games mp
Self hosted cloud etc
Dedicated
@humble comet its a tough issue - if you do it from the server, then all get launched with the same impluse vector and server will issue movement corrections as they fly (as clients say the aren't where server wants). However.... there is going to be a startup lag. If you can gameplay-wise cover that up with a launch particle or windup - then you can hide the delay.
If you try and do it client launched then everyone's timing will be off and probably the launch vectors won't match. And if it is server auth for its movement - then you'll see tons of correction jitter.
@hallow turtle so are you saying that I should stick with server launched version instead of multicast on all clients?
I was hoping that launch character has lag compensation in it
Unless it is something that you do a tearaway on (aka: Fire and forget) then server launched would be generally the way to go.
ps my current setup uses only server calls of launch
If it was for something like - "Launch this ball into space - but it doesn't affect gameplay" - then multicast of "Apply this vector to this ball" would be good.
If you have a repnotify int for rolling in a direction (0,1,2,3 are different directions), in the OnRep function should you set the int to -1 after the rolling montage since if it isn't set to something new and the person rolls in the same direction, the OnRep will never be called?
yeah that's fine kyle
I'm calling the same function on a bullet kill as I call from a melee kill, only thing that changes is launch velocity (for the dying character) but for some reason the server and client don't match only on a melee kill
https://gfycat.com/pinkeasygoingbrocketdeer
Looks like the client teleports the dying player out into the ether for whatever reason. It also looks like the ragdoll might not be working also.
it's weird that it would work differently for a melee kill vs bullet kill because it's all the same logic up until the part where it decides which direction the body flies
okay - closer to a solution for this ^^
When I don't multicast the "KillCharacter" event, the bullet death happens the same way
i've spent two days trying to make a working, replicating cosmetic beam for a LG (lightning gun, lazer) style weapon in an fps. for the life of me i cannt get it to work in all situations at once. how would others approach this i wonder?
@gusty lily you don't replicate the cosmetics, you simulate them
right. so mirror things for player, server and other players separately. sounds good. any good resource for that?
each client should run its own logic for all cosmetics
independently
you won't find a tutorial for anything so specific
@unreal pine you sure your instigator is good there?
on the client
cheers
I'm stuck trying to get some custom movement abilities to replicate correctly, if someone is willing to have an extended PM convo with me to help me learn how this stuff is meant to work, it would be greatly appreciated
Has anyone ever had an issue where they were using a Multicast and the Input on the function was null when called on the Client? It's there on the Server, but need it on Client cuz passing it into UI-related stuff.
No idea what I'm doing wrong, lol
hello again, quick question:
CopyProperties() in the PlayerState. Does it only get called on seamlessTravel?
side question: Is there a way to browse ue4 source quickly outside of my IDE? somewhere online?
the API doc only lists function names and parameters iirc
Github.
oh yeah, I'll try that, thanks
It gets called on seamless travel and disconnection
Are you asking if it gets called for nonseamless travel?
nah, disconnection was what I was looking for. I can't UE_LOG something in my overridden function though
i'm not sure yet
it just doesn't print the message
like the function doesnt get called
but if it does like you say, I'mprobably missing something else
It does, like i say ๐
np
sorry @winged badger I went to sleep ๐ Which instigator are you referring to here?
there was an instigator for melee in that blueprint event
if that is not valid on client, its forward vector can be any kind of junk value
@north swan CopyProperties gets called server side only. Just a fyi
ah yeah, right... it's good. he always moves in the proper direction, but not before getting teleported on the client
That looks fine. It should log to your visual studio console
unfortunately it doesn't
it doesn't even hit the break point I set in the original APlayerState::CopyProperties()
with what binaries @north swan ?
Does anyone have any fixes to this issue? https://forums.unrealengine.com/unreal-engine/feedback-for-epic/1346282-impossible-use-ue4-for-a-coop-or-mp-listen-server-game-due-the-unfixed-network-errors-since-4-years
Take me about one week to find out the problem that I see the clients in my game with teleporting/lag/jitter error. No one know or have clue and there is no docs
Listen server client sees the host moving smooth, listen server host sees client choppy even though both are smooth on dedicated server
@balmy gazelle Since this is your thread and is a bit old, did you find any solutions?
@winged badger both binaries in C:\UnrealProjects\PROJECTNAME\Binaries\Win64 and running via command line with -server argument dont work
editor binaries or not*?
sorry i'm not exactly sure what you mean (my fault).
I'm using a source built ue4 version 4.21. Development Editor/Development Server for project
dev editor can catch the breakpoint in the engine code
and CopyProperties runs every time you change the map
if that includes changing the level, sure
like going to main manu, which is on a different level
oh maybe it was that, I gotta check
if you do not change the level, there is no reason for PlayerState to be reinitialized
and so, it won't call CopyProperties
so it wont get called when I type disconnect in the client console or simply alt-f4
right?
probably not, i don't see a reason to
okay thanks, guess I misunderstood then. ๐ฌ ๐
what5 does "if owning client" mean?
ok why can't my client use the Execute on server thingy?
the function doesn't go thru
What actor are you calling the server rpc from?
my pawn
ah shit I may have realised what it is
One sec lemme try something
nope still aint working
donno what it is
You have to make sure that the actor you are calling the server RPC on has the correct ownership
how do I do that then
Page 60 explains it
thanks
Np
yeah no I don't get it
If the object is owned by the server (not your player controller), then you can't call a server RPC on it
If it's owned by your player controller (like a character and therefore a gun that is owned by the character) you can call the rpc