#multiplayer
1 messages · Page 188 of 1
I have a feeling they will ditch it and put the guts into the Liason
because it literally has had 0 action
Their comments on the PR seem fine though
is putty safe?
what you people used to work with your linux vps?
I mean it also doesn't need much more than the PR. It's in a good base spot fwiw
Yeah, solid
Cool, bye bye Mover
Would you mind if I had few question about Iris?
I am not at all an expert about Iris
Yeah we aren't using Iris so that's not a problem for us haha
but I can try
I assume we might in the future. Will just have to fix Mover then.
but it only supports 10 files max transfer per que?
Yea I ended up using the OG network model, using Iris without being compat with the original network system is a mistake
Mover is deffo fixable, I think it just needs a couple net serializers implemented
It's all about the net serializers yop
but the fact that Mover hadn’t at all been tested with Iris made me uncomfortable
I mean Iris isn't really used yet by the majority of people either
Most cryptic docs ever
subsystem is itself the name of a problem, try t build your own master server and get rid of all these subsystems
yea but it’s still surprising that literally nobody but me seemingly had tried
that was kind of worrying lol
No one? Like we were pretty aware of this when considering Mover
Ah well maybe, nobody had publically made it clear that it didn’t work and there were no comments or PRs about it
It's also not used publicly
I doubt there are more than 5 actual projects using it
Mover that is
fair enough
UDN probably has some stuff about it
But probably locked to some private thread
IF mover and npp are followed up on they will need 2 - 3 more engine versions
They did add more stuff again to mover, like motion warping adapter and instant moves
So at least that is somewhat progressing
2 - 3 more engine versions before the majority of users would pick them up fwiw
NPP won't solve much though. You can't put everything into NPP simulations. Some stuff just isn't made for it (like inventories)
So you'll always fight the GAS <-> CMC problem somewhere
And mover isn't as BP friendly as I originally hoped it would be
I mean it's more that NPP itself doesn't work with iris for who knows what reason. It should just be missing netserializers, idk why they haven't bothered to implement them if even GAS has done it.
It does make me wonder when they're going to move fortnite to iris though, doesn't UEFN now use mover? Which means they can't use iris until that's fixed.
It still requires a lot of c++ boilerplate
I don't think epic uses mover
Epic uses CMC and some chaos physics stuff
I was under the impression they were moving to it for physics-based movement
ah, it's separate then
The Lego stone replication is chaos and only net auth
Thanks, I am trying to create a simple team replication where it replicates actors with team ID to a correct team connections. (Basically redoing some basic nodes from my RepGraph in Iris).
First idea was, lets do a filter. So I found correct DefaultEngine.ini commands to register it but the bloody UNetObjectFilter is not exposed. Sillex mentioned I should do it with groups.
So I did something like this
FNetObjectGroupHandle GroupHandle = ReplicationSystem->CreateGroup();
const UE::Net::FNetRefHandle ActorRefHandle = ReplicationSystem->GetReplicationBridge()->GetReplicatedRefHandle(Actor);
ReplicationSystem->AddToGroup(GroupHandle, ActorRefHandle);
Ok, I have gruop but how do I work with the group now? I can add it to AddExclusionFilterGroup or ExclusionFilter but that seems to be for all connection, not a subset. Do I still need a custom filter to put the group to?
I just want to cry at this point, what is the correct way to do team-replication?
Mover has physics stuff in it
nah I wasn't talking about lego
Npp physics is kinda unused
I was thinking of some demos they had for UEFN involving physics-based movement for fortnite characters
I can't imagine them using it for movement in FN or UEFN
It's not there yet. It would be way more improved by now
Well maybe but it would surprise me
tbh I can't even remember where I saw it so it might have just been CMC interacting with physics
We coded a bunch of mover modes by now. Added the fixed tick smoothing etc. and it still feels like it's not where it should be
We now try to add something to it called movement features. Cause it's not modular enough
Can't go into details though
I'd take iris over mover right now anyway, perf benefits are a no-brainer. Not like you're getting good docs with either one 😛
The project is already fully setup on the rep graph iirc
So iris is probably not so important for them atm
I do wonder what epic sees as the migration path from repgraph. Some of the perf you get with iris makes bits of repgraph unnecessary, but the sort of recursive nature of repgraph is still useful for some things. I guess they expect you to use simple spatial filters and manage the rest with groups yourself.
Mover was way more important due to having weapon system etc run through NPP in sync
Iris replaces it or not?
repgraph and iris are strictly incompatible
repgraph only works with legacy replication, and there are no plans to make it work under iris afaik
RepGraph seems like Iris 0.1
it's not
they work in entirely different ways
repgraph wasn't even a step towards iris, it was a hack on top of legacy replication to eek out the last bit of perf they could
They have a lot of concepts in common that were not in the legacy replication though, like the spatial/grid system, or prioritisations. I think they learned a lot from RepGraph and translated that into Iris, but that is just my opinion.
none of those are specific to repgraph
prioritization exists in legacy replication, it's not from repgraph
Not messed at all with filters, sorry
Thanks anyways, your comments from the last few months in various places were the only pointers 😄
Ah no worries ahah, sorry I can’t be of more help
Yes - you can set the group to be an exclusion or inclusion filter and then choose whether individual connections get affected by it with ReplicationSystem->SetGroupFilterStatus
So to send objects only to a specific team, make a group for the team, set it as an exclusion filter, then call SetGroupFilterStatus for each connection on that team with UE::Net::ENetFilterStatus::Allow
and ofc you'll need to update the group filter status for a connection if they change teams or join in progress or w/e
group filters seem like the main way forward for custom relevancy. Outside of the basic filters (always relevant, only relevant to owner both of which are supported out of the box by iris) and spatial filtering (the net grid filter) most other things should be doable with net groups. Just means you need to think about it a bit differently since it's not constantly polling your object for relevancy.
it also means you can setup groups per-object instead of just per-actor, in theory you could filter out subobjects/components while keeping their parent actor though I haven't tried.
I owe you a beer, thanks!
@hollow eagle Thanks for sharing 🙏
I don't know if this is the best channel to ask, but for folks running a dedicated server in a Linux environment; what do you use for process monitoring & heath checks?
I'd like to setup something where I can get a notification when the server process crashes or errors. I'm in AWS, is there's anything out of the box that I can play with?
On AWS I am using Gamelift that already has SDK with health checks etc.
You can catch logs and unexpected terminations
GameLift feels like the answer, but I could not get the SDK to work. There's not much YouTube content and I struggled to comprehend the AWS documentation. Any advice or recommended links to share?
Gamelift comes with some drawbacks I don't like, for example the complete control over the spinups of the servers. But if you are happy giving it a try, you need to compile the sdk yourself. I did it for 4.27 but still works well. Followed the official tutorial from aws (i think).
https://docs.aws.amazon.com/gamelift/latest/developerguide/integration-engines-setup-unreal.html
The SDK will freeze (while True) the whole game server on startup, be aware of that! It will listen for gamelift session creation call without any debug message.
The setup will take a bit of time but you can quite easily develop with it locally using the local Gamelift (java) manager.
Thank you, this is helpful. I'll give it another shot.
I have it integrated with step functions and lambdas to handle the whole game server lifecycle
I am almost ready to pay someone to debug this for me. I have a C++ class declared as follows (only relevant details show to save space)
UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class DCSINVENTORY_API UDcsInventoryItemInstance :
public UObject
{
GENERATED_BODY()
public:
UDcsInventoryItemInstance();
virtual bool IsSupportedForNetworking() const override { return true; }
I also have a blueprint class, BP_GameItemBase2 to use as a base for interactable items. It has a variable InvItem that is defined as the type above and it is marked Replicated. It is created on BeginPlay as shown in the screenshot below.
Individual items are in other blueprints are defined as subclasses of BP_GameItemBase2. In particular I have a Cone item and a Box item. The cone item works fine, but for some reason the box item never gets the InvItem variable replicated. That variable is always undefined on the remote. The Box item does have it's own begin play, but in it I am calling the parent beginPlay. I've got print message in both BeginPlay graphs and both are printing out.
But when I go to interact with the box. The interact graph is in the third image.
What on Earth is going on? Why is my InvItem variable for the box set when I check it on the server, but not set when I check it on the remote?
The fourth image is the details panel of the InvItem variable that is not being replicated
Why i am getting these errors?
sudo -u server ./MyLinuxServer server -u
[2024.11.08-22.07.51:177][290]LogSockets: Warning: Tried to bind address with protocol STEAM to a socket with protocol IPv4
[2024.11.08-22.07.51:177][290]LogSockets: Warning: Tried to bind address with protocol STEAM to a socket with protocol IPv4
[2024.11.08-22.07.51:177][290]LogSockets: Warning: Tried to bind address with protocol STEAM to a socket with protocol IPv4
[2024.11.08-22.07.51:177][290]LogNet: Warning: Could not create socket for bind address 90198922354863610, got error SteamSockets: binding to port 7777 failed (0)
[2024.11.08-22.07.51:177][290]LogNet: Warning: Encountered an error while creating sockets for the bind addresses.
[2024.11.08-22.07.51:177][290]LogNet: Error: InitBindSockets failed:
[2024.11.08-22.07.51:177][290]LogNet: Warning: Failed to init net driver ListenURL: /Game/Maps/TestMap?Name=Player?listen:
[2024.11.08-22.07.51:177][290]LogNet: Error: UEngine::BroadcastNetworkFailure: FailureType = NetDriverListenFailure, ErrorString = , Driver GameNetDriver IpNetDriver_2147481895
I would guess there is something already running on the 7777 port? Check ps aux to see if you have any other running instances of your server in the background
i don't even have that port added to my vps
by default all ports are open
Like as an allowed inbound port for the security group?
yeah
That doesn't matter at this point, you can't even start for localhost. If the port is exposed or not is the next step
Check if something else is already on that port, in 99% of the cases it's and old dedicated server instance
ps aux | grep mygame
(replace the mygame)
ps just lists the running processes and | grep filters the output
PID TTY TIME CMD
998 pts/0 00:00:00 sh
1020 pts/0 00:00:04 pwsh
1287 pts/0 00:00:00 ps
What is the exact command you executed?
ps aux | grep MyLinuxServer?
Probably need to sudo it since you are running the game server with sudo? (Which you shoudn't)
i have this setup
[OnlineSubsystemSteam]
bEnabled=true
SteamDevAppId=480
bRelaunchInSteam=false
GameVersion=1.0.0.0
bVACEnabled=1
bAllowP2PPacketRelay=true
bUsesPresence=false
P2PConnectionTimeout=180
GameServerQueryPort=27015
[URL]
GameName=GameName
Port=7777
the port 7777 should be in/out UDP and 27015 should also be in/out UDP?
to which port the clients will connect?
i assume it 27015
but why do i need that 7777 then?
I haven't done Steam stuff in a very long time, but isn't GameServerQueryPort for communcation between Steam->GS? Game clients should connect on 7777
I would personally first try without Steam Online Sub and then added it in.
nice information, thank U
Hey everyone I'm having an issue with Jittery movement on the client side
In my game the client experiences very jittery movement with rubberbanding. When I simulate the game normally everything runs fine but if I have the ping simulated as average from the editor preferences then the problem arises. Note this is not some custom movement that is causing the problem, even if I have the characters fall to the level start, the movement on the client side looks like they are constantly teleporting up and down while falling. On the server side they appear to fall and move normally. I’ve tried all the network smoothing modes and nothing has made a difference. I built the character off the generic first person character blueprint and tried reverting all the character movement settings to default. Is there some other smoothening setting I should change?
the issue was, I should not be running it as sudo, thank you for solving the issue
Grats on fixing it!
i can now connect, already played with 3 friends around the globe 😄
In regards to my problem here: #multiplayer message
I changed the InvItem variable from Replicate to RepNotify and suddenly replication is working. WTF?
And that was also my solution to being able to log replication: use a RepNotify and then in the notify handler write a log message.
So im new to multiplayer, my server can easily go into the heli and exit as much as he wants, but as soon as the client enters the heli, the server charcather becomes stuck, so i only have access to the client, any help appreciated.
What happens to an actor with initial dormant that get spawned? does it become awake or dormant all?
Seems like you're possessing it multiple times. The last player to possess it would be the only one that would have working inputs on it and could call RPCs on it and only only 1 player can possess the actor at a time. The way around this is to not possess it again if already possessed, and ensure you have some means of knowing that the player is in the helicopter so they can send an input to the server and the server knows to remove them from the helicopter without having the input on the helicopter itself.
Like you could have an input mapping context that gets added to the player controller when they enter the helicopter and the player controller can signal to the server when they wanna get out.
ahh so i just make some logic for only possesing it with 1 actor at a time, but i thought that would be solved by just useing the get controller @sinful tree So im still a bit confused what exactly is messing up my current logic, server seems to fine, until client interacts
can u perhaps pinpoint where in my blueprint i messed up
If the above is triggered once by one player and then another, only the second one would be able to then call the input you have on the BP_HELI60A here:
Possessing changes ownership, and you can only possess one thing at a time.
So the players first start as a BP_FirstPersonCharacter, and when they press F it's registered on their local copy of the game, and you're RPCIng to the server.
The server gets the BP_HELI60A and then you're possessing it with the controller of the player that pressed the input. They are now no longer possessing their BP_FirstpersonCharacter.
If they press F now, the BP_HELI60A event will trigger, however, if another player happens to press their F key while possessing their BP_FirstPersonCharacter, they wil then be the one who is possessing the BP_HELI60A and the first player is now no longer possessing anything.
So, if you want to prevent this, you need to check if the BP_HELI60A is already possessed, and if so, then you don't have your other player possess it. You can attach them to it or something else.
ohh that makes sense ty!
what could cause this?
Game: Highest Number
Description: both players enter a number, the highest number wins.
I've been making progress thanks to this group. I now have the bones working but I know Binding is not very efficient. Can anyone walk me through how get the server to update both players numbers without binding? Do I use multicast? event dispatchers? or just events?
Nothing wrong with binding, I rather use that than delegate in my cases.
Question is why are you using get all actor of class? At this rate you are just grabbing every single player in the world and hoping you get the one you want.
if you are talking about the original UI binding - they are terrible - they poll and update the values on every tick - even if the value doesnt change. Its a known anti-pattern.
To the point that UE5.3 and onwards gives an editor/project wide option to have the option disabled, and even warn on compile if any exist.
The idea is to use Viewmodels and use the view binding in that - which is actually event based dispatch under the hood
Its an unfortunate decision decision epic called both of them "binding" - cause its going to cause confusion for a while if people are referring to the old way or the new way
Guys, serverTravel doesn't work for me using it with gamlift in UE5.3
I have all the maps packaged correctly and I don't know what is wrong
Hey whats the proper way of controlling the amount of input client sends to the server? Input stack on the server keeping track of everything client sends and executing it in order? I'm trying to avoid client spamming function calls on the server through inputs.
If you’re talking about movement etc, you need to send it all. If you’re talking about events like “attack”, then you can implement a cooldown on the client side to stop the person pressing attack too quickly, and you then need to have the cooldown check on the server side as well if you want to protect against cheating.
Check the logs? Hopefully would be a clue there. It’s hard to guess otherwise.
I am mounting it in a fleet in gamelift, I don't know where to look at the logs of my server compilation
Not movement but actions like selecting, deselecting, duplicating actors etc. are client side bools enough?
Why is this getting called on the server each time a new client is joining. Aren't widgets exist only on a local player?
I know it updates every tick, I just think people make a big deal out of grabbing values every tick.
Why does every single thing have to be a delegate for getting a value to the widget?
It's not really about making a big deal out of it or not
This is one of the many cases where person XYZ can do this and not notice anything.
But there are a lot of projects that grow so far that it becomes a problem.
The Slate TickTime Ms are not to underestimate.
understandable, I never work on anything big
Do you really want to give up processing time that your game can use to do cool shit for polling a value that changes once every 20 minutes?
ViewModels are a wonderful thing, if used properly. Idk how far the Engine is with that, but a lot of other Frameworks, outside of UE or GameDev, utilize them. And if not MVVM then other patterns. Ultimately, most Frameworks that have to do with UI do a lot to avoid redraws.
UE has the Invalidation Stuff fwiw
I only really got into contact with UE MVVM on my current client. And it was actually quite nice to simply alter the ViewModel to grab new Movement Data from Mover instead of the CMC and the UI doesn't have to care about it.
That was a perfect example for it. The "On Change" logic is of course a big +.
In Multiplayer, any kind of Event Driven setup is a f*cking pita.
So I can totally understand if people fall back to Tick/Bindings.
I recently had a discussion with a user here in a thread, that most of you probably didn't notice. I gave them a full setup for a LobbyList based on BeginPlay of the PlayerState and a one-time query on EventConstruct to get all PlayerStates that already ran BeginPlay.
It sounds super simple and straight forward, but in the end, didn't work.
Why? Because PlayerState's PlayerName gets set AFTER BeginPlay, so the whole setup died there in Blueprints, cause no access to PlayerName OnRep.
We fell back to a binding for it for now. It works for them, they are a beginner on that, but it shows how easy it is to not be able to use Event Driven UI
Even tho I didn;'t use binding my self at all soo far, I see how doing so for a list or something big like inventories may cause performance issue.
But I was thingking the line of showing some basic information for the player. Eg Health, Stamina, etc.
I tend to see that people say use delegate to showed those values to people that just start and I don't see how tick is harmful in such case.
I think a lot of people understand why Tick is not useful to set a value based on something calling if you explain it to them.
Bindings on the other hand are tricky to explain, despite that they basically tick.
Slate uses Bindings too fwiw.
👍
In UI, if you want to be really strict, you only re-render if something changes.
And to ensure that the UI knows when something changes, you can:
- Get the Value once when the Widget is created
- Bind to a Delegate/EventDispatcher
Or go even further and use MVVM; where the Widget Binds to the ViewModel. But the ViewModel would follow the same "Get Once + Bind".
But if you can't figure it out, then use a Binding for the start. I'm totally with you that Beginners should not have to worry abut the complexity of EventDriven stuff.
But it sadly also shows that a lot of Tutorials aren't preparing the Code of the System they teach to support this.
I dubt there are a lot of tutorials for anything that properly expose a Setter with a Callback.
In C++ you usually always go and make your stuff private. I think a lot of peeps would be totally overwhelmed by that in BPs
do the UI only re-render when something changes by default?
And yes I know I'm blowing this out of proportion. I'm waiting on my Git Pull to finish,.
I think you are making it very clear tbh.
Trying to word this properly... hm
Let's try it the other way round: What do you think does it mean when someone says "Widgets exist only on a local player."?
I'm asking to see where you misundertand it.
the object exists only locally. So the code in theory also performing only locally? 😄
I packaged a client for my game, when i start it, it starts downloading spacewar game
what i am doing wrong?
Okay, is the believe that no matter what you do when creating a widget, that it sits locally? @floral sail
like how can a widget even communicate with the server if the server doesn't have a copy of it
that was my initial thought, but apparently its not
Your AppId is setup to 480 then.
480 is Spacewars after all.
ye listen server
yeah, i cant make make ship test builds with it?
ship just builds very quicky and and few hunderd mbs, even not 1gb
So, let me write some stuff down that might help:
- Widgets exist where you create them
- If you create them on a Client, they exist on the Client
- If you create them on a ListenServer, they exist on the ListenServer
- This means specifically that you need to be careful WHERE you call CreateWidget
- Widgets don't support replication, so creating them on a server won't create one on a client
- Widgets should therefor not have any RPCs or Replicated Variables in them
hmm
I guess it makes sense now
so the problem is not the whatever code in widget, but the fact that I create it twice
An example for a Widget being created "wrong", which might result in it existing on the Server as you noticed:
- You might be using BeginPlay of the PlayerController to Create your Widget.
- The Server has a Copy of the PlayerController for every Client
- Any Instance, that is relevant on a given Game, will call BeginPlay (if the game has begun play of cousre)
- This means, the PlayerController, existing once locally and once, for that player, on the Server, will call BeginPlay on OwningClient and Server
- ListenServer itself has a PlayerController, no one else has a copy of that
- ListenServer has a copy of every Player's PlayerController
- Each time a Player joins, BeginPlay of their new PlayerController will call on Server and the OwningClient
I create all my widgets on Player Controller Begin Play
I think I should use local controller check before the whole sequence then?
Right there are multiple misconceptions here
that kinda makes sense
Let me write them out quickly
Hi all,
Re: seamless server travel, I'm needing my player controller to get recreated (not persist) on a level change. What's the easiest way to go about that? If I destroy it while still posessing it right before I open map to start the level change could that work?
-
BeginPlay will call for Server and OwningClient, as previously stated
-
Your InitializeInput will thus call also on the Server for every Client that joins
- You probably don't want that, guard it with a Branch(IsLocalPlayerController)
-
Your InitializeUIWidgets will thus call also on the Server for every Client that joins
- You probably don't want that, guard it with a Branch(IsLocalPlayerController)
-
Your ServerSpawnHero is an RPC to tell the Server that the Client wants a Hero on BeginPlay
- This RPC is more or less redundant, the BeginPlay calls on the Server already, if you want to Spawn a Hero, which should be done on the Server (so the theory was somewhat correct), you want to guard it with SwitchHasAuthority and use the Authority pin to call the function. There is no need for a ServerRPC in that case. You can call the Server-side Method directly
-
Side note: Your check "Is Current Level MainMenu" is a bad pattern. Every Level, including the MainMenu, can have a custom GameMode assigned. The GameMode provides the used PlayerController. You want to, as early as possible before it becomes unmanageable, create a proper inheritance hierarchy for your Framework Class. Here is an example:
-
BP_GameMode, BP_GameState, BP_PlayerState, BP_PlayerController
- BP_GameMode_MainMenu, BP_GameState_MainMenu, etc.
- BP_GameMode_Gameplay, etc.
- BP_GameMode_SpecificGameMode, etc.
If you have a Lobby Setup, you may want to additional divide the _Gameplay like this:
- BP_GameMode_Game, etc.
- BP_GameMode_Lobby, etc.
- BP_GameMode_Gameplay, etc.
- BP_GameMode_SpecificGameMode, etc.
You may drop some of the specific classes. E.g. a MainMenu might not need a custom GameState or PlayerState.
You then make sure to put the logic and variables they all should share in the base, or at least the base that makes most sense. Your BP_PlayerController_Gameplay then use the code you posted above, without the MainMenu check.
@floral sail
Tricky
It usually doesn't persist if the class is different
Idk why they coded it so weirdly. It doesn't even call BeginPlay anymore usually.
Why do you need it recreated? Maybe there is a function you can use that makes more sesne
it's the same class. I'm essentially just wanting to restart my game which means loading the initial map. But I need my player controller to respawn so all its begin play setup logic fires
I don't have time to do any fancy refactoring/reworking, hoping there is some way
if there is another way to simply restart your game without quiting that would be fabulous, if anyone knows
Let me check for you
ty ty
C++ fine?
if necessary np is my motto
So AGameModeBase does this:
There is a lot going on, but the first part spawns a new PlayerController
As the comment suggests
Now your problem is that you use AGameMode (which is correct, but still the origin of the issue).
Cause that does this:
The logic being very similar, but the additional if (PC && PC->GetClass() != PCClassToSpawn) screws you here
Because due to that, all you get is this
Now, you have two ways to solve that:
- Alter that function in your own GameMode
- Don't use BeginPlay but
GenericPlayerInitialization(C);
void AGameModeBase::GenericPlayerInitialization(AController* C)
{
APlayerController* PC = Cast<APlayerController>(C);
if (PC != nullptr)
{
InitializeHUDForPlayer(PC);
// Notify the game that we can now be muted and mute others
UpdateGameplayMuteList(PC);
if (GameSession != nullptr)
{
// Tell the player to enable voice by default or use the push to talk method
PC->ClientEnableNetworkVoice(!GameSession->RequiresPushToTalk());
}
ReplicateStreamingStatus(PC);
bool HidePlayer = false, HideHUD = false, DisableMovement = false, DisableTurning = false;
// Check to see if we should start in cinematic mode
if (ShouldStartInCinematicMode(PC, HidePlayer, HideHUD, DisableMovement, DisableTurning))
{
PC->SetCinematicMode(true, HidePlayer, HideHUD, DisableMovement, DisableTurning);
}
}
}
In theory, for the PlayerController, GenericPlayerInitialization is the better call.
That's why I wondered if i could just destroy my current player controller before the level change, but even if I destroy in BP, I dunno if it's even considered null if on the same frame i'm calling open map
hi, I'd like help on my blueprint code. it's for asymmetrical multiplayer. The problem is if I have a team with 1 player that if it is the host, that makes the entire server limit 1 player and the other teams of varying sizes cannot join (they also set the max player limit strangely if hosting, which they are of differing sizes)
Unsure how to fix issue, here is my code: https://blueprintue.com/blueprint/_01d-yvc/ it's in the game mode blueprint. Any help would be appreciated, thanks!
I would not do that in BPs.
does GenericPlayerInitialization(C) get called on the pc when a level loads even if seamless?
If you want a BeginPlay alternative, override the GenericFooBar function and call a Method on your PlayerController
GenericPlayerInitialization gets called:
- On PostLogin
- On HandleSeamlessTravelPlayer
nice, is that or any function that does the same thing exposed to BP stock?
Hm no, this is also ServerOnly
GameMode tells the PlayerController to create the local HUD via
InitializeHUDForPlayer(PC);
// Tell client what HUD class to use
NewPlayer->ClientSetHUD(HUDClass);
/** Set the client's class of HUD and spawns a new instance of it. If there was already a HUD active, it is destroyed. */
UFUNCTION(BlueprintCallable, Category="HUD", Reliable, Client)
ENGINE_API void ClientSetHUD(TSubclassOf<AHUD> NewHUDClass);
You could do something similar if you need a local call
You can of course also change the Handle function to recreate teh PlayerController
I just don't know why Epic choose to not do that, so it might cause bugs
Ok dumb question. Is there any way to reset an actor instance to its class defaults : P This would also solve my problem lol
No
UE has a system of Reset, but it require you to manually reset the variablse
void AGameModeBase::ResetLevel()
{
UE_LOG(LogGameMode, Verbose, TEXT("Reset %s"), *GetName());
// Reset ALL controllers first
for (FConstControllerIterator Iterator = GetWorld()->GetControllerIterator(); Iterator; ++Iterator)
{
AController* Controller = Iterator->Get();
APlayerController* PlayerController = Cast<APlayerController>(Controller);
if (PlayerController)
{
PlayerController->ClientReset();
}
Controller->Reset();
}
// Reset all actors (except controllers, the GameMode, and any other actors specified by ShouldReset())
for (FActorIterator It(GetWorld()); It; ++It)
{
AActor* A = *It;
if (IsValid(A) && A != this && !A->IsA<AController>() && ShouldReset(A))
{
A->Reset();
}
}
// Reset the GameMode
Reset();
// Notify the level script that the level has been reset
ALevelScriptActor* LevelScript = GetWorld()->GetLevelScriptActor();
if (LevelScript)
{
LevelScript->LevelReset();
}
}
oh wow there is a lot to unpac
so aside from MainMenu check, seems like that did it:
(the self part is redundant but doesn't hurt)
I really should use Threads more again
roger, since i only have today to solve this. I may not have time for the fancy but very interesting stuff you mentioned. I suppose alternatively I could just take everything on my PC's begin play, put it into a functon and call that from the level blueprint i'm opening on reset : / and then manually reset all vars in the PC to their class defaults
Let me make that one person's post a thread
that's lame af tho, but should work? : /
Help with Async Multiplayer
I would not try that
Like the ResetLevel one
That's a pain to maintain
oh totally. this is just a one off update, and will never update this version of the game again
Try destroying the PC and recreating it like GameModeBase does first
If that works you are good
yup packaging that now
But in C++, in your own GameMode class, in the HandleseamlessPlayer override
oh right
Now, you say that check main level logic is a bad practice and I should rather create multiple Game Modes. But why? I only plan 3 levels for my map - Main Menu, Lobby and a big Playable Map. Do I really need multiple game mode/game state/player state etc? I haven't done any big projects in unreal yet, so I don't know.
I mean, you can always argue that "you don't need that, code it all in one fiel, embrace the chaos", but if you later come back here with bugs I will smack you
The actual answer is: No you don't NEED to, but you SHOULD
Inheritance is a core pattern for C++ (and thus BPs), and you should make use of it.
Division of concerns is important
Ye thats a better question - what is the better practice
It will make your life easier and the code more organized
It will help reducing the likelyhood of bugs too
So then a better alternative to that level check on begin play would be creating a new Game Mode specifically for Main Menu, then assigning it in World Settings I suppose (the GameMode override)? And then for that new Game Mode I need to remove Default Pawn Class?
Correct
Or alternatively I can create a new Player Controller aswell for the Main Menu level and add the Spawn Hero logic in here on BeginPlay.
Well, not for the MainMenu, if you don't want it there
oh ye I meant for the Playable Map
Yes
But make sure you give them a proper hierarchy of parent calsses
Don't make two GameMode from the engine class
You may always run into a situation where you need data/logic that all of them can use
Ok thats another question then. So I have Main Menu -> Lobby -> Playable Map. How should I set parrenting for all 3 game modes?
I already listed that
so essentially same order would make sense
- Base (Vars/Funcs that all of them may need or override to their liking)
- MainMenu (MainMenu specific logic, like creating the MenuWidget)
- Game (Vars/Funcs that need to be available in Lobby and Gameplay, makes it easier to use "CopyProperties" in PlayerState or "OnSwapPlayerController" in GameMode, cause your Lobby and Gameplay always share the Game one as Parent for SeamlessTravel)
- Lobby (Lobby specific logic, like a ReadyState on the PlayerState for example)
- Gameplay
oh like that
You can't use 480 to upload anything on Steam. You need your own AppId to utilize actively storing the GameClient on Steam and then you need to use the Steam Build stuff to actually handle that for you via Scripts (all explained in the Steam Docs). That's also when you could create different Branchs that house different Builds, like Shipping vs Testing.
480 will only allow you to act like your game is Spacewar, but you can't alter anything of it.
it is kinda hard to make a good classes setup cuz you don't know ahead what you are going to code and where as a newbie 😄
Ok so here's what I've got now. Anything you would've added?
I guess its hard to say. I should just keep in mind that inheritance is a good practice for these "main actors" and in general in c++.
@thin stratus question re: this seamless server travel stuff and the PC. If I'm using different game modes between the current and level I'm going to load, then I would get the new PC and begin play would fire no?
The GameMode you end up in needs to implement that stuff
But I just mean. If the current map A has game mode A with PC A and the map B i'm about the load has game mode B and PC B then of course PC A would get destroyed and PC B would get spawned when Map B loads right?
Yes
So I'm using default Top Down logic atm. I need to edit it properly for multiplayer.
I assume I need to call Follow/Stop/MoveTo only on the server and also make the vector variable replicated?
hmm that why when i open the shipped build, it starts my steam account and i was prompted to downloaded spacewar game 😄
ok turns out I don't need to do anything, just set Allow Client Side Navigation to true in the Project Setting
why is it even disabled by default I wonder, for security measures maybe?
Unless you specifically need client navigation then there's no point in having it enabled on the clients which for the majority of games you don't. There's probably a bit more CPU or RAM use or something with it enabled, but I can't see it having much to do with security as movement can still ultimately be handled by the server.
Well if its disabled then Simple Move to Location function doesn't work on clients
and that function is used by top down template so its kinda weird
Guys, I have a problem. It turns out that I am trying to do a serverTravel in a dedicated server environment in gamelift and it does not run. Furthermore, I have purchased all the packaged maps and it is correct. I'm mounting it in ue5
this same code in ue4 works perfect
what do logs say the error is?
It's not that I get an error. It's directly that serverTravel does not run it for me in a dedicated server environment in ue5
When I run it as as client without being connected to any fleet it works fine for me
It only happens to me in ue5 in ue4 everything works perfectly
The UProjectileMovementComponent uses InverseTransformVectorNoScale in its TickInterpolation function to determine the relative position of the InterpComponent. This function ignores the scale of the UpdatedComponent (the component the movement is attached to). This raises a concern: if the UpdatedComponent is scaled, the interpolation might be incorrect because the movement calculations happen in world space, not the local space of the UpdatedComponent where scaling matters.
Comments within UProjectileMovementComponent suggest the InterpComponent should be a child of the UpdatedComponent, implying that interpolation should occur in the UpdatedComponent's local space, which takes scaling into account.
For comparison, UCharacterMovementComponent applies mesh scale within SmoothClientPosition_UpdateVisuals for smooth client-side position updates. However, UProjectileMovementComponent seems to lack this consideration for scale during interpolation.
is this a bug or intended behaviour?
If it's in world space and it's interpolating from positions in world space, then the scale of the component is irrelevant.
Have you checked which methods it actually uses to determine the transform?
Hey guys, i have a question. Does more complex skeleton affect the quality of a multiplayer game?
Would there be difference between a more complex skeleton like MetaHuman and a less complex one like UE5 Manny?
define quality
Ok gang, I'm trying to get to get a client to be able to send 3 array's to the game state so the server player and or the client player can pull from it. I can get it working if the player who is sending the arrays is the server (shocker that I got the easy part done). Now I need to figure out how to let the client send the same info to the server. I will be eternally grateful if anyone can lend a hand.
Of note that blueprint is on the player.
You can only send RPCs to the server from clients when the client owns the actor you're trying to send the RPC on.
Also, there is no point in multicasting those sets.
If they're replicated variables, set them on the server, and that should be all that is required.
So the reason I can't send it is because the game state is server owned?
No, whatever BP_C_MasterTrainer likely is.
If it is soemthing client owned, then right now you're multicasting those sets - what ends up happening is that every client and the server ends up setting those variables based on the whatever they have locally for them, and then because they're marked as replicated then it'll always be whatever the server has for those variables.
If you're wanting to send data to the server, you need an input on the RPC to the server.
When it's running on the server, you can then set the passed through value in a replicated variable, then clients will receive the values.
That said, if this is a card game, you likely don't want to be passing that data to the server. This is data the server should know already, as otherwise clients could potentially cheat.
It may help to show you want I'm doing.
It is a 2 player game where the trainer Player (Top in image) is using cards for to set the monster's move set (bottom). So both players need to be able to pull and set the data from the same arrays.
So the player, weather they be server or client, needs to be able to set the moves (string array), the number of times the move can be used (int array) and if the card is using an alt move set (Bool array).
Where the monster, again server or client, needs to be able to read all those arrays and set the number of times the move can be used (int array) down each time they use said move.
The way I have been doing it was storing those arrays on the game state and having both client and server pulling and setting said arrays.
Just try to interpolate a scaled projectile, the result will be choppy.
Scale doesn't apply to its position, though, only to the model and any subcomponents.
The scale of its parent might, but projectiles shouldn't really have parents.
yes
@twin juniper well the server has to set that to replicate
And it's done in prenet function on the actor
I set up a run on server and still no dice
@twin juniper well that depends how it's moved
Not sure if any of the setactorlocation dues any broadcasts
I have a server call which attempts to get the value from the input axis but comes always comes out 0 on the client. Retrieves correctly on listen server GetOwner()->GetInputAxisValue("ForwardBack");
I figured this would be already replicated
Input is local only
indeed, anyway to get it from the movment comp?
When you do a server rpc that code is on the server.
Well either you send it in the rpc
Well that's the only aay
Way
fair enough, this is just for roll direction so feels like there's already something that could be leveraged
We don't use the input axis for that
But we do it in the cmc via code :/
Lyra uses a calculated direction fir dash but has to tell server via a rpc
Maybe see how they did dash
You could get the Acceleration from the CMC
That's the World InputDirection * Acceleration
So normalized would be World InputDirection
yeah, good idea, I'm using tons of the Lyra code anyway
If you need it local, local, you could unrotate it
But server us akeays behind client
Play might want right but server still has it accelerating left when it's told to roll
can't decide if I wish I started with replication first in unreal instead of having to redo things now or if I would have quit by now 😅
I guess learning the engine and multiplayer at the same time would have been a bit 🤯
Is there some form of collision LOD that I should implement? My dedicated server is hosting a large map of trees, those trees have simple collision that I use for AI pathing and resource collection.
I understand the server needs to maintain collision info, but is there a way to apply a sort of "net cull distance" for collision on the clients? I figure a client does not need collision info for a tree on the other side of the world.
@rustic sable Multiplayer is not a walk in the park.
You wont learn it overnight.
It can take years to grasp it fully.
Which is why persistence is key.
Keep learning, you will get there.
Hey, I have been running into a situation where one of the non-server playable characters is running into the simulated version of an actor that has moved out of the relevancy range to such an extent that the server version is still out of relevancy range even though the local version is right beside the non-server character.
What is generally the practice for dealing with this?
I could set the actor to always relevant but that feels like it will waste bandwidth if there are lots of actors like this
I could periodically turn always relevant on and off, or increase the radius of relevancy by alot to encompass everything.
I could call a multicast rpc which periodically moves the actor to its current position with random times to prevent overlap on this update between multiple actors
but I might be overthinking it, so if anyone has an easy solution I'm all ears
Here is a bad picture explaining the situation
@wet bridge This is a bit confusing? Are you showing that the Simulated Actors location is different on the Client and Server?
Yes, because the simulated actor moved out of relevancy range, so the server stopped updating it on the client
but since relevancy range is based on distance calculated on the server, the client can meet up with the simulated actor where it stopped getting updates
while remaining out of relevancy range on the server
It is very unusual that you would have an Actor with a different location on Client and Server
That would mean its out of sync
Why are you desyncing the location of this Actor?
So you want the Actor to stop getting network updates, but you also want it to remain close to the Player?
No, I must'nt be explaining it well
What I'm saying is that it is an issue where an actor can stop getting updates because the actor moves too far away from the client's pawn
i.e. moves out of relevancy range
but on the server that actor keeps moving
until it is say 4 times out of relevancy range
but on the client it stopped as soon as it left relevancy range
so the client can walk to where it stopped getting updates and the actor will still be there
because it won't update because on the server, it is still out of relevancy range
That doesnt make sense, since Actors are removed entirely on the Client when they leave relevancy.
So if you are seeing an Actor not being removed, something isnt working properly.
"Disabled replication of WorldSettings on levels created for world partition streaming cells." this was done in 5.3
Anyone knows if it's possible to do the same in 5.1?
This is happening on default behaviour with the character blueprint
I am doing this test in unreal editor though in case the behaviour you're referencing is only in builds
when tho 🤔 :3
So it seems this behaviour only applies to spawned actors and not preplaced actors
had to untick "net load on client"
thank you for bringing this behaviour to my attention. Made it easier to find the problem
Is it possible to run a Linux server build on Windows somehow? cygwin or gcc or something that can emulate Linux on Windows? Trying to test a server locally for Gamelift but the initSDK fails in Windows builds.
sure, you want clang though.
...or use the clang toolchain for windows as mentioned in the docs
Download the appropriate clang cross-compile toolchain based on which engine version you're using.
You will need to regenerate project files (potentially after restarting your PC) before linux will show up as a target.
I was just using get all actors of class because i only intend on 2 players connecting to game session. it's also because I haven't learned how to manage players yet.
Meh - GetAllActorsOfClass is fine
General performance
Like would it cause any major problem, FPS, bandwidth and stuff
for my purpose I think it is.
CPU/GPU performance sure, more bones = more calculations for the animation system, but that has nothing to do with multiplayer and unless you're talking magnitudes more bones in one vs the other it's not going to be your bottleneck compared to just needing to deal with skeletal animation in general.
Bandwidth isn't even remotely relevant to the question.
I understand how to get something to set a variable on the server, but I need to learn how to get those values on the server back to the players.
use the profiler
For a lot of purposes it is fine to be honest. The cons of it are highly overblown.
based and sane take, everyone acts like it’s the devil yet I think i’ve only ever seen it be a problem once ever
Luthage said that they used it on Psychonauts 2 - on tick. Caused no problems.
yep
It is just a TMap lookup really
it’s really weird people i feel are insanely scared to have slow code that works
most common path of self sabotage i feel
I used google benchmark to see which types (int32, int64, float and double) are faster for my use cases, Wasn't really worth it but I feel confident now 😂
that was the opposite of the point i was making ahah
the point i was trying to make is make a pile of shit that works then open the profiler
Best take - https://www.youtube.com/watch?v=flEtQBPtBTc
How to determine whether or not you should be using Blueprints or C++.
i can imagine why this video have so many view
cuz u guys keep sending it in this server to noobie lol
It's not about performance or anything but the manner it was used. He get all players in the world, for each of them, get the player state and connect it to some widget text.
So at this point he is just gonna get values from random player instead the one he wants.
Hi,
I'm trying to get my dedicated server and client to handshake with Steam OSS.
The JoinSession works, but when the client does ClientTravel, the server receives nothing. I.e. packets are not getting through.
bUseSteamNetworking=false does not help.
Dedi and client are on different PCs but the same LAN.
When I use NULL subsystem it works fine.
Any ideas?
Thanks
Maybe you need port forwarding? First thing to check is if the server appears on steam server list
You also might need to allow the ports in the firewall
This is on LAN so ports not relevant
Client finds the server but C-S handshaking fails
If your ports are closed then Steam won't see it
Where is that UI, in the steam client?
thx
np, I have some success with steam but never got any difference between LAN and Online mode
so I use open <ip> for LAN
thx. my server does not show up in the list. Which is odd, because client finds the session?
i.e. JoinSession succeeds
if the ports are closed then steam won't show anything
or if there is an issue with the network
ok because game client knows about the session so why doesn't steam client. weird
steam checks if your client owns the game
using 480 rn
maybe you can find some clues in the log
nothing gets through from client to dedi on same LAN, so times out the connection attempt
Try making your port forwarding work and open 27015-2060 udp/tcp and 7777-7788 udp in firewall as incoming ports
27015-2060 can you correct this range?
I’ve had issues with Steam, dedicated servers and been on the same external IP as a client.
To solve this I routed my on site dedicated server to use a VPN, so that Steam sees it as a different external IP. Could be worth trying, even if to provide the issue is ports/firewalls and IPs vs something else.
Thanks @woven basin and @tender solar - I'll tinker some more.
@LordMot that's the range I use, you can narrow it down if you want
Also make sure that you have the full IPv4, sometimes the ISP shares your ip with other customers and you get like ports 0-16384 and nothing will work
did you mean 27015-27060?
yes
just those 2 ranges?
Is it possible to do host migration for listen servers without using third party services or a custom backend/server? I'm curious what's the logic behing the host migration plugins on the marketplace
hmm i should try turing off my firewalls i guess
you dont need to turn off firewalls just open the incoming ports
it's in French but you should get the idea
and another for TCP
yup done that but my local dedi still doesn't show up in LAN game servers list.
Do you need portforwarding and do you have full ip?
there are some phone apps around that help checking
if both server and client are on the LAN then port forwarding should be irrelevant.
yeah but steam is not on the LAN
yeah, but the client knows about the dedi - it found it and joined it. Just the actual C-S handshaking fails. 😦
null subsystem works fine
ah well
I had an error message that I fixed by adding ApproveLogin in my session class
virtual FString ApproveLogin(const FString& Options) override;
server is not logging ANYTHING when client tries to handshake
just not receiving a damn thing it seems
is there a verbosity switch?
I had an issue like that it was caused by Virtual box that messed my server
it added another Ethernet driver and Steam did not like that at all
I trried bUseSteamNetworking=false but same result
maybe I should get an AWS host and see what happens
Here was I thinking that it was lame if steam client and dedi can't work on same PC, but so far I can't even get them talking on same LAN. lol
they can work on same pc i've played some games like that
my game does not work on same pc though
it didn't work then I deleted intermediate build and binary and then i rebuild and it worked
this is so mysterious
You can use -log -LogCmds="LogOnline All" to get more logs from server
I have PlayerController. PlayerController has SelectionManager Component.
On the start of the game and when Player joins the game, I'm Initializing Component, from the Player Controller.
Inside the component I'm Setting variable - APlayerState, which I Get PlayerState inside PlayerController.
I print PlayerState after initializing it, to see if it's sending something, but turns out the clients prints null. Is it because the component doesn't replicate? (print 1+2)
I did different combinations.
When I put this all on Begin Play in Player Controller, it actually prints good Player States on the start as server (screenshot 3,4,5).
I guess it's because server actually has all the Player Controllers and it can differentiate states?
Like the Server Prints good states, but the client still prints null.
**So my bootleneck is that the Component, is actually not really replicated because PlayerController0 is only 1? Which means, Component is also only one, on this PlayerController? **
To actually have 4 different ''variables'' of PlayerState inside Component, I would have to change this component to not be on PlayerController, but maybe on PlayerState? Or even to make it as Actor?
Sorry for long text..
I would recommend changing your programming style for multiplayer games a bit.
The thing with multiplayer is that nothing is certain. PS can replicate a bit late or a bit early, it may be dropped 5 times along the way.
The way to approach MP development is reactive, once client get's the PS (OnReplicated), it should tell everyone "Hey, I am here and I have been updated".
Usually you would utilise delegate for this, but if the PS is null, its a bit awkward.
Maybe something like this?
Create a Local Player Subsystem with a delegate OnPSUpdated. On Begin play in your component you can check either if the PS already exists (simple option), just get the display name (or whatever).
Otherwise bind to the Subsystem delegate.
Once a PS is replicated, it should call OnPSUpdated and which will update your component.
I think I made it work... it's weird and I don't get it 100%, the thing is I'm working with a plugin and I'm trying to change it so it works in multiplayer. I'm also doing it as kind of excercise, you always learn a lot on cases like this.
What I tried now:
Basically inside the plugin there is variable PlayerControllerIndex, which this plugin (SelectionManagerComponent) seems to use. It was set to 0 as default. I can only guess that when it was like that, anything any PlayerController was doing (doesn't matter if it was 1st, 2nd, 3rd player), the component was always calling to PlayerController0. AND I can only guess, the call was either happening from server (which actually knows about the indexes), something fishy here. I cannot explain it.
I update that index variable in the PlayerController at the start. Now when I run the game with Listen Server, the logic I need to happen works. All the prints are actually good PlayerStates_0 / 1, only the 3rd client actually prints PlayerState_0, but I had the same ''bug'', and it's not a bug but for this client his player state is actually 0, but when he actually sends the data over events, he sends PlayerState_03.
If my logic works, can I in theory accept it and move on?
or in the ''live'' with players it might behave different?
hi guys, just a quick question on best practice for multiplayer - do you keep all of your MP code / blueprints in a kind of "game blueprint" or on the character? It seems to make sense to have it in a central location that everything can access but just wondering
It's where it's needed to be I guess. There is not one space for ''multiplayer'' code. Are you talking about any specific logic? It all depends what the code is doing. For example rules of the game you would put in GameMode. Are you thinking about specific case?
so, a given example for a multiplayer FPS.... I want to spawn the "gun fire" VFX so all players can see it - would I add that in say a weapon component as server / multicast - or add it in a central place and call it from whatever instatiates that functionality?
You would call it where applicable. So probably a fire event on the weapon
that's where I've moved it to now, as I think that makes sense for all weapon related events to be on that component
You probaby need to read this, 3 times, and get a good understanding: https://cedric-neukirchen.net/docs/category/multiplayer-network-compendium
This compendium is meant to give you a good start into multiplayer programming for Unreal Engine.
You would call it from weapon. You could call 1 event for client (placeholder so the client doesn't see lag when waiting for the server), 2nd event for the server that is actually taking care of dealing dmg and is authorative, and 3rd event for mutlicasting the event so all the players see it.
cool, thanks I will
but there is not a thing like MultiPlayerComponent where you call each event if its need to be done on server, you just do it where it should be done
yeah that makes sense, so it's better to basically assign it to the thing that's "broadcasting" the event, such as weapon, player, AI etc
Generally speaking yes
Weapon should fire, not the PlayerController for example. Player Controller only tells weapon, hey, fire now! and after Fire, inside weapon you handle logic Hey server I fired, multicast it.. but it's a bit more complicated because you need to decide what to show client, what to do on server and what to multicast, but all the things you do inside the thing that should be doing that.
yeah that makes sense in terms of hierarchy now - as said, when starting out a lot was in the player but I want to move all that now so the player does player related things, weapons do those and anything else will be the same so it's more reusable and component driven
Is this your first game you are making?
yeah pretty much - I'm a software engineer by trade but now starting to get into UE so I get the concepts, just understanding how and what does what and what building blocks I have
I kinda wish I listened the guys here when I started to not do multiplayer first. Just have in mind that if you are doing multiplayer, if you were that doing thing in a singleplayer, it would take you day. If you want it for multiplayer it will take you 5 days xD
and I don't want to even talk about connecting these 2 things together.. singleplayer is like heaven in comparision
...and that's the OTHER thing I'm wondering 😄 whether I just carry on and get something i like in principles first or try and do everything "right" from the beginning
you know, sweating the small stuff ha ha
My advise also as begginer and as someone who started with multiplayer. I really wish I didn't. If I wasn't caring about multiplayer I would probably have done much higher progress in the game
okay that's fair enough, think you've swayed my decision lol
It really depends how much time you have, but I can tell you I was on the edge with some things xD If you have time only after work and you won't see progress after 2 weeks because you are brainstroming how to do it in multiplayer you might just give up xD
yeah that's kinda where I am lol, thanks for the advice! 🙂
I have started with single player and now I had to break everything that was designed for 1 player
and..it's a lot
Basically everything needs to be done from 0 I guess. 😄
can i override a DOREPLIFETIME_CONDITION in a derived class for a specific property ?
also, how can i override a OnRep_ method ? Can i make it virtual ?
DOREPLIFETIME_CHANGE_CONDITION
I cant remember the syntax - but I've seen that before
if you search this discord, Jambax, eXi etc have mentioned it before - see what the history shows and go from there?
I am thinking about where to put my AItem* CurrentEquippingWeapon.
Should it be on my PlayerCharacter or on the InventoryManager, which is also attached to PlayerCharacter?
looks like eXi found a different way
personally, equipped items I put on the character, since you'll need to do lots with it, with a reference back to the inventory slot
tried ```c++
DISABLE_REPLICATED_PROPERTY(UPGContainerEnhancedInventoryComponent, InventorySlots);
DOREPLIFETIME_CONDITION_NOTIFY(UPGContainerEnhancedInventoryComponent, InventorySlots, COND_None, REPNOTIFY_OnChanged);
doesnt rep
let me show full code
try repnotifiy_always just to make sure its not an issue with it been cached before been disabled or something dumb like that?
otherwise sorry, I've not been down that path before - have to leave it for one of the smarter people in this channel to provide other options
I have done more tinkering with Iris and I finally managed to do some very simple profiling/benchmarking.
According to the docs Iris is
Enabling concurrency by separating replication and game thread data.
Where is that concurrency? I thought the sending would be done on another thread, but it seems everything is still in GameThread.
base class
void UPGEnhancedInventoryComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UPGEnhancedInventoryComponent, InventorySlots, COND_Never);
}
child class
void UPGContainerEnhancedInventoryComponent::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DISABLE_REPLICATED_PROPERTY(UPGContainerEnhancedInventoryComponent, InventorySlots);
DOREPLIFETIME_CONDITION_NOTIFY(UPGContainerEnhancedInventoryComponent, InventorySlots, COND_None, REPNOTIFY_OnChanged);
}
also, how should i override the OnRep_InventorySlots ? can i use virtual ?
also, InventorySlots is an array of structs
@lament flax - just a guess - wouldnt your disable need to be UPGEnhancedInventoryComponent - not UPGContainerEnhancedInventoryComponent?
i.e. disable the parent, enable the child?
let me test
literally a guess though - so dont hold your breath
removing the virtual of OnRep_InventorySlots in base class declaration made it called from child class
but i would like to call the OnRep_InventorySlots on child, maybe i can just do a cast and call another function
hello can anyone guide me like how to implement online multiplayer for andriod devices using google play
has anyone encountered an issue with GetOverlappingComponents or GetOverlappingActors where the listen server correctly detects an overlap while a client does not?
that can easily occur depending on latency.
You wouldnt normally want to detect overlap on both. Either detection of overlaps occurs on server, and it sends any results from that to all clients. OR client detects overlap, tells server overlap occured, and server acts on that. You wouldnt do this for a PvP/competitive game, but works for some scenarios.
no - its too broad a question. Maybe try #mobile
in my case I am doing a procedural level based on a seed. The server seeds the algorithm, then the level generation is triggered on all clients (and listen server) by means of OnRep_GenerationSeed(). Each client performs a deterministic generation algorithm based on the seed.
based on my logs, everything is spawned correctly and identically until the listen server detects an overlap (correctly) but the client fails to detect it. I log the locations and rotations of the objects and test them manually and they do indeed overlap
regardless - even if they did perfectly sync - its not what you would normally want to do
because if Client A detects overlap, and Server detects overlap - what then?
Server is doing it anyway, and its authoritive, so it tells everyone, including Client A, the outcome
then they both continue with the deterministic generation algorithm
but with even the slightest big of lag - you'd have different outcomes?
or is this still based upon the initial seed?
it's all based on the seed, so lag will play no part
based on my logs it seems that the algorithm works, but for some reason the GetOverlappingActors does not detect an overlap that really does exist. I'm wondering whether there is some internal mechanism I am not understanding with the overlap calculations such as needing to wait a frame or call some manual "update overlaps immediately" call I am not making
I did try to call UpdateOverlaps() before the check but that does not solve the problem :/
thanks will see there
What do you have to do in an AnimBP to get layered blend per bone replicate? I have the booleans driving the poses set to replicate and in the GetLifetimeReplicatedProps but no luck so far
AnimBP are driven by the booleans as you said, not replication.
So check the booleans on the client - they are probably not actually replicating
If the boolean is updated - the AnimBP just reacts to the bool
indeed, forgot I was setting this on the server now so had to multicast it out
yes, use dynamic condition
void UFGItemContainer::GetReplicatedCustomConditionState(FCustomPropertyConditionState& OutActiveState) const
{
DOREPDYNAMICCONDITION_INITCONDITION_FAST(ThisClass, ItemStacks, GetReplicationCondition());
if(GetReplicationCondition() == COND_Custom)
{
DOREPCUSTOMCONDITION_ACTIVE_FAST(ThisClass, ItemStacks, ShouldReplicate());
}
}
void UFGItemContainer::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
FDoRepLifetimeParams Params;
Params.bIsPushBased = true;
Params.Condition = COND_Dynamic;
DOREPLIFETIME_WITH_PARAMS_FAST(UFGItemContainer, ItemStacks, Params);
}
ELifetimeCondition UFGItemContainer::GetReplicationCondition() const
{
return ELifetimeCondition::COND_Custom;
}
bool UFGItemContainer::ShouldReplicate() const
{
return ViewingPlayers.Num() > 0;
}
Then on ur subclass u can do:
ELifetimeCondition UFGItemBackpack::GetReplicationCondition() const
{
return ELifetimeCondition::COND_OwnerOnly;
}
bool UFGItemBackpack::ShouldReplicate() const
{
return true;
}
thanks
No worries
There's some example usage around the engine of it too if my code isn't enough, They use it quite a bit on GAS
okay
@hollow eagle Can I bother you with Iris question?
According to the docs Iris is Enabling concurrency by separating replication and game thread data.
Do you know what "concurency" is this referring to?
The perf or server tick doesn't look that much different than with RepGraph. I thought everything after PreSendUpdate would be multithreaded, since everything was already separated from UObjects on game thread.
Threading in iris isn't implemented yet iirc
it's still way faster than legacy replication
and the framework is there
Oh the sadness
It seems similar performance to the fast path of RepGraph from my testings. But much more flexible
sounds about right
the requirement to separate game thread data from networking data is there, though, so threading should eventually be possible. A big part of iris is that it reads data from objects on the game thread (quantization) but can process and serialize to the network on a separate thread since the data is no longer on a UObject.
That feature was the one I was hyped about the most because from the docs it seemed it's already implemented.
There is also async CMC in the codebase but seems to be all sorts of broken.
async CMC is unrelated, but yeah it's pretty broken
seems unlikely that it'll get fixed tbh, mover seems like the path forward (eventually)
Unrealted to Iris but would help squish this massive CMC stack
yeah I don't expect that to happen any time soon
Do you recommend using iris? I'm currently using NetSerialize and planning to go deeper, Was wondering if it's going to make stuff more complicated or the opposite
I don't recommend using iris unless you are very comfortable diving into engine code.
Depends what is your taste to experimental plugins and if you have a lot of clients.
and NetSerialize is way harder under iris. Though also less necessary.
I have a push model enabled and it's not replicating properties I am not marking as dirty, but still I have this chunk in the tick. Is this expected?
yes, it still needs to poll objects that aren't purely push-based
Gotcha
having push model enabled doesn't mean it forces push model on everything
Makes sense
it just allows the use of push model
Are there any build-in tools for stress testing dedicated server? I coded custom one but wonder if there is anything Epic is using
Oh that's sad to hear, I'm mainly doing it to replicate raw classes/data and a lil bit of "replicating some data to specific clients"
As long it works and is not complicated, Having lots of clients is honestly the reason I'm diving deep into netcode
That's very interesting!
A lot of it doesn't work and it quite complicated. Iris is really new with exactly 0 docs
something I'm still not getting about this. Say you have a component in your player which sets an equipped weapon. The equipped weapon is set to replicate and has an onrep, but if you set the equipped weapon in a server function the onrep gets called on all instances but the actual pointer only gets set on the server unless you do a MC? at least that's the way it currently works for me 🤔
You should almost never need to multicast a set. Having to do so indicates that you're probably working with something that isn't replicated and spawned on each client individually.
Are you actually running 100 clients? Or this a mockup?
Can't run more than 5-6 headless clients on my main pc, and only up to 30 headless clients on a workstation with 56 threads
I have a homelab with Proxmox and couple of older servers and 2 PCs.
It's 100 actual clients (no rendering) with simple running logic, but I reduced the tickrate to 20.
240 cores atm
That explains it I guess 😂
But the intel servers are misbehaving under load, so realistically about 120 cores
And thus the custom tool to spin them up and down each time I make a change and want to profile it
I was using aws but that got expensive real fast
Never thought of reducing the tick rate, Thanks for pointing it out!
By default, simple headless runs at 2500 fps
How do I avoid having character mesh even loaded on server?
I can get away with capsule collision for everything on server side, but client should have it. I did this
GetMesh()->AlwaysLoadOnServer = false;
GetMesh()->bEnablePhysicsOnDedicatedServer = false;
That's kind of what I figured hence it's a bit strange that the client is complaining about it being null
If the gun is replicated and the ptr is to the gun, everyone that the gun is relevant for should resolve the pointer.
This may be the best area, but I'm unsure.
I've tried to lookup BP, and C++ answers (right now a majority of my game is BP, but I can do some C++)
Either of 2 answers.
- How do I run logic before the game ever starts on gamemode to load some variable values.
- How can I start a game later? Google is being dumb, and unhelpful.
I wanna start the game laters, even 1 tick later, so that my variables have initalized now, for settings related to the match.
Google either tells me how to not usedelaysin my logic.
or, does the dumb route ofjust disable input, and enable it again later, but I need the player to not exist, and just do all the logic when they come into existence/ spawn and start.
I really don't wanna have 2 unkown states of the game. - If someone joins later in, and has the settings loaded on them from spawn
- I apply the settings on gamemode begin play, to everyone, which just seems like a waste of like "coding space" as weird as that sounds.
I see no reason to code it twice.
When, surely theres a way to delay the match start easily.
(I have also tried the methods such as "restart player", or etc)
But, stuff doesn't seem to load properly, I can't move the camera, move my player, or do anything.
What is it you're trying to load?
Game Instance Init typically fires before GameMode's begin play.
hello dev's i came again for the online beasts , so i have the pickup actor that is picked per client like if player one picked it up player two can still see it , i did this by your help last time , and now i have new issue with new thing , so i am trying to call a "Run On Server" event from anther Actor , to remove the player state from the "player who picked me " array so it can be picked again by that player , the issue is it seems this event is not being run at all , and my guess is owner ship or something , it says replicate to server if owning client so maybe this actor is not owned by the player so that it is not replicating the event , and i tried to set owner to the player and it's now working , but if i put the call inside the player it self it works like magic, but it would be good to know how to replicate to the server from normal actors in the world , thanks in advanced ,
i dont want to put logics in the player directly because we are a team and other people are working on the player character and i just want to have the pickups isolated , at the current moment i have the calls passed through a component , but as you know i am still learning and if i can do it directly on the actor it would be great
As you've discovered, you can't run RPCs on actor that aren't owned by the client and generally it doesn't make sense to constantly switch around ownership of actors.
If you're required to have the client tell the server they want to interact with an actor in some way, then you should have some kind of generic interaction RPC on your pawn or player controller that passes along a reference to the actor they want to interact with to the server. Once running on the server you can then determine what that actor is, or call an interface to that actor so then the actor can then do what it needs to do when a player interacts with it.
If you don't need the client to tell the server that simplifies things, as you can just gate the logic so that it only triggers on the server, for example, an overlap event on the actor can be used with a Has Authority (Authority) check so that you're only running the logic on the server if it is a replicated actor, and from that you can just do whatever is needed on the server directly on the actor without the client having to tell the server anything.
yeah i have the overlap logics runs only on server, but the pickups visuals are spawned for each client alone so when he picked it up i destroy just the visuals and add his state to an array so i can let the server check on overlap if this player already picked it up so i dont give him more pickups , because the visuals are already destroyed locally so he dont see it at all but the sphere trigger is on the level for others to use to pick so he may accidentally pick it up again , that's why i use this array, now as you say i think it is working great m i have a component on the player does the calling and that worked , so thanks again for saving my life
Loading variables on gamemode to define what someone spawns with, and how much at least right now.
(Is game instance not a like "entire EXE start", not "match start"
Right now I have this basically.
My main menu map.
In there you can find matches, start matches, etc.
if your the host, you can define match settings.
Those settings are stored on the game instance.
Then read by the gamemode, when the match is started/ new "pvp" map is loaded.
But, stuff like player spawn happens before the gamemode begin play, so currently connected players lack the host define settings, and only new connects after the match has started get the settings.
Game Mode Begin Play happens before players spawn.
What bind/ event are you using?
I'm using Init Start Spot
Begin Play
Is there no way to build it in the gamemode logic?
There is a Begin Play in Game Mode.
Right, but that happens after the gamemode provided events for when a player spawns.
Thought I could self contain it in the gamemode, not half gamemode, half each player.
Nope.
Thats another actor beginning play
I'm talking about containing it all in the gamemode, and using its provided evbents for when a player spawns
Gotcha..
I can split it between the 2 actors.
Just seems weird that the spawn eveents on gamemode happen before begin play, runining my ability to load settings, and containing it all in the gamemode.
Might want to use something other than Init Start Spot... Like Handle Starting New Player
I can go re-try just to double check, but IIRC, I think only there controller exists at that time.
Or SpawnDefaultPawnFor
How do I run a Linux server build in Linux? What's the command? I'm in a Linux command line navigated to the server folder but don't know how to actually run the server as I would run a Windows exe server build that starts the server locally.
I don't know how to use Linux and the Epic docs don't say anything about running a Linux server. I try running "install.sh" but the Ubuntu response is "command not found"
Yeah, those 2 still have the same issue.
I suppose this is an issue with underlying C++ executing faster than blueprint or something. It makes little sense that some of the player spawning logic would be triggering before Game Mode starts. Perhaps instead of "loading" the variables, you just have it read direct from the Game Instance as needed? Alternatively, maybe pass the values through the option string when opening the level and read them as needed?
the second .sh file should do it, last in list
Does that mean C++ will work fine, for
begin play
THEN
Start/ spawn?
No, but you can override InitGame()
So if you needed to, you could potentially expose an event in blueprints that you call during InitGame which you could then use to load your variables from your GameInstance.
how do i properly make a widget update in sync with the server?
The current logic flow is this
Time passage code in GameMode, with 3 variables. currentTime, finishTime and TimeRate
The 3 variables belong to the GameState, and the GM gets and sets those variables from/to the GS.
On tick (inefficient but i'll deal with that later), get currentTime from GS and update the UI to reflect currentTime
Problem: the widget does not update. The client and server can both access the variables from GS, but neither are able to update the widget
aaand i just solved my problem
i feel stupid
nvm i guess
Needs more rubber duck debugging
Hi, how would i use a repNotify to Update a variable serverside like this ?
Sounds unnecessary. If you're setting a replicated variable on the server, then you can just set the other variable on the server too at the same time.
Yeah i just realized that ther were no point in doing this 😅👍
Spawning some actors, they aren't replicating and spawning in client side. Only warning in the output log is "LogNet: Warning: UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor. Actor: None, Channel: xx", how would I debug this further?
I am working on a Block Voxel game and I want to replicate the terrain data to clients. This is my hierarchy: AVoxelWorld -> UTerrainManager -> TArray<AChunk> -> TArray<UChunkSection> -> FTileStorage. I've read this https://vorixo.github.io/devtricks/procgen/, but would it work since the terrain is modifiable or would I just have to replicate up the chain? Also, in case it's relevant, FTileStorage is paletted storage for a chunk section's blocks. It has an array of entries for each block in a section and a bit buffer which holds the indexes of which block is placed in which tile/position.
Very weird.
I packaged to a build.
and, now its backwards?
The player EBP happens first, then the gamemode EBP?
I don't have direct EBP prints.
But, you can see my setup (player EBP calling to gamemode) happens before my gamemode EBP logic for loading values.
what type/genre of game are you making? pve? pvp etc?
What is the correct way to handle an attack cooldown with prediction?
In particular how to sync accouning for latency
Hihi! I've encountered a bug that made me very confused.
When using the "Add Static Mesh Component" node with the required flags set for replication my components do not replicate. If I swap out the "Add Static Mesh Component" node with a pre-built static mesh component (That has the same settings as the one created at runtime) everything replicates properly.
Anyone know why this happens?
you are tring to make a replicated subobject created at runtime
not sure if BP created subobjects can even do that 
Ty for the link! I didn't realize that was a limitation of BP, but that makes it a bit less confusing. I was starting to think it was an engine bug after it worked with the component I made before runtime lol
If I set an actor's OnRep property and destroy it afterwards, is the OnRep going to get replicated in the same package the destruction is? I want to broadcast a destruction reason message, so I'm kinda right on end of lifetime line
The same question applies to a multicast. What if I want to fire a multicast right when the actor dies, are there instances the multicast will arrive later than the death event?
How would you approach something like this? I guess use something external to pass that message?
Probably separate the destruction into 2 stages.
First stage sends whatever data you want and is a proxy for destruction. Then delay the actual destruction with a lifespan.
The other way is, depending on what you’re referring to, is do you even need to multicast? Just have a function that kills the actor replicated, and run the local effects with the destroy
So one replication for both actions.
I think he wants to send some data about the destruction down to clients first.
I'm new to multiplayer and I gotta say its quite difficult to learn how everything works. The RPC, replicated variables and what actors exist where. Feels like a lot, but over time it gets better it seems.
So here's my current task - Display player name above Character Pawn.
I have created a code that seem to work correctly, no issues, but I have a feeling I have done it in a non-optimal way, so I'd be happy if someone reviews it:
(I use listen server setup)
It works correctly on all clients, but again I feel like I maybe need a switch has authority or something? To now call it more than needed.
Yes, you want a has authority check as Begin Play fires on both the server and clients, so whenever the client begins play, it'll try to set the name locally with a value which you don't necessarily want to happen.
Where do I put this check? Right after Begin Play?
Yep
I want to tell whether an actor (building) was destroyed or sold
Edit: I ended up using Lyra's GameplayMessageSubsystem. I broadcast the message server-side
In what actor is this begin play? The character?
yes the character pawn
Thats why I also use delay loop because apparently Player State is spawned after Pawn BeginPlay an also depends on ping
And if I use Authority = Remote, then all the Clients get names updated, but Server Client has default values.
Kinda weird behaviour to me. As I understand, when a Character is spawned, it calls BeginPlay on Server. Then the server replicates the PlayerName variable to Clients. And then on RepNotify it customizes the widget for each Client. But in reality Switch Has Authority = Authority leads to only server having the widgets updated.
Player State being spawned and Pawn BeginPlay are going to be utterly unrelated to each other. They could happen in any order
You need to attempt the initialization in both places
Don't PlayerStates have an OnPawnChanged event anyway? Probably the safest place.
Well my Widget Component is on the Character so I thought its the right place to write this logic
Ok so what happening right now - If I add Switch Has Authority = Authority (which is I assume the right approach), the the cast fails for all Clients in RepNotify function:
But why? Isn't RepNotify run on all clients so they should have a valid reference to their component?
Ok so the code didn't have any errors as it turns out. Its just that the widget component isn't created fast enough.
Really weird to me as for a newbie.
Widget Components suck frankly.
They encourage tying your UI to game objects which I intensely disapprove of
This now works as intended. No logic is changed, I just added 2 sec delay.
Yeah. You played with the new ViewModels? They are pretty cool and help decouple things.
I know there is also a TextRender. Is that any better?
adding delay should not be a way to fix things in multiplayer. There is no guarantee when data will arrive to clients, that all depends on ping.
Ye I know, its very bad. But at least I unsured that the code itself is not a problem.
0.01 sec worked as well. So apparently BeginPlay is just not a good event to do this logic that I want?
98% of the time I would say you use OnRep to do some logic when the data arrived
Setting up a PlayerName widget seems better to be done with RepNotify to me, instead of RPC, no?
Server RPC to send the server the client's name
But either way BeginPlay is not good enough if I don't want to include delays and timers.
OnRep to update the widget
I am working on the same thing, I have nothing on Begin Play
no delay and no bug either
Yes that is the question. If no BeginPlay as a way to Initialize Character, then what?
This is a very common thing especially in multiplayer. You have race conditions - where you're expecting one thing to have already happened but it hasn't and something else that relies on it is wanting it now.
Using delays is no guarantee that it actually fixes the problem as it could take longer than the delay you entered to actually be ready.
The only way to fix this is to ensure that you're trying to update the names under all condtions.
You'd have to ensure that you're having the widget somehow read the name itself when its constructed (or maybe use the pawn's begin play to feed it into the widget?) and you'd have to make sure it's updated when the value is changed on the playerstate.
I use OnAcknowldgePosession for clients (not exposed to bp if you are only using bp). I'm sure there are some other events you can probably use tho.
Fine for in-world stuff, but I have no idea why anyone would use it for screenspace stuff
I'm sure lots of YouTube tutorials use it though
So when BeginPlay on Character happens, there is no guarantee that the Widget Component is created, even tho it is a Component of the Character?
Kinda counter intuitive
The widget component may have begun play, but it may take another frame for the OnConstruct event on the widget to fire.
Hm I'll try to debug whats happening.
So I removed the delay in RepNotify.
Player 1 creates session -> Player 2 joins session / Result
So when the client joins session, his RepNotify for both Characters happen before Widget Construct, therefor it cannot access it
ok that one is better
Yep, so that's why you need to have the construction of the widget read the value you want it to have as well.
It's getting tricky here because the widget itself won't be able to get a reference to the pawn it's attached to. You'd have to feed in a value from either the pawn or playerstate to the widget.
How do I get the pawn tho?
Playerstate would probably be better.
Ok so here's my result (lets ignore player state infinite loop for now):
Now it works without any delays (the widget part), but I'm still not sure if everything is done right.
For example I'm not sure where I should set the Parent Pawn variable.
Hello, can we add a variable (exposed on spawn and instance editable) to a custom event from a "spawn actor from class" if we put the class to the custom event ??
How would it know which data to exposed when it doesn't even know the class that it's spawning
yeah i see, but when i specified the class in my call custom event, it kown the class and know witch variable is exposed ?
or how can i get these variable, i need it for replication, because it doesn't work when i put my player controler on it. it work only on the server for the server and on the client for the client
Create a base class that all such projectiles would use that has those properties and use that for the class refernece you're using.
Ok i see! thanks
Guys, does anyone know why seamless travel with a dedicated server fails in UE5? In the ue4 versions it does it perfectly with the same code with gamelift aws and in ue5 when doing the serverTravel with seamless the clients disconnect from the server
Perfect It's working ! Thx
is this not how you would replicate a timer ?
or dose the creation of the timer need to be in the rpc ?
Define replicating the timer.
The timer itself will not be replicated. You can either replicate the fact that a timer exists on all machines, or just replicate the effects that the server's timer has on something.
well
my problem is that is not counting down on clients, rather its like the time is set to 0 for the timers
so its not acctualy counting down
do i need to set timer by event in the RPC to make it count on all machines ?
Wait, are you guys saying people add widgets to their characters to control the HUD? I might have misread the earlier convo
because thats not how timer handles work
they're local
you create timers locally and check them locally
dont send handles over the network
well
what you trying to do?
well this is basicly for my "buffs" its for the duration of the buff being displayed with a progressbar
its not getting the values and couting on the clientside
because handles are purely local
im getting the value by reading the "remaining / elapsed" time on the timer
yeah
i get that but im trying to find a solution for it 😛
hm
i could
Predict the progress
let the server handle the timer and client can just simulate it
You'd only need to pass the end time of the itmer to the client to do so, just need to make sure it's in the right time format.
Then you can compare current time to end time and get your time remaining.
yeah and by end time u mean timer remaining basicly
Server > Set a timer, get the CurrentTime + add a timespan of how long your cooldown is. This new DateTime is what you could replicate to the clients.
When the client receives it, they can check it periodically and get the timespan between CurrentTime and CooldownEndTime - this'd give you the number of seconds remaining.
hmm
Only thing I'm not sure of is if timezone stuff could mess things up, but this is the gist of it.
hmm okey, but is this a common solution for timer replications or ?
Yes
Uh are you suggesting FDateTime for gameplay timers?
Not to keep track of how much time is remaining on the server, but to replicate the end time for the client.
Timer handles don't replicate, so I'm not sure why you couldn't just send the time in the multicast
You don't have to use FDateTime at all
No guarantee of when it could arrive, resulting in mismatched times.
Yeah and everyone's computer clock is perfectly in sync, yeah?
@lost inlet so this would work in your opinion then ?
Mostly yeah
You can send a world time too, since the game state sends you a server world time
Which is also accurate enough
hm
yeah that worked like a charm
wdym with send a world time to ?
how would i do that ?
Same thing as what I just described using the Game State's Server World Time instead of UTC Now and DateTimes.
Replicate the expected end time, check current against end time to get the cooldown remaining.
ah ok
When at earliest is it valid to get player state from pawn. After possession?
On client whenever it is first replicated.
overriding the OnPlayerStateChanged function in APawn
I think it might be a 5.0+ thing, because can't see this in 4.27
Are there any other options? Currently working on a non multiplayer project.
Oops I noticed I posted in multiplayer, my bad 🤦
oh it might not be exposed to blueprints if thats what you're using.. pretty sure playerstate will be valid after the ReceivePossessed event is called in blueprints
I'm using cpp. I'm prety sure it is not available in the engine version I'm using. I checked 5.4 and indeed found APawn::OnPlayerStateChanged. No trace of that member function in 4.27 whatsoever.
I will try ReceivePossessed, thanks 😄
ah yea sounds like it just doesn't exist in that version
@sinful tree@lost inlet ok so when doing it this way im still using the "Event attached to the timer" wich makes it run on the server & client how can i make it only run one or so?
?
You shouldn't need to multicast anything.
If this is a shared timer of some kind that everyone needs to be able to see, then have the server start its own timer based on the needed value > this timer is the "authority" to know exactly when the cooldown ends. Have the server also set a replicated variable with the GameState's Server World Time + Cooldown - this will be an accurate indication to clients to let them know when the timer should end.
An OnRep would likely be a better candidate so you can then have it trigger the start of local timers to check the remaining time. This can likely be skipped on the authority as they have the actual authoritative version of the timer they can utilize.
hmm
Hello! I am curious as to when would you guys consider having the player characters as "always relevant". For example, would it be ok to use in a Battlefield style game, and on the other hand, on a DayZ style one?
Player character probably never. Too expensive to have just casually replicated even when other players are half way across the map
You want to replicate mostly the stuff that is around the player
But what about when the players are shooting snipers? If they are out of relevancy, they can't see each other
Override IsNetRelevantFor... You can check if someoen is in view of the scope 😛
Increase the relevancy when sniper is scoped in, but narrow the replication only to like 90 degrees infront of him
Or even better use RepGraph
Getting a common warning that has been driving me mad the past few hours
LogNet: Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor
I've tried setting the owner of the actor to the game state
I'm currently making a component for my player character that will RPC to the server to attempt to call the function locally, but was wondering why setting the owner to the Game State didn't work
the player needs to be the owner of the actor sending rpcs
So why do Game State RPCs work?
Or am I misunderstanding ownership?
I'm still a bit fuzzy on this, compared to RPCs and other aspects of UE Networking
The only type of RPC you can call on Game State that works is a multicast
Run On Server or Run on "Owning Client" won't work because it's not client owned.
Are there some special rules that prevent me from using SetSkeletalMesh() on multicast to replicated it to all clients? I sort of know how to do it with OnRep
But it doesn't work with multicast
No matter how I try it
Multicasts don't keep state. So if that actor happens to go out of relevancy and come back in, they'll have whatever the default skeletal mesh is for that actor type.
Replicate either a number that represents which mesh to use, or replicate a reference to the mesh itself and use an OnRep to then update the skeletal mesh component to the desired mesh.
Yes this is how I have done it in the past... I will do that but it is not going to be very clean way to do it when you have 10-15 replicated mesh refrences
Everything that you need to keep state for needs its own variable. If you wanted to tidy it up, you could potentially use an array, but then that's likely sending more data than needed any time a value changes.
I am trying to extend the VR template to multiplayer. I have been able to replicate teleporting, rotation, hand movement and hand animation. Next, I want to be able to grab one of the cubes and push the other cubes away. This seems to work on the client but is not on the server. On the server the cube moves through the cubes that the client is trying to push away. Grabbing the cube and moving it around works. Does anybody have an idea of what is going on?
Has anyone done any serverTravel with gamelift in UE5?
I have a problem where my client when traveling with the serverTravel with my Gamelift server disconnects and does not create any player controller
Idk if I understood you right but it sounds like you have physics enabled on the cubes so you have to look into physics replication. On skeletal mesh you have "replicate movement" setting which at least gets you started
Thanks! The thing that I don't understand is that the physics are disabled of the cube that the client grabs (this happens on the server). And they are enabled again when the client releases the cube (this also happens on the server). No hit events are triggered on the server but they are triggered on the client. Does this mean that the other cubes, not the one that the client grabs, have also disabled their physics? Do you mean the skeletal mesh of the hand grabbing the cube?
Get Player Camera Manager takes in an index, how can I get whichever one is local in this case?
You can use a reference to the player controller and get its player camera manager directly if it's valid and locally controlled.
Does Anyone know how to replicate the followCamera from the BP_ThirdPersonCharacter template? I try it but, it work on server but screw up my my client. I think i have a probleme because of the spring arm componant but i'm comfuse ?
How would I replicate a material parameter?
Replicate the value or a number representing the value you want in an Rep W/ Notify variable and then adjust the parameter in the OnRep function.
stupid/not stupid question. Default value of variable is 0, I use a repnotify in BP to set it to 0 hoping it would trigger on the clients and do the events I have inside the repnotify. it doesnt (as expected?) since it didnt change from 0 to 0. Is there anyway to force a sync of a variable like this so it fires off no matter what to trigger the rep notify on the client?
is it possible the server first check the client game version before accepting his connection?
In C++ I know you can have a rep notify condition of always which forces it.
yep thats what I saw as an option, was hoping it was exposed to BP but It looks like not? if theres no magical checkbox then -1 for the default value is it 🙂
it already does this <3
oh, if i change the version of the game, build linux server and host.
client will be unable to join with the old client build they have?
I think it depends how it's setup, it's been a while since I messed with it but it should make a hash when you package and if they mismatch you can't join
That might be only if you have EOS enabled? But there's definitely a thing to do this
iirc it's in the game session
I'm really confused i'm trying to find it, am I just schizo, i swear this is a thing
I think it might be this
i am using NULL
not using EOS
Yeah I think on NULL it doesn't verify build compatibility
not sure
It definitely won't if you're joining servers without using session join
If you want a really dumb and simple way to do it without using online subsystem, you could override ApproveLogin on the game session and just pass in the game version as a connection argument
but that's not secure at all
but it will work just fine
You can just parse an for an extra int option here "Version" and then check it's the same as servers
if you don't care that people can just hack and change the string it's fine, which tbf for majority of cases is going to work fine
this is a decent solution in my case
<3
Alright multiplayer wizards, i need some help.
This animation refuses to play on the server (it plays on clients perfectly) It goes through as it the sound plays, but the animation gets completely ignored. Where should i be looking to fix this, i am at a complete loss.
is the 'mesh' variable set on the server? maybe debug/print it and see what the server thinks it is
Can anyone give me some 'nuggets of wisdom' you've learned in your years with multiplayer?
These could be specific, or technical, or workflow, or anything
Hello guys, my boss ask my about implement EOS plugin but avoiding user authentication. By the moment I'm using the TrustedServer policy in the client (only one client by far) settings (Unreal Developer Portal). Am I in the good way? Any further considerations would be extremely appreciate. I'm not getting any useful example by the Internet 🥺 . Thank you kindly.
For example one anoying bug is that sometimes, when I play the game in other computers, my app login implementation redirect me to the user authentication epic games' url. It happens is some computers. In other computers is only about confirming you trust the application in another epic games' url.
Is not about the computer...if I play it in localhost 3 times the game, there is like...a probability of one of the executions being redirecting to the user authentication url.
https://cedric-neukirchen.net/docs/category/multiplayer-network-compendium
https://wizardcell.com/unreal/multiplayer-tips-and-tricks/
Plus a few others - all "pinned" on this channel
My fix is always just to call the rep notify/ edit on begin play.
Unless its some intense wall of logic.
Doesn't exactly hurt to run it twice
How many "max results" did you define?
I was stuck, because that value is bugged.
Its "max results ever", not "max working results"
So, it'll find the thousands of other spacewar servers, hit the max, and stop. I set my max to like 9999999
Because, it did succeed.
But, reached the session limit, and all the sessions have invalid ids, that don't match.
It trolled me for a while
10 max sessions - nothing
Made 1 change
999999 max session - found my servers/ matches
Both triggered success, because from a logic standpoint they did succed, servers were found.
Just invalid ones, and it doesn't check valid status when count it as a session compared to the max
When your game no longer uses space war, it becomes a less/ non issue.
Because, now the 10 sessions will be valid, because they are your game and have a matching ID
Googled for a while.
Tried like 5 things on the internet.
That was the only one that worked.
The other 4 at the time made sense, but after further thinking, made less sense.
because, I was able to create and "find" sessions, and if you run your game with -log, you can see session log spam of invalid gameID or something.
Someone please tell me what I'm doing wrong.
I just want both players to enter a number and display those numbers.
Why are you Multicasting the value of a Replicated variable?
PlayerNumber is already replicated, you dont need to then Multicast it.
Set it to RepNotify and call the EventDispatcher in the Notify function.
@fossil spoke help
Marking something as replicated doesn't mean that it'll all of a sudden work 100% over the network. This component isn't something that is included with Unreal so you may need to go to whoever you got this component from and ensure that it is actually setup for network movement and check the documentation for what is required in order to get it working over the network.
I made it
And absolutely alhave no networking experience
This is the only thing not working others I have sort out
..
@fossil spoke
Let's assume that I am not using Advanced Sessions at all, how would players join each other (in BP)? Would they need the IPv4 and the port in order to join?
That explanation was actually such a revelation, that different actors and even variables in those actors can initialize in a non logical/non expected sequence in multiplayer. I was keep bashing my head, thinking that my code doesn't work because I can't understand how multiplayer works, but in fact the logic was correct, its just that the stuff I wanted to access wasn't ready.
I kinda wish there was an simple Event that would be called after a Pawn is fully initialized on the Server and all Clients, but idk if thats possible to make.
You technically could do something like that, but it would require your clients telling you if they were initialized or not as the server doesn't actually know anything about what is happening on clients and instead only has the data about what it itself knows about the actors that exist on its end. (I think maybe I misunderstood what you meant though...)
The thing is, what constitutes when a Pawn is fully initialized? That can vary between games. If you need to know that the playerstate is ready on the pawn you kind of need to dig into C++ to be able to get that event. Need to know the widget component is ready? From what we've discovered it's usually Begin Play of the actor that you can start to use it and feed in data. So you'd have to figure out where all these things are actually ready, set bools to indicate they are ready, and then have them call a function that checks all the bools when you've set one of the bools true, and when they are all true, you can fire another event to know that the thing is initialized.
I've come up with a simplest solution (without any code in the Widget itself) for my PlayerName and it works:
So basically I loop check (yes its not perfect, but its still practical, let perfect not be the enemy of good) on BeginPlay if Player State is created and ALSO that its PlayerName is not empty (because again, turns out this variable can be set slightly after). And then on RepNotify I check if the Widget for the Actor exists, because when a new player joins, RepNotify fires faster than the Widget is created somehow (not logical as to me, but it is what it is and I get it now).
Although all this struggle kinda makes me think if Pawn Initialization even good for stuff like that. Like lets say I want to initialize the Gear that the Character has, would that also be such a condition race?
yep - Steam/EOS etc abstracts this away from you. Without that, you can just use IPs
Why not have a delegate you fire when your OnRep_PlayerState fires and just call this in response to the delegate?
Potentially, it depends on what is required. The issues usually pop up if you're trying to use multiple individual replicated things at the same time,
please dont ping people, especially mods, for random help. They volunteer their time, and are not on call for non-mod related issues. You need to work through the issue and try different options. Does it work in single player? Then slowly add sections from there. to me the issue on the video looks kinda like the server/client are not sync'd - so debug their values and go from there
@floral sail
I don't really understand how Event Dispatchers work yet. I can't understand whats the difference between them and usual events and what they are for.
I use c++ so idk the bp land terminology but dispatcher usually is something you bind to and it will be called later at an arbitrary time
Callbacks > polling almost always
Right gotcha. That is good info to know. A little extra context though;
I am using PlayFab for players to match up with each other through a queue system (Akin to any battle royale game) and for now want to use a listen server to host the match.
How would I go about determining which player should host the match after the players have gotten into the battle royale queue and thus open up the listen server, after which everyone else can join that listen server?
Really appreciate the help 🙂
They're a means of listening for an event and anything can subscribe to that particular dispatcher. A good example would be a slot based inventory and widgets that represent that inventory. You can have an event dispatcher on your inventory component that broadcasts when it gets updated. Your widgets just need a reference to your inventory component and they can bind to that event dispatcher and have their bound event look into the inventory and refresh the data they're supposed to display. No need to have your inventory component tell your widgets anything other than broadcasting that dispatcher.
Your widget on its Construct/Beginplay whatever its called will get its owning pawn, you query if that PlayerState is valid, if its not then you will get the event variable that fires on the owning pawn (the delegate you setup to fire in OnRep_PlayerState) and then thats it, when it fires you go ahead and run the function. @floral sail
(Player controller also could be a point have that same functionality in its OnRep_PlayerState, pawn or controller is up to you)
can anyone tell what can cause this?
PS /adminacc/LinuxServer/ARMA/Binaries/Linux> ./ARMAServer-Linux-Shipping
5.4.2-0+UE5 1009 0
Disabling core dumps.
MessageBox: Message : Failed to open descriptor file ../../../ARMA/ARMA.uproject
Preparing to exit.Shutting down and abandoning module SandboxFile (6)Shutting down and abandoning module PakFile (4)Destroying PakPlatformFileShutting down and abandoning module RSA (3)Exiting.Exiting abnormally (error code: 1)
Oh well, thats still kinda vague to me. Gonna need some time to research.
AActor is replicating Attachment data by dafult
FDoRepLifetimeParams AttachmentReplicationParams{COND_Custom, REPNOTIFY_Always, bUsePushModel};
DOREPLIFETIME_WITH_PARAMS_FAST(AActor, AttachmentReplication, AttachmentReplicationParams);
Any idea how to override this in child class to disable replicaiton of this variable?
Are you planning to always support listen servers, or is it just for testing?
Let's assume I will never make enough money to make use of PlayFabs dedicated server service 🥲, so yes I want to support listen servers for the whole lifetime of the game.
this is probably a mega dumb one, but does anyone know how to replicate player camera manager? this is how im doing it at the moment and it's not working (spawning at 0,0,0)
this is player camera controller
fast question yes or no:
Is there some limitation regarding interfaces to be replicated?
I am not sure if I read is not possible, they should work fine if I set up sending to server etc ?
So as I understand there are 3 steps to create an Event Dispatcher:
- Create and Call it in Actor 1.
--Calling an Event Dispatcher is kinda like calling a Function in a sense that in the end it will perform some logic - Create a Custom Event in Actor 2
- Bind the Event Dispatcher to the Custom Event in Actor 2
--I can bind it at any point in the code, as long as it happens before the time when I would need the Custom Event
--Binding means that the Call of that Dispatcher will lead to the Custom Event logic
That way I can tell if my PlayerName Widget is created in my Pawn Blueprient without loop timer and without a reference to Pawn in the Widget.
Do I understand everything correctly?
Yea, you've got it right. Just keep in mind that the construct event could happen before you had a chance to bind to the dispatcher in which case it may not be all that useful to use a dispatcher for this but if it does work how you're hoping then all the better 🙂
Well widget component can never be constructed faster than the Pawn BeginPlay that owns it, it can not be that chaotic right? 😅
Easy mode but eww is to just update on tick
Well its cool to have such a tool, that will be helpfull for sure. But for my task I'm not sure it better.
I understand that from a programming point of view, making Event Dispatchers on Widget and PlayerState creations is far better than loop timers, but that will lead to a good chunk of new code and will reduce readability.
I would need to Branch both Events to check that Both Objects are created, and then again I can not create an Event Dispatcher for PlayerName variable change in the Player State, so I would need a loop for that anyway.
So I guess my initial solution with loops is better and its cheap enough to afford.
^ Here is my solution
Delay and timer shouldn't be a solution to race condition especially for multiplayer
The task is to update PlayerNameWidgetComponent for all Clients whenever a new Pawn is Created.
Ik what you are trying to do. You want to create a name tag above players. I got exactly the same thing.
If I want a clean solution then I would want an Event Dispatcher in the Widget construction/on init and in Player State BeginPlay.
But then there is more - PlayerName in PlayerState isn't assigned before PlayerState BeginPlay.
How can create an event for PlayerName value changed?
I think begin play is not a great place for many cases in multiplayer
I don't know any other events to initialize something.
OnAcknowldgePossesion for clients
But not exposed to bp, so you will have to look for another event that is called on client
That's called on server
But its for Player Controller, not Player State
Check out view models.
The client tells the view model data as it comes in.
Widgets react to data changing in the view model.
It’s pretty cool
If you see icon with the electric thing, that is indication that it's called on server
This one?
Oh well since it seems you only want to use blueprint, I can give suggestion that you can do the ez way
Make a name variable in the player staye
Create widget when ever you like
The widget reads from the player state and the name
If name is replicated variable the value will eventually will be updated
And widget simply read from it
Reads when?
Reads every tick (binding)
Thats even worse than loop timers tho)
I'm not saying I would do it that way either
Checking it out rn. Seems interesting.
Ok will keep in mind
Yes works in single player
Actually thats exactly what I need, because I need server version of the Pawn to replicate my variable.
Event Possessed means that the Pawn already has Player Controller, which means it already has Player State with the data I need. I can remove now loop check for PlayerState and PlayerName on PlayerState and it works.
The only loop that is left is in RepNotify. It is needed because RepNotify fires faster than the Pawn initilized/Widget Created.
Hello, I’m looking to understand the method for obtaining a value following the execution of a custom event. If it’s not possible to directly retrieve a value, what would be the alternative to access a value after triggering a custom event in Unreal Engine 5.3?
I have a game that is in the very early stages and primarily single player, but looking into the possibility for co-op by having up to 3 friends join the host's session (so no dedicated server, cheat prevention, etc needed). I'm about to rewrite the controller and movement system anyway, so I'm looking over alternatives for making it networked.
Does anyone have some insights into what would be most suitable for this kind of setup? Regular CMC, plugin like GMC, the new Mover 2 component, or something else?
That question makes no sense fyi. You will need to rephrase it.
True, but I've seen quite a lot of people running into issues with it and instead recommend going with GMC to avoid the headaches. I'd rather pay that extra cost than lose potentially a month or more of dev time, but I'm not sure if it is overkill for my use case, or even recommended at all by experienced people.
I never used it
We use Mover atm. Can't recommend if you aren't able to do custom changes. Not production ready
And I'm sure it's going to have a ton of breaking changes
https://github.com/EpicGames/UnrealEngine/commit/fe8bdb8d3db97f5db79527a110cf2f39935ec9bc already moving to gameplaytags from FNames