#multiplayer
1 messages · Page 267 of 1
What bit of data in the door BP represents if it's open or not?
a bool? A float? Just the orientation of a door mesh?
a bool
heres the code for it
ok so the onrep of your bool Open? is where you should do the code that should run based on Open?
show the onrep function
ok
onrep / repnotify
i dont remember what bp calls it
anyway its the function that runs when Open? changes
ok
i think what yr talking abt is here
it'll be a function
show the functions for this class
you'll have one that's automatically called when Open? is changed
its this one
...how do i do that...
nvm i added one lol
so it shouldnt do that now, right
So far your code looks correct, it appears that everything that happens after ChangeDoorState is correct (IDK why you have a flush net dormancy there though)
so you need to make sure ChangeDoorState is being called when and where it should be
I'm still trying to figure this out, so it's working fine most of the time but then sometimes I get it into a state where it just causes the corrections.
I've root motion for everything enabled, so the animations should drive the forward motion, I' disabling Use Controller Rotation Yaw so that this can't be an issue.
But Why does it even cause corrections, since the client is also limited to the animations root motion same as the server. (The animations come from motion matching, if this might be of any relevance)
Hello, im using UE5.5, and currently im encountering an issue when hosting a lobby using the steamsubsystem and steam sockets.
when i make a lobby on my first boot up, for some reason, when my host server travels to the lobby of the session it made using ServerTravel(TravelURL)
the travel URL gets modified to include ?Name=Player, before the ?listen. as you can see on the second line of the log, and then due to that, clients cant find the session. HOWEVER, if i back out of the lobby, and create a new lobby as that same host, it works correctly, and clients can find the lobby and join it. The second block of logs is from the second lobby made. Any further lobbies made by that host during that gameinstance work correctly.
any insights?
[2025.08.07-17.46.22:522][706]LogGameMode: ProcessServerTravel: /Game/Maps/Menu/LobbyMenu_Map?listen //<------ correct url
[2025.08.07-17.46.22:522][706]LogEngine: Server switch level: /Game/Maps/Menu/LobbyMenu_Map?Name=Player?listen //<<<-------- externally modified i think
[2025.08.07-17.46.22:522][706]LogGlobalStatus: UEngine::Browse Started Browse: "/Game/Maps/Menu/LobbyMenu_Map?Name=Player?listen"
[2025.08.07-17.46.22:522][706]LogNet: Browse: /Game/Maps/Menu/LobbyMenu_Map?Name=Player?listen
[2025.08.07-17.46.22:522][706]LogLoad: LoadMap: /Game/Maps/Menu/LobbyMenu_Map?Name=Player?listen
[2025.08.07-17.46.33:075][982]LogGameMode: ProcessServerTravel: /Game/Maps/Menu/LobbyMenu_Map?listen
[2025.08.07-17.46.33:075][982]LogEngine: Server switch level: /Game/Maps/Menu/LobbyMenu_Map?listen
[2025.08.07-17.46.33:075][982]LogGlobalStatus: UEngine::Browse Started Browse: "/Game/Maps/Menu/LobbyMenu_Map?listen"
[2025.08.07-17.46.33:075][982]LogNet: Browse: /Game/Maps/Menu/LobbyMenu_Map?listen
[2025.08.07-17.46.33:075][982]LogLoad: LoadMap: /Game/Maps/Menu/LobbyMenu_Map?listen```
The host should move to the lobby before it creates the session.
Not the other way around
so i should be, as host, already in the lobby map, before i create the session?
Yes
You sure about that statement? Most cases show CreateSession into OpenLevel.
doesnt seem to have solved the problem, i looked online and it also doesnt seem to matter if your in the map before you start the session or if you start the session then travel to it. as the session exists with the gameinstance not a map
Honestly, I would even say all cases, but nothing stops you from creating a session after opening the lobby fwiw
What you write there is a lot of mixed up stuff.
- ServerTravel is not used to start listening, usually. You do that via OpenLevel or fwiw ClientTravel in C++, and the ?listen flag. ServerTravel is used to travel from e.g. the Lobby to Gameplay and Gameplay back to Lobby or other Gameplay maps etc. ServerTravel ensures that Clients are moved with them (seamless if possible!).
- The order of the options, so ?listen?name or ?name?listen doesn't matter at all. The URL is queried for them. It doesn't check them in order.
- Sessions and you opening a level with ?listen are two different concepts.
- ?listen causes the local player to start listen on port 7777 (by default) for incoming connections. You can actually even do that without changing level fwiw, but that's C++ only iirc. You don't need to create a Session for players to join that "ListenServer". If you know the IP and you are using Subsystem NULL in the Editor or generally, players can simply connect via
open <ipaddress:port>. The whole connections process is usually not tied to Sessions. The only exception is that some Subsystems (like Steam) remove the option of joinin directly via IP to hide the IP from others. - Sessions are just a set of information that points to a game that can or can't be joined. You can create a Session without having a ListenServer active, which people can join fwiw. But if they try to connect to the Server behind that Session, it would fail, cause the Server isn't listening yet. If you use the builtin BP nodes for JoinSession you might think it's one an the same, but Epic is actually doing the "Travel to Server" after "Joining the Session" for you all in one step. It isn't a requirement though.
- ?listen causes the local player to start listen on port 7777 (by default) for incoming connections. You can actually even do that without changing level fwiw, but that's C++ only iirc. You don't need to create a Session for players to join that "ListenServer". If you know the IP and you are using Subsystem NULL in the Editor or generally, players can simply connect via
And that means, you can Create a Session and do the OpenLevel(?listen) stuff in whatever order and with whatever delay between them that makes sense for your game.
MOST tutorials and games probably do CreateSession -> OnSuccess -> OpenLevel(?listen)
Mainly cause CreateSession can fail.
i turned on seamless travel, and now the "Name=Player" isnt being injected into the url, so clients do find the session, however, now clients cant join and i get this log in the host log
when a client trys to join
[2025.08.08-11.13.22:222][496]LogSteamSocketsAPI: Warning: SteamSockets API: Warning Ignoring P2P signal from 'steamid:76561198183756341', unknown remote connection #3532827115
in the clients log now it says that
the FOnlineSessionSearchResult is 0, boots the client back to main menu, and get this log
[2025.08.08-11.10.45:794][701]LogSockets: SteamSockets: Now tracking socket 1930157348 for addr 76561198183756341:7777, has parent? 0
[2025.08.08-11.10.45:794][701]LogNet: Game client on port 7777, rate 100000
[2025.08.08-11.10.55:787][558]LogSteamSocketsAPI: Verbose: SteamSockets API: Log [#1930157348 P2P steamid:76561198183756341 vport 7777] problem detected locally (5003): Timed out attempting to connect
[2025.08.08-11.10.55:798][564]LogNet: Error: UEngine::BroadcastNetworkFailure: FailureType = PendingConnectionFailure, ErrorString = Your connection to the host has been lost., Driver = Name:PendingNetDriver Def:GameNetDriver SteamSocketsNetDriver_2147482085
[2025.08.08-11.10.55:798][564]LogNet: Warning: Network Failure: PendingNetDriver[PendingConnectionFailure]: Your connection to the host has been lost.
Are you trying that with two different PCs across the internet?
yes this is in packaged builds
SeamlessTravel is only relevant when the Server travels from Lobby to Gameplay Map and back.
It has nothing to do with the connection process.
well it def affected it, as the only thing i changed between my first issue and second attemp was setting seamlesstravel to true in the gamemode.
without it, i have that initial problem, where the first time i host a lobby, its unfindable, then if i leave it and try to create a new one, it is findable and joinable.
with seamless travel, now its findable off the bat, but not joinable
was setting seamlesstravel to true in the gamemode
You only set that to true in Lobby/Gameplay maps. Not e.g. MainMenu.
And you should not use ServerTravel to start hosting.
And that is only used when you ServerTravel AWAY from a Level, not to it.
It will probably drop the ?name cause why keep it if SeamlessTravel keeps everyone connected.
But that should only be a thing for Clients, not for the Server. Please use the OpenLevel/ClientTravel code for hosting.
The error you get is a Steam related warning as far as I can tell.
Relay candidates enabled by P2P_Transport_ICE_Enable, but P2P_TURN_ServerList is empty
That's Steam throwing a warning, not UE.
Is this even a ListenServer setup? Or are you using a DedicatedServer?
listenserver
But the whole connection error you get seems to be Steam P2P related.
Might be an ini file setup that is wrong.
Can you show what you've changed in DefaultEngine.ini regarding OnlineSubsystem, OnlineSubsystemSteam, NetDriverDefinitions and NetConnectionClass?
ye
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/SteamSockets.SteamSocketsNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")
[OnlineSubsystem]
DefaultPlatformService=Steam
[OnlineSubsystemSteam]
bEnabled=true
SteamDevAppId=480
bInitServerOnClient=true
[/Script/OnlineSubsystemSteam.SteamNetDriver]
NetConnectionClassName="OnlineSubsystemSteam.SteamNetConnection"
Hm I would suggest removing this bInitServerOnClient=true
mind you these are changes i made after upgrading to 5.5 from 5.4
in 5.4 everything was working, when i went 5.5 it was busted,
and this ini file is after finding what to change and add for 5.5
That boolean will cause Steam to init a Server locally.
const bool bIsServer = IsRunningDedicatedServer();
bool bInitServerOnClient = false;
GConfig->GetBool(TEXT("OnlineSubsystemSteam"), TEXT("bInitServerOnClient"), bInitServerOnClient, GEngineIni);
bool bAttemptServerInit = bIsServer || !!OSSConsoleVariables::CVarSteamInitServerOnClient.GetValueOnGameThread() || bInitServerOnClient;
UE_LOG_ONLINE(Verbose, TEXT("Steam: Starting SteamWorks. Client [%d] Server [%d]"), !bIsServer, bAttemptServerInit);
// Don't initialize the Steam Client API if we are launching as a server
bool bClientInitSuccess = !bIsServer ? InitSteamworksClient(bRelaunchInSteam, RelaunchAppId) : true;
// Initialize the Steam Server API if this is a dedicated server or servers should initialize on clients
bool bServerInitSuccess = bAttemptServerInit ? (InitSteamworksServer()) : true;
GConfig->GetBool(TEXT("OnlineSubsystemSteam"), TEXT("bInitServerOnClient"), bInitServerOnClient, GEngineIni); that is your config boolean.
And that causes bAttemptServerInit to be true.
That will cause Steam to do InitSteamworksServer
Can't promise that fixes anything, but that shouldn't be there
Input variables not being used is sus
maybe it's about backward compatibility though
It's also cause the method is probably virtual so you can override it.
And then you might be interested in those properties.
ooh I see !
Hey i am creating a basic fireball ability, everything is working fine but on the client the projectile (with a projectile movement component) is kind of shaky. I checked on lyra how they did to have a smooth grenade for example but i didn't find anything related to this. The only thing is that they enabled the interpolation of the projectile movement (which i also did) but on my side there's no improvement. So my question is: "is there a way to interpolate the projectile movement easily, or should i create a custom system for that.
Shaky or stuttery?
Shaky might be the position precision
Stuttery is probably net update frequency and can definitely be fixed by interpolation
Ive not had an issue with it. Perhaps it doesn’t really matter 🤷♂️
When you create the session doesn't matter. Most just do it before travel to determine if they should use the listen parameter. It's also more common to create the session first so that you can error out easier on like connection issues and such, they don't have to load a map just to get booted back to the main menu.
I tried to use the interpolation of the projectile movement component but i can't find any doc about it so its hard to understand how to use it
Actually it is shaky not stuttery, its like shaking even if i put the projectile speed to be really slow
is the Projectile movement component even networked at all?
afaik everyone is running their own locally
any cmc experts know if the physics volume that cmc stores in itself is properly predicted? though im not even sure if should use physics volume, but i do require some predictive way for characters to detect that they're in specific areas
Well i figured that after disabling replicate movements, it is smooth. For this projectile its not a problem for the clients to run their own projectile (which is only for visual as the logic is running on the server) but i was wondering one day if i have a more complex projectile how could i make it smooth for everyone
You need to implement your own smoothing. Turning on replicate movement will just override the location and fighting the pmc
Okay i understand, thanks !
Btw i am also doing a fire ball. Havent test with big latency, but rn i am just spawning locally on client using GAS.
Client will receive the server copy but it will be hidden.
So basically the client fire its own proxy projectile but it only serve as visual component. The real hit will only account for projectile in server instance.
There's a plan to smooth it, so when client receive the server fireball it will interpolate to servers projectile location.
But if without that and the test seems fine then i may just hold that off.
Yeah that's what i was thinking to do if i couldn't find a good solution. So you spawn a local version of the fireball on every client (multicast) ? Also, how do you trigger an event when you receive the location of the server ?
You are not using GAS?
Yes i am using GAS
If you are doing anything involving ability or attributes (e.g rpg) you should.
Yea i just execute the ability with prediction.
Client spawn first then send the direction of where the fireball is going.
The server then will spawn on its end and replicate the projectile to everyone including the caster.
But on the caster world its hidden.
No multicast. Just use GAS activate ability.
yeah ok i see
But then how do you check when the server send new location to interpolate ?
If we were on a more complex projectile for example
Like how complex? my fireball shoot straight.
Caster will receive the server's copy. I can just have a FGuid to indentify projectile that belong to the same ability.
So the caster will have 2 projectile on it's machine. It's own and the server's (when the server replicate it's copy back to client).
and when that happend, I can just simply interpolate the caster's projectile to the server's projectile.
effectively rubber band the projectile but with fine tune I can probably find the middle ground.
pretty sure this is what Unreal Tournament does as well.
BlasterAnimInstance.cpp
bWeaponEquip = Character->IsWeaponEquipped();
Returning false for the client. It was working before but now it's broken.
Source code is here
Did you debug it? Is Combat null, or is equipped weapon null?
Combat is not null neither is the weapon as you can see but I don't understand why the client can't run an equip animation.
One of those have to be null or you wouldn't get a false return.
I'm using RPC for this
Still in Development. Contribute to iprabhsidhu/BlasterMultiplayerGame development by creating an account on GitHub.
& Replicated Property, OnRep_EquipWeapon()
this actor exists in the world and it spawns vehicle when a character sends requests to it.
void ABP_VehicleSpawner::RegisterVehicle()
{
if (!HasAuthority()) {
return;
}
if (ASurviveGameStateBase* GameState = GetWorld()->GetGameState<ASurviveGameStateBase>())
{
GameState->RegisterVehicle(this, server, VehicleCount);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Failed To RegisterVehicle..."));
}
}
why it fails to get the game state? and prints Failed To RegisterVehicle
I think i'm using a C++ game state instead of a bp parent.... making it sure now loading the editor 😄 to test
yeah, in a demo level i was using a different gamestate, issue not exists anymore
I am customizing a struct container that uses TMap to store massive amounts of data. I want this container to be network-synchronized. How can I distinguish whether a player is attempting to synchronize this container for the first time? I need to send all data during the first synchronization, but only send incremental information in subsequent synchronizations.
A player guided projectile for example such as the skye's flash in valorant if you know it
Can't comment unless I go further with my own game.
For my self, I will just simulate locally. Interpolation can be added on top in the future if required. Game need to be tested first.
Yeah that makes sense, thanks for your time and responses !
How is this unwound on prediction miss?
Usually the common way to handle "replicated" tmaps, is to make a FastArray with a struct that has the key and data. Server constructs elements for this from it's own map. Client gets each fast array element addition or removal and will and add or remove them to their local version of the map.
Quick question for someone smarter than me: if I wanted to make a simple project where several different players control different parts of a spaceship, with no need for split screen, do I need to spawn a player controller for each or can one player controller use multiple controller input?
Debatable. Multiplayer?
I mean obviously. But like local or networked?
Local. If you've ever seen or played Lovers In a Dangerous Spacetime, the concept is similar but no little players running around inside the ship. Just each controller does something different in the ship. Ie, one pilot, one controls shields, several others control turrets etc.
I'm inclined to say just add players for them to begin with. Because if you ever go to consoles or anything you're already set up for it. Each set of controls can be a possessed pawn or something that handles inputs differently maybe.
That makes sense. Sometimes as you're asking questions you start to answer them yourself as well and this is where I was starting to lean before you answered. I guess the simple answer would be to make player 0 the pilot and then each of the controllable ship parts would be the subsequent players. And their pawns would be attached to the main ship pawn with attach actor to actor.
What could I do, to move a character to a location, so that the locomotion animations are still triggering, that will work in multiplayer?
You mean without Player input?
You could use the navigation functions.
MoveTo for exmaple.
It would then path along navmesh as if it was walking
Yea I tried that, but the issue was, that the nav mesh is not synced by default and it said that this will add quite some overhead to networking if one does.
Also I can only use simple move to for player controllered characters right?
I'm also curently trying ApplyRootMotionMoveToForce, but it appears to not work well with motion matching or something
does SpawnActor async load the actor class on the client before spawning and calling beginplay?
assuming the actor is replicated
I am using this helper to attach characters to vehicle. it is working for the driver perfectly but other clients glitching very badly... feels like the server is correcting their location.
void AVehicleBase::ServerHandleAttachment_Implementation(class ACharacter* Target, const FName Socket)
{
if (Target && GetMesh())
{
Target->GetMesh()->SetSimulatePhysics(false);
Target->GetCharacterMovement()->StopMovementImmediately();
Target->GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_None);
Target->AttachToComponent(GetMesh(), { EAttachmentRule::SnapToTarget, true }, Socket);
}
}
Make sure you handle collisions between them properly.
You likely want to disable collisions for the Vehicle and the Meshes so they dont try and force each other out.
Character is ignoring vehicle/physics bodies in the collision preset
and the vehicle Body mesh is also blocking only ground
their collisions has no interactions at all with each other
These are collision presets for character, pawn, vehicle
Can you show whats happening exactly?
"glitching very badly" isn't a helpful description.
I can now record a short clip yes
You might need to override some parts of the character/cmc to know to not correct when in this state?
mesh interpolation will always be trying to mess with the mesh relative location unless stopped afaik
so make sure you reason about the actual actor location and the mesh separately
I'm not exactly sure if this is the correction
the passenger is attached by server
and the driver also
for the driver it works fine, there is no glitches
for the other client want to sit with me in the vehicle have lots of glitches
vehicle mesh is the root component
of the character
Target->AttachToComponent(GetMesh(), { EAttachmentRule::SnapToTarget, true }, Socket);
you are attaching the character to the car
what I mean here is the skeletal mesh and the character capsule are seperate
do you attach the camera to the mesh (or a child of them) or the capsule component of the character?
mesh->springarm->camera
okay, then like I said you need to consider the offset of the mesh
also as a side note that is a scary number of skeletal meshes... ideally they are merged at runtime
they are my custom, no ticks or physics .. they just follow the animation of the parent
still extra draw calls but perhaps that works
would be curious to see a real profile of it (no I do not mean an fps number, I mean the actual cost of each one)
Debug draw the character capsule or just quickly attach a mesh to it to visualize where it is
I will use the merge method once time comes in future
yeah... definitely scary to set up
basically what we are trying to see here is if the character AND the mesh are moving in this jittery way or if it's just the mesh relative to the character capsule
if they are separate you want to turn off mesh smoothing when this is attached (which should be off already? I would just debug what is setting relative transform)
if they are together something else is moving the actual character relative xform
Editor just restarted after a change build, testing it now
could make the debug draw in bp or add the mesh in bp
for something like this at least
I tested using listen server, and found that if the driver is client and the passenger is server everything works fine both sides
if the driver is server and the client is passenger, the passenger client glitch
if the driver is client and the passenger is client, the passenger client glitch
what moves the car?
yeah you are going to have to debug the set relative transform
like I said
I have a rep Notify that does a lerp that's being applied every 10seconds for an aging system I'm adjusting half height and radius to keep the bounds same size as my character. But because I'm adjusting the capsule the mesh needs to have a relative offset. When applying this relative location to move down it doesn't apply on multiplayer. When doing print string test of the values its saying its being applied on server and client but visually its not working
mesh relative location will be affected by mesh interpolation
for a cmc (for sim proxies)
see UCharacterMovementComponent::SmoothClientPosition_UpdateVisuals
I guess there is BaseTranslationOffset
driver client possess the car and moves it using input keys f/b/l/r
I think you misunderstood what I meant
I don't see how the buttons are relevant here... I mean if it's a physics object, locally predicted etc
I should have been more specific with examples I suppose
void AVehicleBase::Throttle(const float Val)
{
const bool bIsForward = Val > 0.1;
const float Throttle = bIsForward ? Val : -Val;
ChaosVehicleMovement->SetThrottleInput(bIsForward ? Throttle : 0.0f);
ChaosVehicleMovement->SetBrakeInput(bIsForward ? 0.0f : Throttle);
}
class AVehicleBase : public AWheeledVehiclePawn
ChaosVehicleMovement = CastChecked<UChaosWheeledVehicleMovementComponent>(GetVehicleMovement());
this is from a default vehicle template
i just changed the vehicle mesh
Oh I should probably say
I wonder if replication is coming in for the person in the vehicle still
Debug the actor transform onrep
I can't guess what is happening here, you need to debug what moves the client locally
One thing to be noticed, if i add child actor components in the vehicle and set it to the character that want to attach to the vehicle and make it visible, everything works fine
I have to take some rest 😄 brb later
I wonder if it would be possible to reimplemt CMC jump to make it work similar to crouch or how we implement custom stuff like sprint.
I mean to make it go through the UpdateCharacterStateBefore/AfterMovement functions. I checked how jump is handled and it and it's called from ControlledCharacterMove
which also eventually calls the UpdateState functions. Comment says jump needs to be checked before adjusting input acceleration so I'm not sure if I can change this.
I'm asking because I'm working on a generic ability container that handles the abilities similar way to default CMC crouch. Works nicely with crouch/prone/sprint/dash so far but jump default implementation is just spread all over the place so not sure how to go about it
definitely is
Hi everyone,
I’ve been a dev for a few years now, mainly for singleplayer, but I’m now trying to move into multiplayer. I’ve learned the basics... listen client, LAN, etc... but the project I’m working on is a 1 player vs 1 player matchmaking system. It’s meant to be fast matches, and since it’s 1v1 and requires matchmaking, my understanding is that I need a dedicated server to handle connections, matchmaking, and even possible cheaters.
However, just like Unity has Photon, which allows 100 concurrent players for $45 per year, I did some research on dedicated servers but only found hosting services. I’d just like to know if that’s really the only option for a poor indie dev who can’t spend much money.
does anybody know my server browser only works when lan is enabled? my default engine.ini is correct and i have advertising on
pls im about to publish my game
photon isn't a dedicated server, no? I thought it was just the ability to host a server that supports that number of players
I believe steam and other services allow matchmaking. if you want both players on a third party server as opposed to one of them hosting , you will need to pay to host somewhere
my understanding is that I need a dedicated server to handle connections, matchmaking, and even possible cheaters.
This you can do through steam or eos
Yeah you can use Steam's relays or EOS' P2P to connect players without using dedicated servers
one of them would just be the host
yeah but if cheaters are a concern, then I'm guessing it's fairly competitive
so you don't want to give one player a clear advantage by being the server
1v1 is pretty shit for server density too
You can use the matchmaking stuff in steam to connect players to any kind of server. Dedicated or not.
if you want something more lightweight than an Unreal game server instance, then that's custom server territory
misread their message a little, but yeah ik
Its 1v1, but its Turned Based, so its no that high advantage
You can do that with a webserver better then probably.
yeah that can be a custom thing
I am getting confused, has anyone had this issue before?
I'm working on networked/replicated stuff. I'm spawning in an actor with BPs server side. I then attach the actor to a second parent actor server side. The reason is I want the parent actor to move around and the child to follow it. (Object on a vehicle) So far so good. Child follows parent around.
I then try to destroy the child after detatching it server side. This works on the host session but not on the client side of things. Child actor stays there. :\
The strange thing is if I don't attach the child, everything works just fine. Attaching it seems to be the cause of the failure to destroy the child.
show code
I... just found the issue. I think, if the BP is not a child to another actor, it works. Something about attaching it to another actor is causing this. I'm going to try making a USceneComponent that does what my spawner does and see if it helps.
When you make a X Actor be the Child Of Y Actor, the Y Actors now OWNS the X Actor, so, if a client, that dont OWN Y Actor, wants to Deele, it cant Delete because lacks Ownership.
You can make a RPC to the server side by the client i think maybe will work
This fixed the jitter in forward/backward state
but rotation still jitters little bit
void AVehicleBase::MulticastHandleAttachment_Implementation(class ASurviveCharacter* Target, const FName Socket)
{
Target->GetMesh()->SetSimulatePhysics(false);
Target->GetCharacterMovement()->StopMovementImmediately();
Target->SetCanMove(false);
Target->GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_None);
Target->SetActorEnableCollision(false);
}
void AVehicleBase::HandleAttachment(class ASurviveCharacter* Target, const FName Socket, const bool IsDriver)
{
if (Target && GetMesh())
{
if (!IsDriver)
{
Target->GetCharacterMovement()->bIgnoreClientMovementErrorChecksAndCorrection = true;
}
/*Location, Rotation, Scale*/
FAttachmentTransformRules NewAttachRules(EAttachmentRule::SnapToTarget, EAttachmentRule::KeepWorld, EAttachmentRule::KeepRelative, false);
Target->AttachToActor(this, NewAttachRules, Socket);
MulticastHandleAttachment(Target, Socket);
}
}
the actor class also has a virtual function OnRep_AttachmentReplication you can override
yeah it is virtual and called when the replicated actor has something attached/detached
UFUNCTION()
ENGINE_API virtual void OnRep_AttachmentReplication();
UPROPERTY(Transient, ReplicatedUsing=OnRep_AttachmentReplication)
struct FRepAttachment AttachmentReplication;
Exact issue as mine
https://www.youtube.com/watch?v=rDSHA7c6GIo
If you've ever banged your head against a wall repeatedly in response to endless network replication issues involving moving physics vehicles and character pawns, this might just be the video for you!
I try my hardest to quickly explain how to fix the most annoying network replication issue people seem to have; the dreaded client side jitter wh...
actually its called when the actor itself is attached/detached to something
well only for clients though
Hello,
Does anyone has a way to use **OwnerRelevancy with Rep Graph **? It feels its not take in account and i dont find usage in code ?
Hi, I need some advice.
I have a side scroller game, and I made an ability where you shoot a projectile towards the mouse. When I spawn the projectile I pass in a direction Vector. What is a good way to replicate this vector to the server and clients?
Should I use Target Data, an ability task, or a variable on the ability itself?
target data
I know UE has some functions for like global is this variable replicated, custom wise
I can't find any form of is this variables replicated person connection/ player, custom wise
Player 1 get data, but player 2 doesn't sorta deal.
All I see is
Everyone gets it, or no one gets it
Is it weird, or just not something you can do?
You can't make variables replicate per player really
Well, yes and no
You can make it only replicate to the owner, not the owner, stuff like that
And if your engine version is high enough you have access to net groups iirc
Lemme check the docs on that again
Mmmm no, net groups are only for subobjects
But you could replicate properties to X players through a subobject that way @halcyon ore
That or you have a proxy actor that contains the properties you wish to only replicate to certain players
And then you override IsNetRelevantFor
Hmmm, so probably more work then its worth, at least right now.
In theory I feel like you could do it with structs and custom net serialization
Since you get access to the package map of the client
Never tried it though but it doesn't sound far fetched
nvm, can't change on a per connection basis
trash
Yeah it's odd considering how often it comes up
You'd think the engine would have a way to
I kinda wanna try out my idea with custom struct net serialization and the package map
Since technically you'd be able to know who's receiving it with that
I think
I guess it would be hard to have an actor in a valid state if the property isn't always replicated
Maybe
are there any good tutorials someone could suggest for multiplayer? my game is currently local (as we didnt need to go through the hell that is replication for a university module) but since we're motivated to get it on steam its just hard to find a place to start converting it to online. It works great locally, but i dont have any idea where to start with replication or networking. Ive been tinkering in a couple of multiplayer templates that has the lobby/joining friend thing set up to learn from, but ive also got to replicate damage, hp, melee attacks, picking up weapons, environment stuff too.
So id honestly appreciate any advice anyone can give, tips or even just a general direction of what helped them learn the online side of programming. Thanks guys
Its hard to provide advice, given I usually suggest to design with multiplayer in mind, not do it later. Since it leads to stuff like this.
There honestly isn't much to do.
You kinda just gotta go chunk by chunk.
Theres no simple catch-all for it sadly.
Just gotta start from the bottom, and start to network it all.
I oddly find to better to just always design with networking in mind, even for a random singleplayer thing, or etc.
Just feels so much more correct.
Rather then going back over all my code, to make a server work.
Then, probably back over again to make singleplayer work again.
Yeah thats fair enough, and honestly if it wasnt for a grade at university it definitely wouldve benefitted us to do that, but it was more so just writing designing and testing the game to have it functional in around 4 months.
I knew id have to essentially rewrite everything to have it function online properly with the ability to have it work locally via LAN as well, and I'm honestly okay with that, I just don't have much of a good place to start. I wasn't much of a coder before I started so most of my knowledge is purely local based games
Yeah, from my past experience (BP graph modding for 4 years)
Replication can be hard to wrap your head around.
But, once it clicks, you kinda just handle it without realizing.
Some people act like you have to split your brain, cuz 2 things running the same piece of code, but differently.
So, its definitely extra hard to provide advice to a person new to networking.
Since, theres various slight different ways to do stuff.
what I've seen so far is pretty much having the client call an event that runs through the server, that server event then runs to a multicast, and the multicast runs the actual code. But having a lack of knowledge I don't know if doing that is right or wrong, but considering my health and damage doesnt work and I can't even get print strings to display, I'd assume I'm doing it wrong 😅
I'll just search up some intros to replication on youtube, possibly find an online course or something if it's still hard to wrap my head around. Thanks for the replies
Yeah, I know my advice ain't the best.
Theres just a ton of tiny things.
First thing, since your project was first made SP.
Did you setup the C++ correctly for replication (I guess i'm assuming C++, but i'd hope university wasn't BP)
Since, replication needs special Implementation functions, for the actual code.
Then, the stuff like how you can't just wildly use ROC, ROS, and multicast calls.
Cuz, they require some form of owner (ROC, and ROS), and you may not have owner setup, since SP doesn't need that.
No everything blueprint, they didn't teach us coding it was more the art side of games, but they didnt expect us to code it. It was just making a vertical slice of a game, so almost everything art related had to be done by us, but we could use templates for anything else pretty much, we just had to make it clear that such and such was used. So i have very little knowledge of C++
Ah thats my bad sorry, I didn't know there was stuff like that in there
yeah I feel like its a bit of a tall order given there are like 30 pins but there are a lot of really good "getting started" guides
you can skip the weird trivia ones you might not have the context for yet
BP multiplayer is possible but it's VERY restrictive compared to the freedom of C++ mp
but you can get pretty far with BP only stuff if you have to, its not unusable
also if you are making a small project for school or a co-op project you can avoid a lot of suffering by making stuff client authoratative because there is no need for anticheat/authoratative stuff
Sorry I was just scrolling through and opening a few links to save for later.
Yeah I know C++ and BP go hand in hand, rather than one over the other, just most of my studies have been art based so I havent had the chance or it's been quite intimidating to try get started, plus when ive been developing something its hard to search for a specific thing, even now my main issue is just replicating melee attacks, but there's still more to work on than just that.
it started off as a small project for school but the hope is to push it to steam since we've recently won a competition with the game so far and the games studios local in our city that have seen and played the game love it, not much like negative or this needs fixing feedback just like casual tweaks and polishing, but having that sort of push is whats driving us to try publish it but its pretty daunting for me anyway to try and learn something this big
your goal is to replicate different parts of the melee attack
both the fact the person is meleeing and the thing that got hit getting hit
split the problem into small parts
the like animation part and the meleeing player works, as well as the sphere trace by channel is detecting its hit a player, but it's getting that hit detection to detect it's been hit and deal damage. In the local version I was using a MeleeTrace plugin that did it for me and I'd just use a pre-made event that would deal the damage on hit (as all the characters have the same parent class) but using an anim notify state is also new to me so im not entirely sure if that works or not
Hello did UE5.6.0 really made it so that you have to add UPROPERTY() to USTRUCT members to have them replicated? In patch notes i see "improvements to replication" but they didn't detail the changes.
You've always needed a UPROPERTY marker on a property in or out of a struct to replicate it.
My code was working without that before
Hmm. I could see that if it's just grabbing the struct and passing it's full data minus anything explicitly marked NotReplicated. But I'm not sure that it is intentional. It's always been an Unreal kind of way to mark stuff UPROP for replication.
I see maybe it was because they were in TArray and they made further checks
Super weird bug. GameMode spawns character for player then gets possessed by player, in BeginPlay of character an event(sound+Niagara spawn visual effect). The event causes the character to become permanently desynced and laggy. This does not occur when the player is spawned by default pawn class.
If I disconnect the event and the particle+sound are not spawned the character is still desynced because of the event. This occurs even without any network emulation under perfect network conditions
If this is coming from BeginPlay, why do you RPC?
So all players see and hear the particle/sound.
Beginplay is an RPC out of the box and it calls on all clients and server, you don't need an extra rpc for the beginplay
What
That is not at all correct
(That BeginPlay is an RPC)
It is most certainly not an RPC
EPIC GAMES :: we need an extra special attachment function specially for attaching characters to vehicles, maybe some like
AWhieldVehiclePawn::AttachCharacter(ACharacter* NewCharacter);
I figured out the problem, the sound doesn't work even when not replicated.
There needs to be a delay
this function will handle this issue... since the already existing attachment functino is buggy in terms of attaching characters to a VehiclePawn
delay means, the character was not fully spawned and the event was executing, so 0.01sec delay can be good to go
Correct
if you want to use beginplay, don't use any rpc wit it, just call any event in beginplay, it will be alled on all clients and server
if you still want to use a multicast, put a check if server in beginplay and call your multicast
or use event OnPossessed, this will be call quickly when character fully spawned so you don't need delay
yeah, what i mean is it works like a multicast rpc, which calls on all client/server
No - it doesn't work like a multicast rpc because it isn't an rpc at all. It is simply a lifecycle method.
Correct, but in easy terms it calls on all clients/server... the same way as a multicast called by a server
No - do not spread bad information
Who calls beginplay when a character spawned?
It is not a multicast specifically due to it not being an RPC
The gamestate is what starts the beginplay process
I agreed already that it is not a rpc, what i mean was by nature a beginplay calls on all clients and server which is what a multicast also does
I mean server or client calls it?
People already have a hard enough time with multiplayer - don't say stuff that will only lead to confuse people even more
It is not an RPC. End of story.
It doesn't act like a mutlicast RPC either - because it is not an RPC
Use the correct terminology
Teach them what a lifecycle method is
that's not my answer, what calls the beginplay in a gamestate?
World Settings
Your silly little game doesn't mean diddly squat Missty. Do not spread misinformation
hmm, and which world? , there are two worlds in the game, one owned by client and the other owned by server.
I'm done with your game Missty.
Don't be angry Sir, i want to learn from you
I am just sure that server is calling the beginplay... no matter from which direction but it will be still the server in teh end
I had the two mixed up anyway - here is the order of BeginPlay. #cpp message
Great, but still there is no mention which UWorld, server or client
When you spawn something at runtime - it checks to see if begin play has already been ran. If it has, then it'll run begin play for that actor.
The server has to be the one that calls it because it relies on the GameMode - which is server only.
UWorld -> GameMode -> GameState -> WorldSettings
This solved the issue and answered my question 🙂
The GameState is what is responsible for calling begin play on clients as well.
Hi, I need a smart fella to explain something about overlaps to me.. why when playing as the server and overlapping something does it call both the begin and end overlap events at the same time.. or should that not be happening?
I'm using the pawns capsule component and calling these events on my interaction component when the player overlaps or stops overlapping with something, if the player is within range of an actor that is interactable it'll create a widget component and display an indicator widget at the location of the actor to indicate that the actor can be interacted with which only needs to happen on the client, if not then it checks on the server if the player is overlapping with the interaction overlap of an interactable actor and if so adds the actor into a Overlapping Interactable Actors array which is used elsewhere to actually select which actor to interact with, then when ending overlap for the indicator widget it'll find the right widget component, stop showing it and destroy the widget component.
The problem I'm having is with the indicator widget.. it should fade in when entering the indicator overlap and fade out when ending overlap, when I play as the server with other clients the indicator widget doesn't fade in it just appears immediately but it does correctly fade out when ending overlap.. weirdly this only happens when playing as the server player with other clients, when I play as the server with no other players everything works fine and when I play as the client alone everything works fine, but when I play as the server with other clients the issue happens.. if I unplug the end overlap event the widget correctly fades in instead of popping in so it must have something to do with the fact that both the begin and end overlap events are being called at the same time for some reason on the server player. Can anyone explain that to me?
Only happens for the server, clients always see correct behaviour.
I found the root cause of this issue when attaching a ACharacter to AWheeledVehiclePawn .... what should be done is just
if (Target->IsLocallyControlled())
{
Target->bUseControllerRotationYaw = false;
}
so my final attachment solution is: and it solved the issue permanently...
void AVehicleBase::MulticastHandleAttachment_Implementation(class ASurviveCharacter* Target, const FName Socket)
{
Target->SetActorEnableCollision(false);
Target->GetMovementComponent()->Deactivate();
Target->GetMesh()->SetSimulatePhysics(false);
if (Target->IsLocallyControlled())
{
Target->bUseControllerRotationYaw = false;
}
}
// Called by server only
void AVehicleBase::HandleAttachment_srv(class ASurviveCharacter* Target, const FName Socket, const bool IsDriver)
{
if (Target && GetMesh())
{
/*Location, Rotation, Scale*/
FAttachmentTransformRules NewAttachRules(EAttachmentRule::SnapToTarget, EAttachmentRule::KeepWorld, EAttachmentRule::KeepRelative, false);
Target->AttachToActor(this, NewAttachRules, Socket);
MulticastHandleAttachment(Target, Socket);
}
}
the output is, an attached passenger can now look around using their camera, but their camera can't conflict with the rotation of the vehicle applied to the passenger client
also this not needs for the driver, since the driver is possessing the vehicle and already using the vehicle camera for looking around
is anyone here have experience with switching levels on dedicated server for specific client?
instead of using main menu, i was thinking to move character creation to server side. so the flow would be: player joins → if they have no data on the server (first time join, no character), server sends them to a character creation level → after creation is done, they travel back to the game level. if they already have a character for that server, skip creation.
i have a few ideas how to do this but just wondering how other devs handle this kind of thing.
I don't believe there's any way to have multiple persistent levels at a time. You could load a sublevel, make it only relevant for the one client, and spawn them into it, though
for something like character creation though, it doesn't need to be on the server at all I would think?
Yeah that's what i did read.
Sublevel might be work, thanks for the suggestion.
i want players to create their own character per server instead of using the same one for all servers. it’s not just about cosmetics, player will also have attributes based on their choice like “policeman”, “thief”, “nurse” etc. so keeping it per server works better for my project.
also thinking about saving the latest character locally when logging out from a server and showing it in the main menu, maybe at a campfire or something like that. could be cool for the player to join later and see their latest character sitting there waiting for them.
I have on the Character this function:
ESGItemType CurrentItemAnimationType;```
and then, I have a set function like this:
```c++ void ASGCharacter::SetCurrentItemAnimationType(ESGItemType NewItemType)
{
if (!HasAuthority())
return;
UE_LOG(LogTemp, Warning, TEXT("Server: SetCurrentItemAnimationType: %d"), (int32)NewItemType);
CurrentItemAnimationType = NewItemType;
}```
it executes the log and the variable is replicated on the GetLifetimeReplicatedProps. then, on the animation blueprint I have the character saved on the blueprint initialize animation event and on the update event I get the character current item animation type and save it on a local variable. then on the anim graph I have it set up as the image. but it doesn't work.
if I play it with the server, it doesn't show on the clients, and if I play it on the clients it doesn't show on the other clients but yes on itself and on the server
anyone knows what I'm doing wrong?
i would replicate CurrentItemAnimationType using onrep, and call from the animation class SetCurrentItemAnimationType(ESGItemType NewItemType) and pass CurrentItemAnimationType
this way you don't need to update the variable on tick each frame
void ASGCharacter::SetCurrentItemAnimationType(ESGItemType NewItemType)
{
if (!HasAuthority())
return;
UE_LOG(LogTemp, Warning, TEXT("Server: SetCurrentItemAnimationType: %d"), (int32)NewItemType);
CurrentItemAnimationType = NewItemType;
OnRep_SetCurrentItemAnimationType();//call this manually if using dedicated server, on listen it will be called automatically
}
void ASGCharacter::OnRep_SetCurrentItemAnimationType()
{
AnimationRef->Event_OnUpdateCurrentItemAnimationType(CurrentItemAnimationType);
}
void UAnimationClass::Event_OnUpdateCurrentItemAnimationType(ESGItemType NewItemType)
{
CurrentItemAnimationType = NewItemType;
}
it works!!! thanks :) <3
it also might be possible to have the character creation done entirely inside of UI with a scene capture of something (pretty sure theres a better solution)
Is there an ideal way to set up a command interface for dedicated servers? Passing -log only enables printing, some online resources say to connect a client and use ExecServer, and I found https://dev.epicgames.com/community/learning/knowledge-base/3KEe/unreal-engine-receiving-exec-commands-on-a-dedicated-server-through-the-stats-port which uses a statsport to receive commands, I'm wondering if making a simple program on top to read from the log and send via curl is best
Look for dedicated servers manager/launcher on github, most of them are made in Csharp. Basically they command the server via command line arguments, logs and settings, some also provide update functionality via steamcmd and there is also the possibility to use RCON for example to send messages to global chat. While a full featured manager is a lot of work, you can make a simple one pretty easily. As for the exec commands I haven't tried them. The ones made for Ark and Conan Exiles are pretty impressive so that can give you a good idea of what is possible.
a bit new at making multiplayer stuff
How exactly does a player data go from like main menu to a lobby map?
How would the player data transfer work?
(making a coop game, so game save would hold all individual player data at first)
look up seamless travel
I see, thank you, I'll loop it up more in depth
Yeah, i already using in it my inventory widget for character previews.
data can persist within a SINGLE INSTANCE OF THE ENGINE through GameInstance or Saving/Loading
if you mean "how does a client send data to the server" then that'd be through an RPC (run on server event)
oh yeah, they could just load the same data again
This is multiplayer so I presume they're asking about how to talk to the server on connection
yeah, was confused about the connection part
In that case, it'd probably look a bit like the client loading some data, then sending it to server so the server can host it on their authoritative state of the world
It's all some combination of save/load and rpc
sounds about right because all clients need to have some data of each individual players
What are you talking about specifically, give an example.
Character name? Full save game? Something in between?
name, item loadout, custom character appearance, etc
Yes that'd be in a savegame, and you'd have an RPC to send the data to the server so they can apply it to whatever
gotcha ty
just make a struct representing all that data and it can be your payload for savegames and for the rpc
handy!
Hi, anyone got any ideas about this? #multiplayer message
stick some debug print nodes at the beginning of the overlap events to be sure.. they shouldn't be firing at the same time
also not sure if this is part of your problem but the Play
Animation node returns instantly, not after the animation is done
has anyone ran in to the problem where you cant update relative location of a mesh on multiplayer I have tested my code with print strings and it replicates on server and client but when i plug it into the characters mesh it never replicates correctly.
the variable that is driving it is correct
character movement component right? i believe it has something to do with the smoothing.. theres a function you can call on the character actor at begin play to fix it.. CacheInitialMeshOffset() i believe
so what im trying to do is adjust the height of the character as it ages. i have the mesh updating correctly but the capsule component is wrong after age= Y and then the capsule needs to be bigger im adjusting the half height and radius to suite the new size but then my mesh is not on the ground or in the ground depending on my character i have selected. i tried to do set relative offset and it works in single player. just not for the life of me i am getting it to replicate
I feel like the character moevement is playing with me i tried to set it up and do a z offset on the root bone in the anim graph but it does retarted poping back to 0 then to new size looks horrid
Im watching it on the blueprint debug thing so I can see both of them firing at the exact same time when entering or exiting the overlap on the server
This is also alright at the moment, for some reason when i call DestroyComponent it doesn't remove the widget thats already being displayed so it's not causing any issues at the moment cause the fade happens correctly lol
hmm maybe the SetWorldLocation in your display indicator function is causing the overlaps to update and trigger the end overlap
i think if you tick "teleport" it would stop that
I tried removing that node completely but it still happens lol
This is what I'm seeing when using the debug thing (the server one)
corey you have much luck?
I dont think you need to check HasAuthority, what I do with my overlap is I get the PlayerController from the actor then check if that PC has a valid UI. If it does then I push the interaction widget.
The authority check is to handle the ‘Overlapping Intractable Actors’ array that shouldn’t effect the indicator widget display as that should only be running on the client i think
Can I select which world to show in the viewport when running multiplayer? Because when I detach from the player it always shows the client world. Image on left = PIE running the server, image on right = when I detach the player it shows the client
If Begin and End overlap fire at the same time you need to make sure it's about the same actor and component. About HasAuthority I find it strange because it won't switch if it is locally controlled.
Not sure what you mean mate? Like print out ‘OtherActor’ to make sure its the same thing?
The HasAuthority isn’t firing in this scenario anyways because this is just to display the widget, the HasAuthority is for something else thats technically unrelated to this indicator widget being displayed
Also the issue only happens when playing as the server playing with other clients, if you play as the server alone, it works fine.. i dont get it 😂
Yeah that's because you have this issue only when you play with other clients that I look into it. Basically your standalone has authoriy and is locally controlled (unless I got something wrong). As for your events they are custom and output an actor and a component, so it's possible that the begin event fires with a certain actor and a certain component while the end event fires with another actor and another component.
hey is there a tutorial on how to do proper portforwarding
i try to do it but it doesn't work
can i connect with remote windows dedicated server -server cmd command
and do join session/connect beacon to it
i can find its session but i can't join its session or connect to its beacon
what does it take?
afaik portforwarding shouldn't have anything UE related. When I had to host a server on my machine locally for someone else to connect, I forwarded 7777 to the local IP of the machine I was running the server on, and setup two ACL rules to let the other player I was testing the server with in, and block everyone else
You might want to read UE and OS networking logs to see whether the server even gets any request from the client. If not, the problem should be related to the settings of the host router, unless there's something else
and if I want to do this I have to also do an onrep? because happens the same. but then wouldn't it be bad for network performance?
Yeah so I unplugged all the logic on both of them and just did the print statements printing the actor and component and they're all the same and the correct actor & correct component (print is just from begin overlap, but end overlaps prints are exactly the same), I have no idea why the overlap gets called 9 times anyways which also somehow varies cause sometimes its called 4, 5, 6 times lol and even with just the print statements connected to both begin and end events they still both get called together at the same time.. no idea 😅
so, I found this very werid client ragdoll physics behavior I'm trying to wrap my head around
My steps are 1. Create default Third Person Template
- added these nodes to player character
all this is does is ragdoll the character and make the capsule teleport forwards every very seconds (my tick rate is .5)
I would think the expected behavior is that only the capsule would teleport, not the ragdoll. in singleplayer, works as expected. in multiplayer, server works as expected, but in client I see the ragdoll teleporting when the capsule is teleported
anybody have any explanations? Is CMC making some assumptions here that I can't see?
oh I forgot to mention, it's the same behavior when only the authority wire is plugged in for tick
and for some reason this causes the mesh to completely disappear for client's character on the listen server... I'm so confused
I have no idea how to solve your problem but I do remember something about physics tick being async benefits ragdoll effects
thank you for the lead at least. Although even the screenshot above isn't even ragdoll, it's just a detach to component node (I turned off ragdoll and it still does the same thing)
Why not use standard overlap event rather than custom and see if it works the same? If it does then it must be a geometry issue maybe?
Mine are custom but they aren't really, all i'm doing is using the pawns capsule component's overlap events by binding too them so I can use them inside my interaction component and then using 'Create Event' to create both of those 'custom' overlap events
Outliner gear button
You mean the gear of the viewport, or the gear of the outliner? Because if it's the Outliner one, I know I can choose the world I want to see, it helps, but I would also like for it to reflect on the viewport
I'm not sure if this is the correct place to put this, or if I should move it to #freelance-jobs or something. But basically, I'm willing to give $20 to anyone who could help explain what's going on here, as I belive it's critical to my own project
It seems so simple but yet...I'm not sure
Does anyone know why when I transition to another level my players aren't spawning? player 1 and 2 do. Players 1,2,3,4 player states are in the world and their camera is being set, but no player. Seamless travel is also on in the gamemode, I have a transition level put into the project settings too
ah i see thanks for sharing
were you able to get canyouseeme to see your ip?
because i failed that even when i did port forwarding
OK I think you need to simplify until it works, so maybe just drop an overlap box with a printstring and see what happens
Try running ipconfig in cmd (in case you're on windows). It should contain a bunch of local ips, including yours
this is a tick stuff, no need for onrep
also just use movementcomp->velocity.size for the speed directly
That wouldn’t be ground speed then 
Anyone implemented a triple jump for multiplayer? (i.e. jump higher each time like Mario) I'm finding it very difficult, especially with lag. The server lagging behind makes syncing the jump count almost impossible.
how is it being implemented?
is the server actually lagging or is it getting corrected due to a desync between client and server?
Character lands. Non-replicated jump count increases to 2, non-replicated jump speed increased, character jumps clientside.
Server still hasn't landed so when the character jumps it interprets as trying to jump while in the air so nothing happens, server resets jump timer, client has jumped, server says no client didn't jump and resets position to back on ground.
might be worth changing the movement mode
Also gas could help
does ue5 exist a "Chunked Sparse Array"? stable item address + index reuse
gas won't help with that
it already takes some effort to have abilities work with movement prediction
I'm trying to impliment a custom inventory toolbar for my game where there would be 5 slots that are not nessessarily weapons. I was using the LyraInventoryManager to store the items in and am working on the UI side of things. What I've done works so far in single player but when I drop into multiplayer, I'm finding that I'm having trouble getting my client to understand that the inventory has been altered. I figured there must be a way to hook into the inventory's array and use an event or something to listen for changes client side... but I can't quite find this. Am I missing something?
There's TSparseArray, what makes it chunked?
if the inventory is a replicated property, you can use the ReplicatedUsing specifier to call a function every time the property replicates to a client
you can then either directly call your UI refresh if it makes sense, or have it call a delegate
Silly question I once knew the answer to...
If two replications on the same member trigger, but because of the gods of networking the packages arrive out of order...
Is unreal smart enough to understand that they are out of order and not update the client value with the older value?
(I feel it should be...)
I don't know for sure if it's guaranteed to not be out of order but it is guaranteed to eventually be consistent
your code shouldn't rely on getting every state or not getting htem out of order, just should rely on being stateful
Someone told me as long its from within the same actor channel. It will be called in order.
I know for sure you're not guaranteed to get all updates
don't rely on getting 1 2 3 4 5
your code should run just as well getting 1 4 5
nope
well it will always be the latest
BUT it can skip stuff
so if you rely on that, your screwed
like if its for a state, and it changes twice before client gets it
then client could skip a state
ie server does > Chest Opening -> Chest Opened
client only recieves Chest Opened and misses the Chest Opening state
as long as it ends up with the latest state, it works (assuming no lost packets here)
in your example, the client chest will never do ChestOpened->ChestOpening due to ooo packages
yeeep, good enough for me 👍
thanks all of you ❤️
Also, just for anyone that needs to hear it:
- If the "when" it happens matter, it's an RPC
- If you don't care "when" but only the end result, it's a replicated property
👀
I dont agree. Rpc is a one time event.
Many case where people can miss it.
If you need to keep track of time then add a time stamp or some number to determine the order.
A state should never be RPC
state + when is the tough one
right, RPCs can also arrive out of order 🤔
I meant more like "if it only matters to you if you are present to see it happen", that's the "when"
If something that happened 5 minutes ago it is still relevant now, then it is probably a state and not an event 😛
probably just include a timestamp with the state and check it vs synced time in the onrep
that way you can onrep your door state but not have to hear 30 doors squeak open when you walk into a town that wasn't relevent before
C++ has some way around that right?
something like old value or some timestamp or something
if it does... I don't know about it 👀
The OnRep in cpp have access to old value
I thought it at least had old value but idk, I haven't done much with c++ networking
OnRep does
I don't see how the old value would stop the doors from squeaking tho 🤔
You check the OnRep time to determine how far ahead the door actually is.
If its already pass the zone where it just start to open then don't play the sound.
What do you convert unique net id into to make it useful?
Can't even run an equals into unique net id from playerstate
GetPlayerFromNetUniqueId or something like that aint a thing? I feel I saw something like that
Some people only use bool to represent state of the door.
If open, play open anim if close play close anim.
So when you enter the town or just join the game. you end up hearing 30 squeak sounds.
Need to give more info to address that, such as time stamp.
Hi, I'm having some trouble replicating an actor that is set to Only Relevant to Owner that is spawned during runtime.
For context, Airship_Base class is a replicated pawn class that is Owner Only, I only want to replicate the player's own ship in most cases.
In cases where the player needs to see another player's ship, my plan was to spawn a proxy Airship_Base that mimics the other player's ship with the owner being the viewing client.
That way I don't have to replicate every ship's properties to every client, only replicate to the ones who actually need at the moment.
Above is a mock testing code for the Client A, when pressed 1, it should spawn a proxy Airship_Base owned by Client A that mimics the Airship of Client B, I thought that would spawn the actor for the Client A as well.
The problem is that the actor spawns on the server, but it is not spawned client-side for Client A even if it owns it.
Edit: Fixed it, turns out Pawns override ownership stuff when spawning. Changing the class to Actor fixed the issue
What could be the issue because honestly I have no idea why it wouldn't spawn on the client
playerState->GetUniqueId() == NetId should work, shouldn't it?
At least in bluepeints it unconnects the node. But maybe thats because I'm trying to get it in game mode
Why does it matter where you get it from?
this thingy, from a player state, should be comparable to other thingy like it? (dark blue wire)
Isn't it a struct? What do you see if you split it.
Probably have sometbing to compare i dunno
it is a struct, it does have the == overloaded tho
(the FUniqueNetIdRepl extends the FNetUniqueIdWrapper)
You can't break it in blueprints.
(how did you get a network id in the first place tho? )
You can just pull it from playerstate
I was doing that from a user wodget
So I'm trying to set which multiplayer character is which class so I was trying to store the unique net id ref and then in game mode spawn from that
That thing be transient tho
The unique net id? That should be the same
from when to when? (since you are storing it)
I'm having a player set it on a mossion console
So if its not set then I'd just default to host I guess.
Though, maybe not since I can't compare it. Hmm.
the thing is, every time a player connects to a server, they might get a new network id.
And hard traveling is reconnecting so they might get a new network id
maybe a soft/seamless travel retains the net id, maybe not, I am not sure there 😛
the shape and lifetime of the network id depends on the network backend (epic, steam, lan, etc)
Cedric says unique net id is constant from the subsystem though?
I started chasing it with "go to definition" and found it being created in LocalPlayer and in World as you spawn the Player in 😛
but in network, I trust cedric with my life 😛
so do as he says
I mean, honestly, if there is a better way to get a chosen character class and assign it based on the character I'd love to hear it.
I may just be tilting at windmills. If someone logs into a listen server I'd like the game to remember stuff about them.
Unique net Id seems to be the best way to do it?
Because it persists through logins.
So... you need to persist data... across network thingies...
if only we had a wizard... that had cells...
wait, imma get the site
Can you not replicate spawned actors with flag Only Relevant to Owner?
Edit: Fixed it, turns out Pawns override ownership stuff when spawning. Changing the class to Actor fixed the issue
I've looked into the persistent data stuff but I don't think its what I'm really trying to do...
I think I want to save stuff into structs on the server side and probably replicate from there based on unique net ID
maybe a string for save game name?
or gettypehash on it
Anyone know how to truly decouple multiplayer sessions in the editor? We have a static AActor* singleton to easily access one of our classes that for some reason, since the Client's singleton spawns second as the map loads, updates the Server's Singleton, leading to call to that singleton to not refer to the right actor while playing in PIE
This stops when we are in Standalone Game (but not when loading both players as Net Mode = Standalone)
If I can't find a solution for that, might have to pull everything into the GameInstance for local singletons
you can try unchecking "Run Under One Process" in the Editor Settings under Level Editor -> Play -> Multiplayer Options
probably best to use a subsystem instead of a static anyway
You learn new things every day
I have gone all this time without knowing of subsystems
Can't use it in this case since it's an Actor, but still
just think of it as a Singleton with a definite lifetime
you can store an actor reference in one just fine
Hi everyone. I have a player pawn which is using the Mover 2.0 setup. It is working great, but when the pawn dies I want to tear it off so the pawn and its ragdoll continues to exist on the local client for local simulation, but on the server its destroyed (since a dedicated server doesn't have to simulate ragdolls and other client-side effects)
The issue is that the client-side pawn generates a huge amount of warning spam from the mover component post-death:
LogNetworkPrediction: Warning: Independent Interpolation starved: -2
I assume this is because the network prediction liason backend is freaking out because it's no longer receiving updates from the server. How do I inform the mover component that it is now operating independently? I tried changing the backend class in the TearOff() functions like so:
void ABSPawnBase::TearOff()
{
Super::TearOff();
if (MoverComponent_Private)
{
MoverComponent_Private->BackendClass = UMoverStandaloneLiaisonComponent::StaticClass();
MoverComponent_Private->UnregisterComponent();
MoverComponent_Private->Deactivate();
}
}
void ABSPawnBase::TornOff()
{
Super::TornOff();
if (MoverComponent_Private)
{
MoverComponent_Private->BackendClass = UMoverStandaloneLiaisonComponent::StaticClass();
MoverComponent_Private->UnregisterComponent();
MoverComponent_Private->Deactivate();
}
}
However this does not fix the problem at all. I assume because the backend class has been changed, but the existing backend is still operating. As you can see, even unregistering and deactivating the component does nothing.
if it has a transient specifier or not is pretty irrelevant. the unique net ID is always expected to remain the same for the same account, on steam, this is just your 64-bit steam ID
Deactivate does nothing to Mover
It's component specific and mover doesn't implement it at all.
@hybrid zodiac have you tried UninitializeComponent() ?
@latent heart UninitializeComponent doesn't help 🙁 Still spams
Very annoying, I'll dig into the examples and see if they have any death mechanic in place
Maybe actually destroying the component? If that's even possible.
It may not even be the component.
It may be the backend having a registered component that is then like, "where'd you go, bro?"
Yeah destroying the mover component does nothing either
Seems like Mover is determined not to die
maybe you could manually call UnregisterInstance() from UNetworkPredictionWorldManager
it's a world subsystem so you can get it through the world.. not sure if it would have side effects though
Sounds a good idea!
I'll give it a try 🙂
@tardy fossil To unregister it, I need a FNetworkPredictionID. Do you know how to obtain this from the actor? (if it even can be obtained...)
Maybe the cleanest way to handle this is to destroy the original pawn entirely, and spawn in a new "dead body" actor instead
You really shouldn't need to!
Agreed
But the mover examples has nothing in there to show how to cleanly "tear off" the mover component. You'd think that would be an obvious use case given how ubiquitous death is in multiplayer games
Maybe there's a way to switch it to standalone simulation
well i did a little bit of digging and saw it's actually stored in network prediction component class but under a proxy class which is protected..sooo this probably isn't the way
maybe you could just unregister/destroy the network prediction component too?
Does it make sense to replicate a boxcomponent? It does not have any replicated property, but when I replicate it then nothing happens and when I create a local copy I get this warning: Warning: FNetGUIDCache::SupportsObject: BoxComponent <Component> NOT Supported. I can silence this by adding replication to it but it does nothing anyways.
It's not a defaultobject but created dynamically in runtime
I'll see if I can manage that, thanks!
That's what UnintializeComponent does and that doesn't work.
It looks like BoxComponent->SetNetAddressable(); also silences the warning but it does not seem very useful in this case
it is not a transient uproperty, it has a comment from epic saying "this is transient, it will probably change with the date of the login, you shoulnd't use it" 😅
but then again, epic comments have lied to me before 😛
Then it's probably a lie because I've never seen it be ephemeral on any platform
This property is often used for server persistence, backend lookups, forcing server bans, etc, for years
And I'm yet to learn of an OSS that deviates
I'm trying to use it to load save data on the server side of a listen server...
You can pull it from playerstate in blueprints but it won't let me find out if it equals anything so I'm not sure how to match it.
Does BP not have a string conversion?
Do you just have to match it in c++?
Also anybody know if you've gotta over ride copy properties if you're loadimg from there. Probably running GAS on playerstate.
BP doesn't have a string conversion.... built a c++ blueprint function for it yesterday though. I think I'm making progress but just struggling with data persistence.
i think that unique player id does change when using the null OSS since theres no backend login service, but every other OSS its persistent
there's a cvar for enabling consistent netids for the null OSS
Hey there! I've been tasked with adapting an existing system called "ATS" for multiplayer. I've been having some success with it, but there are some outstanding issues.
The first one I'm trying to figure out is that the animations don't always replicate, such as in the case in the first screenshot. This doesn't always happen, as shown in the second screenshot that is from the same run. (I'm using Dedicated Server)
I'm not very used to dealing with animations, so I'm not sure if this is a common issue with a simple fix, or at least if there's a path someone can point me towards
Hi, can anyone explain this?
Both overlaps are triggering together regardless of whether the player begins or ends overlap, how is that possible? If I play as the listen server without any other clients they don't fire together and only fire once, same for playing as the client without any other clients, but playing with the listen server and other clients connected will then fire both of those overlap event together (on the server debug) for any player who begins or ends overlap.. I don't get it lol, I know that overlaps fire multiple times because its ran for every player or whatever whenever someone overlaps so that's not unusual but how the fuck do they both fire at the same time? 😂
Server/client miss match? Maybe try printing has authority to see when the server thinks they entered and exited?
Not sure what you mean mate, it just does the same thing.. I just dont understand how it can fire both at the same time lmao
it could be anything, you need to dig more info when debugging.
print out the other actor and other components for a start.
All the same component and actor, and if it was something to do with the actor, or meshes or components that's attached to the character, wouldn't it also print multiple times when not playing with another client (which is where it triggers only once and not at the same time as eachother)?
I would suggest to see what component or actor is actually begin and end overlap.
before making further deduction
That's what I meant, they're all the same
and correct btw, those are the exact actor and component that is should be overlapping
can someone explain to me why when You call a repnotify event you have to do it this way?
Like
Why are we using a NOT boolean
why not just call the repnotify function straight up?
Using a not so it just always does the inverse. You're setting the variable instead of calling it directly because when it does get called, the variable that the onrep is for is already updated. If you called it directly, it'd be just like calling a function locally. Does nuffin' for other connections.
It seems silly to do it that way, though.
hey, I am working on a multiplayer game and I learned some basics on how Multiplayer works in Unreal Engine (blueprints). But I still feel like I'm not quite good at implimenting multiplayer and many times I faces replication issues or don't know "proper way of doing it".
Can someone share me any way of how can I learn multiplayer properly for Unreal Engine? maybe any course or yt video playlist?
Read the network compendium by Cedric and then just experiment.
That's pretty much all there is to it.
I've used that one with UE5, despite a few changes it worked well https://www.youtube.com/watch?v=abmzWUWxy1U&list=PLZlv_N0_O1gYqSlbGQVKsRg6fpxWndZqZ
In this video we take a look at the finished project and step through each of the features that will be covered in this series. We show our functional Main Menu and its options, a lobby where players can chat with one another and select their characters for the game, some server options such as changing the map or match time as well as the abili...
Is this the one where they do RPCs in the GameMode?
oh thanks man, didn't knew this exist on Unreal engine's official channel
lol
is it still valid? like.. for ue5
Should be. The basics of networking hasn't changed in forever
If you go with null subsystem it should be ok, if you go with steam it wont work that well
But uhh - don't put RPCs or replicated variables in the GameMode
yup that's right I guess. This tutorial series based on listen server?
Very pointless, as it only exists on the server
Couldn't tell you.
It is a very very old tutorial.
I mainly just used the network compendium
haha okay
Then experiemented.
actually nothing was working for me then I grabbed this tutorial and it worked one shot
People say this all the time cause game mode is server only so 'it doesn't need rpcs' but what if i need to make it reliable?
Cedric? is that a yt channel?
Reliable how? It won't get sent anywhere because the GameMode only exists on the server.
Clients do not have it.
Check the pinned posts.
okay got it
@Corey have you checked your collision mode btw?
So you dont need to worry about that at all for game mode? Obviously you hear that you need to mark events reliable that absolutely have to get ran so it doesn't break anything under poor network conditions, but that doesn't apply to the game mode class?
Correct. It does not apply to the GameMode. Because there is nowhere for the RPC or replication to go.
Interesting, never knew that lol always wondered why people mentioned not having to use RPC's in game mode but never really understood why considering reliability
wdym mate? The ObjectType is Pawn with custom preset
I've transposed that tutorial in C++ and I don't see RPCs though, it's mostly about Prelogin and Logout stuff
Well your issue comes from somewhere, Collision Profile is a good candidate, other than that it can be that you have multiple actors spawned on top of the other but that seems less plausible.
Has absolutely nothing to do with reliability. The game mode object only exist on server. Clients dont have a copy so theres nothing to rpc from server to client or client to server.
Just that one on Server, so not a big deal
Yeah no idea lol, I dont think its because multiple actors are overlapping and it should be able to handle that anyways but right now i haven't got a clue why the both fire together lol
Its also very possible its a GMC related issue, ive asked in their discord as well to see if its linked in someway
Maybe try OverlapOnlyPawn or something like that?
When nothing worked that one worked for me though.
Read the pinned material in this channel. Wizard tips and trick and exi compendium.
Youtube multiplayer tutorial full of garbage.
sure did! I got it when its was GMCv1 tho so was only $300 before the price increase split between me and my mate.. bargin!
Last i check Matt aspald he place HP in player controller.. avoid.
That tutorial used the PC a lot so I've replaced it with a Subsystem, then I used parts of Lyra code to handle the sessions. Still it was good to get started.
He is right, youtube tutorials are mostly shit because they dont take into account context, wheres those pinned docs help explain the whole framework rather than 'use this node and this node and this..'
They always do em wrong as well lol
Using MC's when they should be OnRep's ect..
Can't rpc with sub system, they are not replicated.
Client only know their own PC. So placing any variable that needs to be known to other such as attribute is straight up wrong.
Wizard tips and trick article illustrate whats replicated and not.
No he uses PC to fire and suscribe to dispatchers, I replaced that with a Subsystem.
That tutorial isn't bad at all when it comes to networking:https://www.youtube.com/watch?v=gru6EmDmevw
Exploring how TArrays replicate in complicated scenarios.
1: How to replicate TArrays?
2: Do TArrays replicate when adding values? Yes.
3: Do TArrays replicate when you change the contained values? Yes.
4: Do TArrays replicate when you only change 1 value in the array? Yes.
5: Do you get an OnRep if the TArray was modified locally to contai nthe...
<@&213101288538374145>
Hey smart people. I'm trying to figure out a simple same-screen local multiplayer issue where I have multiple gamepads plugged in and I'm using "Create Local Player" in the game mode to spawn in additional players, but none of them are responding to input from my other gamepads.
so, were doing the NOT because, lets say, I have the flashlight, and if I went to pick up another it would NOT pick it up because its doing the inverse that it already has
but what if
I pick up the flashlight
and then drop it
and then go to pick it up again
wouldnt it not pick u p?
or i guess it would save beause whenever I pick it up im destroying that actor, and then when I pick it up it creates a fresh one
But lets say, just theoretically, i I wanted it to be whewre the flashlight is still on the ground after i interact with it, and i go to interact with it again, wouldnt it let me NOT pick it up the first time but then let me pick it up the second time?
Its just toggling a boolean value. True become false, false become true.
I know. But what I am asking is, is if I had the rep notify give me something, like a component. then it would now be True, because the default is false. Soif i wen to give it to me again, it would NOT give it to me because It is now false, and then if I did it again, it would Give it to me because it would then be true
Is what i just said correct?
Hi everyone, I'm wondering, where do you initialize all the widgets that are necessary at the start of the game? I've noticed that APlayerController::AcknowledgePossession runs before the player character and its components' beginplay on the server, whilst on the client it runs after. In my case it's causing problems because one relies on the other to be already set-up but I can fix that.
lol
I ran into this quite recently as well.
I took the advice of others, and seperated them.
So, the components/ logic doesn't rely on some visuals to operate.
The timer will still tick down every second, the points still go up with every kill.
But, then the widgets just either check on tick, or use delegates to detect changes, then read the variables.
Thus not needing a certain order of operations for my widgets to function correctly.
So, the game can technically operate without issue, if the widgets were to suddenly vanish, cuz the actual logic that runs the game just calls delegates, and hopes the widget exists
But, for me, I just constructed them all on the hud begin play.
And, since there not required in some special order of operation now, it just works.
Widgets bind to delegates, and widgets update fine.
Yeaah I'm already on that delegates type of setup, it's just that I ran into a weird scenario where, the inventory widget can't be initialized until the inventory component of the player character itself is initialized, which happens at beginplay since the component relies on a data asset. So what I did was have a delegate on the component saying "I'm ready!" but that crashes on the client because the delegate isn't bound yet as the binding happens on AcknowledgePossession which hasn't fired yet
I'll try having the logic on the hud's begin play like you said, that could work. Otherwise I'll just fix the case where the delegate isn't bound yet during beginplay.
Since I also have an inventory system.
My setup, is to just instantly bind to the inventory.
But, just detect item changes
Don't wait for any on ready.
Either the widget begins, and the inventory is ready, so data is just loaded.
Or, widget begins, and inventory isn't ready, and delegate tells it that an item changed, so the widget updates.
Does sound like your doing similar, but seems odd your delegate crashes, shouldn't they be pseudo anonymous, so null or valid shouldn't care
It crashes because the delegate isn't bound to yet, as binding happens on AcknowledgePossession which itself hasn't run yet. But yeah we're doing very similarly, I'll just have to check if the inventory is ready or not and continue on that!
Are you using some special delegate.
I don't have a ton of C++ experience, but have yet to run into a delegate that crashes if its not bound.
Isn't the whole point of them to not care about the bound thing, so null shouldn't matter?
I ran a quick test with the logic being on the hud's begin play and apparently the logic also runs on different order in server vs client, but anyways that doesn't matter anymore
Yes if a delegate isn't bound, it'll crash if you're calling .Execute or .Broadcast, if you don't want it to crash you could check .IsBound or just run .ExecuteIfBound
I have no idea what you are doing but checking if a player own something using boolean like that is wild to me.
Question about subsystems. Can they check authority?
I would like that subsystem to spawn an actor on server and then that actor would replicate itsefl to others
This would most likely be a world subsystem, in which case, you can check the world's net mode. Can also have the subsystem not initialize on clients.
They can always do Actor->HasAuthority(), if you don't have the reference to an actor then you can broadcast to an actor manager class that is an actor itself, as long as it listens to delegate only on server it should be able to do what you want.
subsystem ain't an actor
I was just asking if what I said was logically correct
I wouldn't use boolean to give a component. Why is giving a component a state? That should be something the server handle and if the client have a say in it, then server RPC it.
tldr, I think what you are doing is not gonna work anyway
then why if it's on tick it doesn't work? (the legs animations only work on server and the client that walks or only in server if it's the server)
Shouldn't OnRep, simply drive it with GroundSpeed on tick which is calculated based on player's velocity
look at Default Third Person template
https://blueprintue.com/blueprint/82aioen9/ I have it set like that
which I think it's the same setup as the third person template, but the legs doesn't animate correctly
Not the same setup..
Have you looked at the pinned material on what object is replicated and not?
Clients only know their own controller.
With your logic atm it wont go oast the cast for client as controller is null
Thus the idea of storing youe replicated variable such as the pitch and yaw in that code is also incorrect.
so I'm looking at it right now and I should do it instead of the player controller on the character shouldn't I?
Yeah the character exist on all machine.
So get rid of your player controller ref in the anim bp
Thats not gonna work for clients.
okeyyy, thanks a lot
Look into getBaseAimRotation
That should give you the player control rotation.
Not sure how you set your yaw and pitch but control rotation is already replicated.
I was setting it as this:
void ASGPlayerController::Look(const FInputActionValue& Value)
{
const FVector2D LookVector = Value.Get<FVector2D>();
AddYawInput(LookVector.X * Sensitivity);
AddPitchInput(-LookVector.Y * Sensitivity);
Pitch = FMath::Clamp(Pitch + -LookVector.Y, -18.f, 18.f);
Yaw = FMath::Clamp(Yaw + (LookVector.X * .25f), -15.f, 15.f);
}
it's the same as using the getbaseaimrotation?
I dunnoe, dont have editor on me.
But theres already replicated variable to get the control rotation.
Its already compressed too
So you have to do some math to restore the value for clients.
I'll look into it then. thanks again :)
Well start with your ground speed first.
Character should start walking now if you remove the player controller from anim bp.
I can share the code tom if you still stuck.
yeah it works :)
hmmm, i'm giving servers the ability to change their async physics tick rate via a config, but having the client match the tick rate when it connects seems to be a problem.. Theres no network data being passed before the client creates the world right? by the time any connection is made the physics solver is already created and the physics tick is set
i guess the only way to do something like that is to kick the player and have them set the right tick rate and reconnect
unless theres some way to modify what UE sends in the handshake packets
Can't you send it via the Session Info?
You can also try a beacon connection first, communicate the tickrate and then connect fully
Team, I don't want to sound too confident here, But I think maybe I've pushed the first successful rpc in Unreal history...
You can post the code here if you are not sure.
confidence and arrogance are different
you can be as confident as you wish
Trying to carry data over in a struct saved to a game instance subsystem...
And it works on hard travel. But doesn't seem to work on seamless travel.
Probably should add the subsystem to asset manager...
@thorny ore whats the GI got anything to do with traveling?
Each machine gets one when the game run and it get destroyed when they exit the game.
The lifetime doesn't relate to traveling maps.
Nothing. I was using a Game Instance Subsystem to store a struct I was updating from Game State. Everything was working fine in play in editor, but it broke in a packaged build.
I thought it was because of seamless travel, but ya boi didn't add the subsystem to assets.
Game instance always betraying me by being unreplicated and existing on every client.
I just assumed it was screwing me over again.
Game instance is never replicated.
Its created when you run your game. Its nothing to do with networking.
As mention their life time start when you open the game and destroyed when you close the game.
It does if you cheat. 😂 set a struct on it, update the struct from game state and then download it after seamless travel.
Probably better ways to do persistent data but its my first real success.
No, you can ofc pull out data from GI and send it over the network but it does not mean the GI is replicated.
It is not, only the machine running the code have access to their own GI.
For my game. Save games are saved locally.
So every client just get their save game subsystem, then send it to server via server rpc.
Replicated object / actor means that every machine have a copy of it.
In the case of GI it doesn't. Player 1 does not have a copy of player 2 GI and vice versa.
Yeah. Saves seemed like the way to do it. But this is just gameplay properties I wanted so its working.
You dont need saves to carry pressistent data you can just use the GI.
You need to question your self, who needs to hold the data , who to send, etc.
Might be easier to just have the server track and keep the state then apply it on the next map, but it really depends on your game.
E.g player scoreboard, have the server save the value.
When the travel is done, just set the game state player score to w.e stored in the server G.I
Yeah. Switched to a struct so I didn't have to repetitively set things to send to game instance. Just set member in the struct and set once.
Player Data between ServerTravels should just remain in the PlayerState tbh. Unless you actively need to persist the data between 2 servers, at which point you need a backend if you don't want players to cheat
There isn't really a need to store this on the GI or in a SaveGame.
+- the PlayerController fwiw.
UE has built in methods for both to move data from previous to new instance.
And for the PlayerState that includes players that reconnect (with the requirement to have some unique net id via an Online Subsystem to figure out which PayerState belonged to the reconnecting player).
For just moving between levels you use CopyProperties in the PlayerState or OnSwapPlayerControllers in the GameMode. For reconnecting you use OverrideWith in the PlayerState.
GI and SaveGames are only needed if you need to move data to the Server from before you connect. But since you are talking about cheating I don't see that being a thing you are doing.
Ah. I thought copy properties was firing too slow on seamless travel because I could never get player state information to persist through seamless travel.
But you're saying if you can match playerstates you can keep information?
Btw, if your save game gets too big you will need to send it via multiple RPCs. Ran into that in The Ascent.
Too slow? It's literally meant to move data from old to new PlayerState on seamless ServerTravel
Thanks for the heads up, I am at a point where I just save cosmetic and nothing else. Good to know going forward.
Lords of the Fallen 2 also had an annoying problem where saving the progress to the coop client caused the game to stutter more and more the further you got into the story.
Ultimately recorded them a video and told Bruno to forward it cause it was at some point almost unplayable
The reason was quite obviously that the data that was sent got too big eventually.
Yup, make total sense.
Or maybe it was the act of saving all together. But the saving was fine in Singleplayer, so probably the RPC
But yeah those two examples are ListenServer coop games where cheating doesn't matter
And where designers wanted players to take their characters with them to other servers/friends.
For anything that can't allow cheating, dedicated server and keeping the data on the server is a must anyway
Gotta drive to the store now. Good luck!
Yeah. I'm making a listen server game with co-op so if people are gonna cheat whatever. 😂
I'm also just an idiot. Never considered matching player states. But I did only now get unique net ids working.
Thanks Cedric.
Not sure what you mean by matching but when seamless traveling as stated by cedric, you can retain the data from the old player state from previous map.
You don't necessarily need to match them. CopyProperties calls already on the old or new one, passing the other one along.
Yeah but thats never worked for me ever. Before I was trying to keep an enum on the player and it would never remember from playerstate.
Only thing you want to have is a proper inheritance hierarchy, so your specific PlayerStates move the data they know about.
Not on the client. The server host always remembers.
There is nothing to it though. Seamless Travel is a requirement but that's about it
Oh you just have to call it?
It?
Hmm. Maybe I just wasn't getting seamless travel to work. I'll test it.
Sorry. This is just me being dumb again. I'll go print some strings. In the past the clients have never remembered anything.
Assuming you are on GamplayLevelA with a Server and a Client. The Server will need to ServerTravel to GameplayLevelB and the GameMode used on GameplayLevelA needs to be marked for Seamless Travel in its settings. Which all GameModes that are used in Multiplayer setups should be (e.g MainMenu GameMode doesn't)
Yeah. Done. But I'll double check
If you are able to ServerTravel in the Editor, without enabling the console variable for allowing it in PIE, then you aren't using Seamless Travel.
Should be set in my parent game mode.
The console variable is experimental and can lead to crashes. Best testing is done in standalone or ultimately in packaged builds of course.
But try the console variable first I guess.
Without it it will print a warning if you try to server travel seamlessly in the editor
Thanks Cedric
Anybody know the best place to destroy session? Is it just on logout? Can't rehost or join after being kicked to main.
Potentially just in your MainMenu GameMode tbh
That's more or less the clearest point at which you know you shouldn't be in a session anymore.
@grand kestrel know anything about whether we need to override FillAsyncInput() or its sibling functions? just finished reading through your github repos, and was glad to see that i had came to almost exactly the same code conclusions, but didnt see anything regarding the async input function or struct
That's for async character movement and I have no idea if epic ever got it working or not, if you're not using it then no
Anyone know how to "unregister" a mover component so when you tear off it doesn't spam the log about being starved of input? Or just unpossess the pawn.
Destroying the pawn (on server and client) doesn't actually stop the spam.
Hello everyone. I'm using the MVVM plugin and trying to replicate the uproperties of a given view model so when the server sets it, it updates the UI of all clients. Generally it works, but I'm having an issue with one of my properties. It seems that calling UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED is somehow clearing some internal flag (although this is just a wild guess on my end) and the field is not replicating/triggering the repnotify on clients. If I remove the call to UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED, the field replicates as expected. Has anyone experienced anything like that?
Nevermind, I think I found the issue and it's in my own code.
I asked this a bit ago, but something just made me think.
So, I had asked, is it bad to just have a replicated variable that barely changes, but will still change.
IIRC, someone had said that oh, its no worry, cuz the server will check if the value changes, not just blindly send it every 5 seconds and waste bandwidth sorta deal.
But, wouldn't it still have to use bandwidth to check the values between server/ client?
It doens't check the client.
It checks its own value.
If the client changes the value itself, but the server doesn't change, the server will never know that and won't replicate the variable to correct it.
How would that work with lag then?
Lag usually corrects itself, but if server is 5, and hasn't changed...
Then the lagged out client is just stuck in a limbo of 4?
Variables are reliable. The server will send 5 until the client acknowledges it. I think anyway.
Ah, ok.
Didn't realize that.
I assumed the default is unreliable.
Is there anyone who has issue about "OnlyOnwerSee" in skeletal mesh (in lyra 5.5.4)?
In B_Hero_ShooterMannequin, i add skeletal mesh component and set SKM_Manny (Used in B_Manny)
and set OnlyOwnerSee = true
but Every Client can see other client's skeletal mesh
And if i change Skeletal mesh asset (SKM_Manny_Simple), OnlyOwnerSee works correctly
anyone know how to notify a client about a gamepause event? I'm having trouble doing it because once the game is paused the rpcs aren't accepted anymore
how are you setting it?
onlyownersee/ownernosee uses the chain of owners of the viewtarget to figure out if they are "owned"
so what it really means is if they are the local view target or not
I'm wondering if it just needs to be marked render dirty after the fact or something
kinda strange setting the skeletal mesh matters
But if i just changed SKM asset, it works well. Only SKM_Manny (and quin) has issue
are you changing this in the defaults or at runtime?
First person mesh is Skel comp i just added and Set skeleal mesh in default( editor )
if i used skel mesh asset in lyra project, it has error and other skel mesh doesn't has error
fisrt skm_manny : No error / Second Manny : has error
does it support the anim instance set on the skeletal mesh component?
for First Person Mesh?
nothing. jsut new Mesh spawned at (0, 0, 0)
and if i set OwnerNoSee = true at Skeletal mesh component in B_Manny
Same issue happen (lyra SKM_Manny -> Show mesh also to owner, other mesh- > Owenr can't see mesh)
so I asked you earlier if you spawn this at runtime
No. I already add skel comp in editor
what is the log from then?
Not spawn at runtime
just in case, can you show clicking on the mesh and showing the value of only owner see on it? make sure you set the world in the outliner to the client
second check is OnlySeeOwner
and each client can see other client mesh
If i change Lyra SKM_Manny to Otehr SKM_Manny,
Each client can't see otehr client mesh
I'm surprised because that should work fine... if they have the correct outer chain to a not locally veiwed actor
I wonder why SKM_Manny from Lyra work like this..
the fact the skeleton matters makes me think something from the anim instance is intefering but for now I guess you can just band-aid and just set it to hidden when they are not locally viewed and show when locally viewed :/
First of all, I want to check out the same and different versions of the new Lyra Project. Thank you for your help
yeah I would need to debug the actual render calls to see what it thinks it is doing here
Spawn of something usually at 0, 0, 0 is also a problem caused by incorrect replication settings, but it's complicated because it's a multiplayer environment..
can you elaborate? You are having issue spawning an actor?
- Add new Skeletal mesh component to Lyra Hero Character
- Set OnlySeeOwner = true, Set Skel mesh asset SKM_Manny (provided by lyra, used in B_Manny)
- Play in editor (play as client)
- then Client 1 can see Client 2's new skeleltal mesh (client 2 can see client 1's new skel mesh)
- if i change Skel mesh asset to other mesh, It doesn't happen
are the replicated variables in the same actor component guarantee to arrive "at the same time" on the client if they are both dirtied at the same frame on the server?
nope
if you want them to arrive at the same time I would suggest making them a single struct to use atomic replication
Iris kinda does this by default for structs too afaik but doing this will work for now
hm, i have a FFastArraySerializer but i also need a way for the client to know that this variable has gotten the latest replication from the server, i was thinking to have a separate bool for the server to replicate to inform the client
or am i thinking too much? when the FFastArraySerialzier is replicated to client, it should be the most current version of the server at the time of initiating the replication isnt it?
You are overthinking it.
Changes made in the same frame will all be sent at once. The problem is that you might receive those changes out-of-order relative to other changes, so relying on atomic properties is generally quite difficult.
And in Epic's own words, Any order is considered an implementation detail that should not be relied upon
If you want to check the status of multiple replicated properties after replication, use PostNetReceive()
In non-iris replication it's possible for the client to get into a state that never existed server-side if properties change over multiple frames.
@echo bough if you can give more background on what you're doing, there might be a way around it.
i am doing a game state for a multiplayer scenario, the game should start in WaitForPlayerReadyToStart, during this state, the server spawns the players respectively, and also preparing the map for gameplay (e.g. spawn enemies, item, etc). Each client will RPC to the server when they have their Acknowledge Pawn being set to signal that they are ready to start. The GameMode wait for all player to be ready then proceeds to start the game.
I wanted to add an additional condition for the Client to be considered ready to start. All other player pawn should also be replicated on that client before they are considered ready. I was thinking to use a FFastArraySerializer to keep track of the other actor reference whether they are replicated or not.
My problem comes in, since players may join in different times during the WaitForPlayerReadyToStart state, how should i handle this properly?
The simplest thing to do here is RPC to the Server when you receive another player pawn too, and track Server-side when all players have received all pawns. I don't think you want to involve any property replication here.
naive psuedo-code:
TMap<PlayerController, TArray<APawn>> PawnsReceivedByClients; // game-mode
AMyPlayerController::Server_ReceivedPawn(APawn* ThePawn)
{
GameMode->PawnsReceivedByClient(this, ThePawn);
}
AGameMode::PawnsReceivedByClient(Controller, Pawn)
{
PawnsReceivedByClients.FindOrAdd(Controller).Add(Pawn);
if (HaveAllPlayersReceivedAllPawns())
{
// Go
}
}
AMyPawn::PostNetInit()
{
if (AMyController* LocalController = GetWorld()->GetLocalPlayerCOntroller())
{
LocalController->Server_ReceivedPawn(this);
}
}
but if i wanted to specify which actor the client should wait, it probably should be a replication of actor reference?
You can't replicate an actor reference if the actor hasn't been received yet. This is why only the Server can track whether players are "ready" or not in this scenario
The idea here is whenever you receive a pawn on the client, you tell the server about it, and the server tracks who has received what. The server decides when everybody is "ready".
This also assumes you don't have to worry about things like dormancy or relevancy.
And you'd have to re-test the condition server-side whenever players leave, or pawns are destroyed/spawned etc.
If a player joins after all the other players have been determined ready, you either set the game mode back to the waiting phase if you can, or you ignore them and carry on anyway
Keep in mind there is also a greifing/hacking opportunity here - if a client doesn't send the RPC for whatever reason, your server will stall, so I'd advise a timeout too before it progresses anyway. Otherwise hackers could abuse this by blocking those RPCs being sent.
hmm thanks for the scenario, yeah i will need to plan it out
Probably how I'd do it anyway
yeah the point where "letting client to determine things" can be a breaking point if somehow it is blocked at the client.
so the idea is to let client tell the server, "i recieved some pawn", server decides whether it is relevant to game start, and tells the player to start when condition or timeout is met
Well it's not that you'd explicitly tell the player to start or anything, the game would just naturally progress to the next stage
But regarding the timeout, what I mean is the Server only gives each client a brief window to acknowledge the pawns (a few second or so) - after that, it stops caring and progresses the game anyway.
in my case, it would be changing the game state, then that replicates to client and they remove their loading screen and such
yeah sure. To be honest, when it comes to these "waiting for players" states before games start, its usually just the server waiting for players to connect, it doesn't typically extend to clients receiving data too.
Its soo annoying that in some game, such as rainbow siege. Sometime we just get stuck at the start game.
Happend when one of the player doesnt respond but i guess its a bug because theres no time out.
Yeah, ideally you don't want to allow a way for the server to get "stuck" because it's waiting for a client to do something - or if you have to do that, you want somekind of timeout so it can't be abused
And ofc you have to make sure you re-test those conditions when a client drops out or something
if that is the case, wouldnt the start time of each player be quite different? i am thinking of games like Lost Ark where they (i think) waits for all player ready to move before starting so you get a more similar starting time(able to move, etc)
they have a timeout too
Not sure what you mean, the server is deciding everything here
Don't the server have countdown?
Perhaps their starting time (a state saying game is inPlay) is a little different by a mili second. But thats the price you pay for having big latency. Nothing the server should compensate imo.
It can't really compensate anyway, your latency is your latency, can't make it lower
Unsure if Multiplayer, or online-subsystem.
But, how do you do server side checks, without fully connecting?
Such as a whitelist.
I know games like ARK (when I started), makes a full PC, and "connects" a player, then do whitelist, and kicks.
Surely that can't be the best/ only way.
(and, same deal for passwords, and etc)
Beacons
Thanks.
Seems a bit more complex then I would've thought honestly. 😛
But, I'll look into it/ work on it.
tbh this is typically something you'd do directly in your backend rather than bother the game with it
hey
im having some issues trying to test multiplayer within the editor
im running the following settings. players 2, net mode play as client, launch seperate server true, run under one process false. with these settings it loads a completely empty map despite the default maps and modes being set correctly so i have override the game mode in the world settings witch gets the map to load. but then, my players are not spawning at the player starts and my custom pawn isnt being used, so im just an immovable ovject spawned on the outside of the map (seems to be spawned at the same location every time, but not a meaningfull location, like not at 0, 0, 0 or anything)
Is there a collection of resources for optimizing multiplayer performance?
it works fine when not using run under one process
but then i dont know what's going on. i need to debug some code, particularly for my inventory system which is all server authoritative. when i get issues with it i dont know where the problem is coming from so i want to completely isolate the server and clients to their own processes
for example when not running under one process, the server crashes related to my inventory plugin, but when using one process it never crashes
oh wait the player is spawning at 0, 0, 0, my bad
Wouldn't only big games like MMO have a dedicated backend for stuff like this?
having a backend for each private dedicated server seems a bit much?
Or, do I miss-understand, and backend means something else?
You wouldn't have a backend per dedicated server. One server could handle millions upon millions of requests.
I don't see anything wrong with rejecting a player after initial connect if they violate some condition
You gave ArK as an example, so I think that was the context he was using to give you advice.
Some people may not know what ARK is, so I wasn't sure.
So you'd have one server that would handle doing small pings to. That would have the information that you need as a joining client. Then you would just get that information when needed.
isn't that overkill for just a self hosted dedicated server?
ARK is definitely not the example for technical excellence...
what you describe should be possible via beacons
Its not info the client needs.
Just preventing the client from joining, based on server side info.
Rather then making a full PC, and connection to the server, just to close it like 1 second later constantly.
is there anything wrong with that?
Just seems a bit much?
Handle an entire client connection, taking up player slots, etc.
well yeah, it's why beacons were invented
or just do something in prelogin
yeah PreLogin is good for something like a password or handling things like a ban list. It sounded more like server slot reservation-y which is more beacon territory
if you truly don't want the game server to even know a player gets rejected it sounds like beacon is probably best
but I would think rejecting someone in prelogin is completely sufficient for most cases
PreLogin is pre-PC creation since that function affectively gates the creation of one
yeah
I guess you could get login spammed? but you can probably just temp ban the IP or something
No.
Purely just check whitelist/ password, without a full game connection.
I just know my only context is ARK, and in ARK you do a full connection, then get booted out of the server.
and, I hoped that wasn't the only method.
erghhh
I think there's even PreLoginAsync now which allows you to do an async backend query, process the result, and allow the login based on that
PreLogin is pretty damn early in the connection process so it's fine
why is the console for the server closing
it used to remain persistent so i could log stuff on the server side
is this new to ue5? a bug? is there an option to keep the console persistent?
well is it actually running and not just crashing? what launch args are used?
because it definitely works
-newconsole is even a thing
it could be crashing, lemme double check
looks like it is
yeh its crashing while trying to access my inventory data, but that works fine on the client.
is there anything with the server where it doesnt include your data tables or something?
did you build full debug and not debug game?
is it a dedicated server build?
its debug game. but im running from PIE so that should be ok shouldnt it?
its not a seperate server build
well it's not even a cooked server build so there isn't even a question of including content
so every time you need to test multiplayer you need to cook a server build after a change?
its set up as follows. my inventory system is its own module/plugin. the plugin has settings for data tables to populate your inventory data which then gets cached by the server and client to link everything with simple integer IDs so not to have to send names between client and server.
the client and server compares an md5 hash of the cache, if there is a mismatch then something is wrong with the data and the client is disconnected
those settings should hold the same data tables specified by the user in the plugin settings on the server right?
Hey guys, I'm making a multiplayer game, and for some very strange reason, my player has skills that work normally — but after a server travel, the skills only appear for the server. Even if the clients are standing right in front of the server, they can't see them.
no? if you need to test with your actual cooked server then you need to cook
what content is included with the build has no bearing on standalone
since that's uncooked
There's nothing complex about beacons. It's just a connection that gets done to the server similar to normal joining but not quite. The difference is that you use beacon actors to communicate with RPCs instead of getting a full map load and full on replication and such.
I mean. If anything. It's probably the absolute simplest and most direct way you're going to be able to get some basic info from a server or make requests to it.
It is. Which is why I said to use beacons originally. I was just expanding on Jambax's answer
sounds like you're using replicated variables but should be using rep notify instead so that client can do something with the changed value
Nop i just spawn an actor same a fireball and the server can see but the client cant but before the server travel everything is okay
if u server travel then spawn before client is ready then client doesnt have the actor
the server is attacking in front of the client and nothing happens to the client, something curios is that the client can take damage so the skills are in server but not in client
please stick to one issue at a time
can you show how you are spawning in this actor that has the replication issue?
I'm struggling with syncing stuff and replication. Thought i had it, but i don't 😖
What is the right order? Run on owning client, and then run on server?
I'm just trying to figure out Physics Handle and Cable component, and getting it synced.
I saw some tutorials to refresh my memory, gonna see if i can resolve it. But i am also struggling with physics collisions between players. I am however using SmoothSync plugin, and am not quite sure if that handles physics aswell
Hi all! I've been banging my head against a wall with an issue and was curious if anyone had thoughts. I am using SteamSubsystem w/seamless travel to manage multiplayer. I have a lobby with a lobby controller, lobby hud, lobby character, and lobby overlay and game mode. I am able to get players into the lobby and then go to the main game. The main game similarly has its own controller, hud, character and overlay and gamemode. After the game is over, I server travel everyone back to the lobby. Now here is my issue, everyone comes over properly and the hud and overlay and character look good, but for some reason the Lobby Overlay no longer works. the buttons just stop working. I'm wondering if I'm missing something obvious, why would my Overlay react differently the 2nd time I am coming back to the lobby?
I am not using PostLogin to initialize stuff since I know that only happens once. Another weird thing, when just doing this with 1 player, (the server) this issue doesnt happen, but when there are 2 players it happens.
My goal is network efficient projectile system. I'd like to build something that does not require a replicated "bullet actor".
I am using GAS to call a func which spawns a BP_Bullet on the server and a BP_Bullet on the client. Those bullets are fed the same trajectory and speed. BP_Bullet is not a replicated actor.
On the BP_Bullet's tick for both client and server, I move the bullet along the trajectory at the given speed, at the time it is scanning for collision hits.
On Server's hit, the bullet passes damage.
On Client's hit, the bullet leaves an impact mark, makes sound, and triggers anim reaction (if hit character).
Everything is working with my setup, but I notice that sometimes the bullets get desynced just enough to miss characters. Resulting in a false positive hit client side - bullet stops, blood is spawned, but it wasn't actually a hit on the server.
What are my options to get around this false hit without having to replicate the projectile actor? Should I reconsider this approach in general?
What's an overlay? Widget?
Are you using console controller? Wdym the widget stop working, like you cant click buttons?
i'm trying to make backwards reconciliation for hitscan in my fps. i have a perfectly accurate network synchronized clock that re aligns itself every few seconds, and all my characters record info about themselves 60 times per second on the server. when the client shoots, it sends an rpc to the server requesting a shot and providing a timestamp, and its camera location and rotation, and the server sets all the players back to where they were at the specified time using its records. however, there's like 20-40cm of error if there's a decent amount of latency. i think this is because the server sees different things than the client at any given time, so does anyone know how i would work around that?
The client has to tell the server the timestamp of the enemy data too
Server needs to roll back the enemy to that timestamp and then perform the hit validation
Without that the server won't be testing the correct enemy state against the hit
hmm
so theres a communal list of data
and the client just tells the server which one it wants?
If a player runs in a straight path, they themselves have the newest data and are the furthest along that path. The server will be next and the other clients will see that player the furthest delayed.
So when you tell the server to validate a shot, the server will already have progressed the other players further. The timestamp you send must be the one of the enemy you hit, so that one can be rolled back to the point that the local client saw.
No what the shooting player sees
Every pack of data that defines the position of a player has to also contain a timestamp.
So that the local player can tell the server what replicated data they saw
so when the server sends movement data to the clients, it attaches a timestamp?
That would be ideal.
so how do i do that
The timestamp under which you also saved what data to some history on the server so he can roll it back.
Might be enough to have a replicated property in the character. They should replicate together then.
ok
But you would need to test that
What's your movement math?
On Tick I move the projectile CurrentLoc + (Trajectory*DeltaSeconds)
I run a trace OldLoc to CurrentLoc, and if I collide with a thing, then stop tick and trigger an OnHit event
GPT suggested a solution that works, but I am not sure if it's so clean.
I've changed Server projectile to instead multicast the OnHit event, then on client side's OnHit, I reposition the projectile according to the server's passed in hit loc, and then trigger projectile effects at that location. I get a little bit of weird warping in my bullet trail when I relocate the client projectile, but I'm frustrated enough with bullets to call this "good enough".
How to correctly resync state / play montages from the right position in multiplayer?
For example, there's an event N where an actor must play a RootMotion animation (an AI character passing through a door). On the server the montage starts immediately, but on a client the OnRep() that triggers montage playback may arrive with network delay. The result is that the client starts the montage from the beginning, while on the server the montage is already further ahead.
How to properly synchronize montages so that the client starts playing from the correct point in time (not from frame 0) and stays in sync with the server’s RootMotion state?
To complete the question:
Is it a good idea to play AnimMontage in multiplayer via OnRep() structure, which will contain
- The montage itself
- TimeStamp taken from the server to take the delta from the client?
I would suggest to use GAS play montage
depending on the effect that you want, some things are more involved.
well, I've already made a component, which takes an array of this structures, and according to server's timestamp plays montages. If I need to play montages one after another, I just need to calculate timestamp when it will be played (server time + animation length) When OnRep() comes to client with network delay, component calculates delta between this events and outputs StartTime for montage. If delta is too big, montage gets skipped.
Works like a charm.
GAS is, in my opinion is a bad decision, because in order only to play correctly replicated montage on door I need to give it an ability.... It's too overcomplicated for such a task.
wouldn't a "delay" be acceptable anyway because everything else is?
though I wouldn't have thought something event based like playing an animation would use an OnRep
How far in do you want to be in sync? if the player is delayed enough the animation will skip too much from the offset.
It feels a bit of a solution looking for a problem. Like everything you get from the server is going to be delayed by at least half RTT
but an OnRep is still a bit of an interesting choice because that'll be bound to the net update frequency of the actor
if client delta > animation length, it should not be played at all
which would introduce more delay
nope
this is only visual
what delay lol
ok, I'll record a video to show
just wait a bit
well you're the one talking about delays,
and for something that's an "event" why is it not a multicast?
this what you get if you simply play animation OnRep()
door has small NetCullDistance for demonstration
AI had already walked through, animation will play from start
which is generally why you don't do event based things (playing a transitional anim, spawning particles, etc) in an OnRep
once you are in relevancy distance, then it runs
this is montages via component
For simple doors like this, on Beginplay set it to the current state of the property open or closed. On open or close, multicast it and play the montage based on direction.
If it's not in relevancy range it won't multicast to said client. When it is in relevancy range it'll beginplay.
There are 4 montages, 2 for AI to enter, and 2 for exit.
When the client gets the info, it should be properly replayed in sync with server
all this to avoid a multicast
multicast doesnt' work at all, lol