#multiplayer
1 messages Β· Page 48 of 1
Any time someone joins the game.
Yeah, the old school shooter project from unreal does a lot of iterating over all player controllers and doing something to each of them lol
because on my lobby i do that and then store controller on a gameInstance to get it after switching level
Datara is this the BP version of PostLogin?
Player Controller references stored in the GameInstance won't be valid after transitioning from one map to the other.
ah
PlayerState might be persistent, but I'm not sure
atm i do that then in the other game mode spawning the player (this is lobby game mode)
PostLogin is where it's safe to call RPCs from the server to the client on the player controller.
HandleStartingNewPlayer is where the player is ready to enter the game, ie. before their pawn would be automagically spawned.
In the other game mode you could just let the game mode spawn in the players. If you want them all in an array you can store them in PostLogin maybe or if you want to be sure the pawn is possessed by a specific controller you can do something in the character's OnPossess
@jolly delta I've just realized that my spawning setup wouldn't be applicable to your use case, when your players transition from the lobby to the "game", do you load a new level? If so, do as @bronze mauve suggested, just have a separate game mode for your lobby and game and set the default game mode for the "game" level to the "game" game mode that will spawn using the native way
this is what i do to switch
then TopDown level has a different gamemode
It's not really necessary to store the controllers in the game instance - it's just not worthwhile as the references will be removed on hard travel.
GameState already keeps track of the PlayerArray which is a list of all active player states, which you can get controllers from if necessary.
Yeah your switching code looks okay.
I'd just let the TopDown spawn players on its own.
Yeah the player states array will already exist for you as well.
Loop through that to do custom things like sort them into teams for example
sound so logic that i do not understand why i have not think about it
Okay, so you can just use the "Default Pawn Class" for that on your TopDown level game mode, If you need more control over the spawn process, you can do something along these lines in the TopDown game mode, my system has a concept of player selectable classes from the game instance, but that part is optional.
EDIT: The 1st screenshot is from my game mode, the second is from my controller, the last is back in the game mode
I have an issue with a TArray on my client. I add items to the array on server side using "UFUNCTION(Server, Reliable)". This seems to make it so the client side TArray will never be populated, and I am unsure how to query the server side TArray for the client. Any hints?
Ah so in your case you can choose the character class before traveling to this level?
How would you store the chosen class that was selected, in the game instance or player state or something
Typically, replicated variables will automatically update on the client, you don't need to "query" the server for it
Replicate the array and only populate it on the server
Yes, correct, you can see the example of how I get the class from the game instance on the client side in the controller
Just remember that the client side array is just a reflection of the server's and you shouldn't add to it client side
Beautiful
I wonder if there is a way to enforce that.
Just so I am sure I get this right, if I replicate the TArray using the "Replicated" keyword in the UPROPERTY macro, it should automatically mirror the server's TArray? Do I need to do more before it is replicated correctly?
You also need to add it to GetLifetimeReplicatedProps
For example
void UEBInventoryComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
// Lifetime variables.
DOREPLIFETIME(UEBInventoryComponent, InventoryItems);
}
2Fast4U 
Too fast for... oh forget it
Ahhh. That actually makes sense! Thanks both. I will test it out and then either cry or smile in just a bit!
It's usually in that order 
So with replication of TArrays... is there any built-in optimization?
If the array has 4 elements and I add a 5th, does the whole array get serialized and replicated down or just the 5th element
Smile-crying is acceptable too
Take a read of this, there's likely something regarding that in there regarding TArray delta serialization
http://www.aclockworkberry.com/custom-struct-serialization-for-networking-in-unreal-engine/
Where do I actually implement this method? In the component itself?
In your class that holds the replicated property itself
Yes cool thanks. That's what I meant - forgot to specify that my class is an actorcomponent π
I have now tried the following: 1) add the replicated TArray to the lifetime replicated props on the base component class, and 2) add the replicated TArray to the lifetime replicated props on the child component class that derives from the base class. In both examples I seem to run into the same issue where the TArray is only updated on the server side, and not the client. What would you recon I did wrong here?
I'll be happy to screenshare the code if that is easier!
Okay so from what I think I gather, you can replicate arrays in a more optimized way, based on delta states, if you wrap them in an FFastArraySerializer and define the NetSerialize function for it
Some screenshots of the relevant code would be sufficient (your header, the cpp where you're updating the array, etc)
Yes, I believe that's the general gist of it
You only need to register it in the class that contains it, i.e. your component. Don't add it to GLRP in the owner of the component too.
Also if that component isn't set to replicate, it won't replicate any of its members even if they are marked as Replicated
Afaik
That FArchive << magic is pretty crazy
I didn't know it was overloaded to work both ways based on context
Laura told me that yesterday in another channel but I don't think I fully grasped what she said lol
Edit: I am too stupid to post screenshots in the correct order, but it should be self explanatory what's going on
Basically, the DebugAddWood calls the AddItemOnServer, which calls the AddItem function
Is this image the only time you check your hotbar items to see if it was added? If so, are you sure it's not actually been added but you're just checking it too soon?
https://media.discordapp.net/attachments/221799385611239424/1059128691814301707/character_AddItemAndGetItem.png?width=950&height=349
Also, is your PlayerHotbarComponent definitely marked as replicated?
Oh let me check that last point
For the first question, I also look in the editor when adding items. It doesn't update the client's TArray.
what is the behaviour of posses ? when i use it it remove my pawn of the clients
I totally missed when you guys told me to mark the component as replicated as well. It works now! Thanks a lot @weak linden and @bronze mauve. I have marked it as replicated using blueprint for now, just to get things moving
Possess, takes control of the pawn you specify, I.E it will de-possess the existing pawn and take control of the new one
It's always something simple π glad you got it fixed!
but it only allow the controller to controll the player on client side right ?
Oh yeah definitely do that π
It's a global process, it should be executed server side, but yes, It will allow the client who the controller belongs to, to control the pawn
Yeah it's confusing, but the player state, player controller, etc. Are all associated with a player. ULocalPlayer I believe?
even if this is not exeactly what you tell me to do, for test purpose is this is supposed to work ?
because if I remove the possess it spawn the actor on each client as expected but when i add the possess the actor is mission on every clients
idk why but location on client out of sync with server
so im attaching actor to actor on server
client side actors are in different location
there is a way to force transform sync ? or something like that
yes
delay fixed the problem but i have feeling this is not correct way
link func
on linked runs
Has anyone here used the General Movement Component plugin from the marketplace? Is it good? Sure looks like it 
guys when i join my game I get instantly kicked after loading map this is what I have in log do you have any idea where can be problem?
warning 2 ?
idk why connection is lost it looks like I was kicked by some reason
there is no session to join so u got kicked
no there is session to join and I am already joining it ,that warning is there always it was there even it was working it's some warning from inside of unreal idk why
so i don't count it
did u make the session ?
yea ofc
here is my server with session on laptop
now from pc i tried again and joined but it is weird
sometimes it kick me
you can see this is second part of log
same as previous saying no sesssion to join
which is normal
wrong ip and port on client ? or u missing something else
nono thats all is ok something in blueprints inside must be wrong or spawnpoints thats why I get kicked sometimes but i dont know what of these
is there any reason that force me to add a delay here ?
u don't need delay
unless u trying to run it on client with is wrong
Delays as a fix for something are 99% of a time wrong
The only times where a Delay for a fix is fine (if it fixes it) is if it's a Frame Delay :D
in that case if i do not add this delay my actor disappear
hmm it's really weird both logs from my games I don't actually understand what's going on even I now don't get kicked from map I don't see each other there
hmm
u are in single player because connection to server failed
that's unreal because on server log I can watch I am joined there are logs every sec of my joined time
packets
which are sending server to client
gonna debug it maybe I will find solution
That's the worst place to put a delay
Loop Executions don't wait for the Delay to end
@real ridge
try to add 2 rpc one form server to all
and other form client to server with print string
and send it every 10s 10 times
if u don't get 1 of then u know u are not connected
You will probably get the last iterations PC there all the time.
Why are you handling spawning of your Characters by hand anyway?
You can just put your Character Class into the GameMode's DefaultPawnClass
And override Find/ChoosePlayerStart to return a PlayerStart of your liking
That would also remove the need for any shitty delays
Cause it calls properly for every player once they are ready
UE Multiplayer is all about understanding what Unreal Engine already offers you instead of reinventing the wheel
i am doing it but I did not enable it now I will I have it used as internet connection test
You should honestly delete that function and have your GameMode handle this as explained
A lot less headache
You can even dynamically select a Class for each Player if you override the right functions
GameMode has a lot of functions in the Override tab
Once you learn this, you'll have a much easier time
Yes listen exi he is boss
i know ahah i am a beginner on unreal and even more on network
Bump :^)
Sometimes I successfully connect to server but sometimes I am one second after joining kicked and this is log what can be problem?
Is it enough to simply add bReplicates = true; in the constructor for an AActor to obtain the same functionality as ticking the "Replicates" tickbox in an actor's blueprint?
Try to search the channel for it. Someone had a look at it
@whole grove maybe knows who that was. Wizard maybe?
(that Marketplace movement comp)
From the video and tutorials it looks pretty darn good
Yeah looks like messages say the same
Honestly looks easier to extend than the CMC for custom movement
and the possibility to use different shapes is nice as well
That general movement component looks epic
a good way to achieve what i want to do will be to call on level bluprint on each client a command to spawn the actor ?
like :
begin play level -> call spawn -> on game mode spawn default pawn -> posses it
?
The RPC works on the server and the flipbook is visible to other clients, but the function is not executed on the client
Woah, you're sending an update to the server on Tick? Might want to rethink that.
But anyways I think you'd want to call the function on the client too
Why not just inform the server when the state changes, and have the animations update in tick locally?
Thanks, i'll try it
I meant if you know the user who looked at it and tested it.
But I wasn't clear enough via the phone typed message, sorry
What?
I never said that :D stop making up things, this isn't useful
i'm lost sorry
The GameMode already handles everything
guys how I can send here log as txt? I dont want spam whole chat i Have one log to show
Seems like the server really just needs to know the state, and even if the flipbook updates aren't in sync between server and client
Right, thanks, that's all I wanted to know
okay I have it @whole grove thanks, guys here I have my log from my dedicated server there are bunch of errors which I have propably need to fix but for some reason I am getting kicked from this server short after joining do you see problem why? I cant find it thanks
dang no red squiggles for my missing semicolon though... πΏ
@thin stratus
You can just put your Character Class into the GameMode's DefaultPawnClass (edited)
And override Find/ChoosePlayerStart to return a PlayerStart of your liking
That would also remove the need for any shitty delays
Cause it calls properly for every player once they are ready
i do not understand how to do that..
oh wait
You can just open your game mode Blueprint and set the Default Pawn Class.
But you're WitchCell, so you have ownership rights too
Roxxor so... when the server processes a new player, there's an entire sequence the gamemode does server-side that includes acknowledging and verifying the player is okay to join the server, then it starts an entire sequence starting with InitNewPlayer
this includes finding the default pawn (which you can override to decide what pawn they should use), finding a playerstart for them to use, etc.
then whenever you need to, you can call a server restart on the player controller that will restart the sequence and find them a new place to spawn, give them a new pawn, etc.
it's best to override the functions within the gamemode that already handle it and just add functionality within the existing framework
@solar stirrup TLDR: it's really easy to understand and extend. Also look at the tutorials if you haven't done so, they give you a better picture of the plugin. Honestly best plugin I bought to date. The creator is friendly and helpful too ^^
The creator is friendly and helpful too ^^
Hasn't been broken by the Marketplace yet
Whatever God bless their soul
oh, exi, i know you probably don't remember but i FIXED MY ISSUES with my custom movement component!
Which was that

defo grabbing it when i can
the one where i was getting issues with like collisions bugging out and stuff? basically have a tank-control style pawn i'm making and i didn't want to use character and cmc because they're really heavy for something this simple
The only sad thing about the plugin is that it gives Epic another free card to ignore the problem at hand
I grabbed it while at sale (30% off that was iirc)
π€‘
it turns out i was A) sending the wrong rotation data to the server in every move packet, and B) i was using addyawinput on both the server and client, which was generating inaccurate rotations because it was resolving the rotation at different times
Full price or go home
Support the poor soul
so now i've fixed the rotation data sending, and fixed it so i read and write directly from the controlrotation on the controller
and like EVERYTHING fell into place, it works SO beautifully
True tbh
That 400 or whatever it costs doesn't get you far nowadays
Looks very much worth it
i'm so proud of myself LOL, i can't believe i figured it out
epic's cut, whatever actual currency they have and taxes
They keep little from it
And you save a shit ton anyway if you need this
Cause you otherwise pay probably something with four zeros to get this done from scratch
100,00 of course 
sigh
it work like that π₯
Yeah that's one way of doing it
You can keep that if you want
Is there a reason you use a TMap and construct a String?
Instead of just an Array and using the Integer as index directly?
is one of my coworker that do that so
we are student ahaha x)
the way i do it is i have my own player starts in my maps that contain the data i need, and i have custom functionality in ChoosePlayerStart to pick one for me
Yeah that's how one usually does it
thank you a lot for your help
mhmm, also remember that uh... restartplayer is a functionality you might want to think about! so for example, when the pawn that the player has runs out of health, you would want to be able to have the player depossess the pawn and have it be destroyed, and then restart the sequence with a new pawn
HandleNewStartingPlayer only fires once at the beginning
Yus
it's a bit more advanced, had has different functions you'll want to override, but for now that definitely works
Gotta figure out how to increment that int then though
Think the Choose functions are const? maybe not
server travel reset controller data right ?
Not always
but it is a bad behaviour to trust about it if is is not always ?
void AGameMode::HandleSeamlessTravelPlayer(AController*& C)
{
UE_LOG(LogGameMode, Log, TEXT(">> GameMode::HandleSeamlessTravelPlayer: %s "), *C->GetName());
APlayerController* PC = Cast<APlayerController>(C);
UClass* PCClassToSpawn = GetPlayerControllerClassToSpawnForSeamlessTravel(PC);
if (PC && PC->GetClass() != PCClassToSpawn)
{
if (PC->Player != nullptr)
{
// We need to spawn a new PlayerController to replace the old one
APlayerController* const NewPC = SpawnPlayerControllerCommon(PC->IsLocalPlayerController() ? ROLE_SimulatedProxy : ROLE_AutonomousProxy, PC->GetFocalLocation(), PC->GetControlRotation(), PCClassToSpawn);
if (NewPC == nullptr)
{
UE_LOG(LogGameMode, Warning, TEXT("Failed to spawn new PlayerController for %s (old class %s)"), *PC->GetHumanReadableName(), *PC->GetClass()->GetName());
PC->Destroy();
return;
}
else
{
PC->SeamlessTravelTo(NewPC);
NewPC->SeamlessTravelFrom(PC);
SwapPlayerControllers(PC, NewPC);
PC = NewPC;
C = NewPC;
}
}
else
{
PC->Destroy();
}
}
It depends on the Class your GameMode uses
If the previous GameMode uses the same PlayerController class, then it won't recreate it
Then it only does this:
else
{
// clear out data that was only for the previous game
C->PlayerState->Reset();
// create a new PlayerState and copy over info; this is necessary because the old GameMode may have used a different PlayerState class
APlayerState* OldPlayerState = C->PlayerState;
C->InitPlayerState();
OldPlayerState->SeamlessTravelTo(C->PlayerState);
// we don"t need the old PlayerState anymore
//@fixme: need a way to replace PlayerStates that doesn't cause incorrect "player left the game"/"player entered the game" messages
OldPlayerState->Destroy();
}
oh find my mistake i think, the var is not synced with the server
Also, the code might not show it, but in both cases it will call OldPlayerState->SeamlessTravelTo(C->PlayerState);
So you always get your CopyProperties call on the PlayerState
(also, it's really highly advised to read through some of those classes and learn a bit of c++)
cause knowing this is pure gold for UE multiplayer
can I have BlueprintImplmentable NetMulticast ?
avoid multicast's if u can its directly writes to buffer
ak u can have player 1000km away and it will restive it
- if is reliable it can create a lag spike with ~20-50 players on server
no dont give wrong info man
and if u set it on tick it will get worse
if its not net relevent it wont be casted
im using it for some of my events , and its better than Replication in this way
its fire and forget event
UE live stream https://youtu.be/mT8VUVuk-CY?t=3973 somewhere here
yeah, but then remember it's also not uh
it only exists for the time that it was fired
so if it becomes relevant after it was fired, it won't recreate the multicast
thus, on rep variables become invaluable for keeping the state of things consistent
yea I know, im just using that for some auxiliary events, like player hits a tree and I want the tree to just shake a little on clients
Did you simply just try it?
Or where does that question come from?
@thin stratus yea tried it right now, 'error BPimplementable cant be replicated'
same error with native, so I have to create seprate func and make my code dirty π
:D
I have to write down all these limitations so that I dont forget it 1 year later
π
π
Oh snap not good then I must have messed up before. The hell do I pass info without saving files to disk thenβ¦.
Only thing you can do in BPs is to ask the Client for the Data after joining
But, even in C++ you have to do that if it's more than the options string can handle
You just have better entry points for that in C++
So you mean to say that Iβd have to log in on main menu level then when moving to server level Iβd have to re log inβ¦ tbh Iβm sure thatβs what the options string is for atleast where iv seen it mentioned and used itβs like passing an api on connect to client. I get itβs not working though but I do see my options passed to the server. Either way I guess iv not a clue and not doing it the way anyone else would do it. Thanks for the help though. Ok have to go deep to find out how to persist from main menu to server in a reliable way. Without needing steam/epic
Hey I have a component I'm creating dynamically by class (using AddComponent) then later I'm trying to call a server RPC on it and I get a bunch of errors:
LogNetPackageMap: Warning: FNetGUIDCache::SupportsObject: RailgunComponent_C /Game/FirstPerson/Maps/UEDPIE_2_FirstPersonMap.FirstPersonMap:PersistentLevel.PlayerCharacter_C_0.RailgunComponent_C_0 NOT Supported.
LogNet: UNetDriver::TickDispatch: Very long time between ticks. DeltaTime: 50.28, Realtime: 50.31. IpNetDriver_18
LogNetTraffic: Error: ReadContentBlockHeader: Client attempted to create sub-object. Actor: PlayerCharacter_C_1
LogNet: Error: UActorChannel::ReadContentBlockPayload: ReadContentBlockHeader FAILED. Bunch.IsError() == TRUE. Closing connection. RepObj: NULL, Channel: 3
LogNet: Error: UActorChannel::ReceivedBunch: ReadContentBlockPayload FAILED. Bunch.IsError() == TRUE. Closing connection. RepObj: NULL, Channel: 3
Do I need to do something special after dynamically creating this object instance for it to be registered for replication or something? The impression I get is that the FNetGUIDCache::SupportsObject ... NOT Supported warning indicates that the server is not expecting this component to be sending network messages, is that correct?
The OptionsString is usually Server Options. E.g. when you have a ListenServer or when ServerTraveling.
Client Options are passed via the Login methods
Where PreLogin and Login give you access to them, and PostLogin does not
PostLogin being the only one of the three being exposed to BPs
I'm not sure this works in BPs tbh
In C++ you usually make sure you only call this on the Server
And you have to manually create the object and register it
And ensure its stably named
AddComponent, if that the BP node that then has the custom Component name in it, is usually only meant for ConstructionScript iirc
is client should also be build using sources when server is build ?
how do i go about disabling joining to a session without destroying it? there is a getsessionjoinability in agamesession but nothing seems to call it
at least thats what my ide says
sad :(
there's the even easier option to give up on online games :)
ahh thanks. id tried to find pre login but not found. been doing some reading and looking like i should be using savegame file to save some hash/jwt that can parsist into the server then call for player data based on that.
Keep in mind that those Login functions only vaguely have something to do with actual "Login"
It's not really an authentication thing
But yeah, I could imagine that you'd want to send the AccessToken via the Login Option String
Honestly, if you plan to do some funky stuff with backend etc. not using C++ is kinda bad
Like, BP Multiplayer is just too limited
what do I need to do to add coop support to Lyra (preferably without touching C++) ?
so when u say "pre login" you mean just something i did previous to throwing the "open level bp" i see. i thought it was actual bp logic i was to look for even with all other posts using same naming. cheers for the help. im on my way now using a game instance to "store" transient info. like the username set in main menu. then all i will need is a few other things to validate users on joining the server. this will do for my needs. im not making cod.
PreLogin is an actual function in the GameMode that does not exist in BPs
oooooooooooooooh
Same as Login and PostLogin
Where PostLogin is exposed to BPs
And PreLogin as well as Login have the parameter with the Options
That's why you would need C++ to use the Options string
The Client one that is
right and just intercept the url and send it out as a hook or do something with it.
il look into messing c++ side later i guess. if in i need to.
I'm having trouble finding reasonable resource requirements for a small VPS to test my dedicated server build. It looks like the Linux dedicated server binary is a few hundred MB, but what about system memory? Could I get by with 2GB to test a few players on my server? 
Just fire up a DigitalOcean instance for 10 bucks and try it out
2GB can be either way too little or waaaaaaaay too much, depending on what your game does.
How can i check if the player controller is 0 index player or not?
I want to check if this player is the first join player or not
Check if this player controller and player controller 0 are equal
Only valid on server of course
Everyone is 0 on their own machine
why this is not work well,,,always return true..
I can't read what language that is but you are probably proceeding before the results of the 0 player search are replicated
Is it ok to use actor's owner variable to store custom actor ? Or is it engine specific ?
This occurs instantly.
What are you trying to do?
owner is important
Should not be used then ? I have a owner logic and was wondering if i could use that
Owner can be anything but what are you trying to do here?
I have an actor that depend of a "owner", so i'm setting it but not sure if it's designed to do that
Sure you can do that. Owner is used a lot for replication though, just keep that in mind.
Keep it in line with the concept of ownership.
Cool, thanks !
how can i replicate the Web-browser and its audio in multiplayer? any ideas?
i guess here there is no more players left in the world so it cleans up and closes. would it be appropriate on level load putting in a ghost player so its constantly loaded? or is there a bool i can toggle to say never shut down
I don't understand why this is not working well...
I want to detect the player controller is the first player or not!
this code written in the pawn
You're not checking if it is locally controlled. So both owning and non-owning connections call this on the pawn
think of it like this, it's not being executed 2x like you think, but 4x, and twice of that is bad
2x assuming 2 players
Also delays never solve a problem, they just hide it
sometimes they do, rarely tho
glad you said that to them as it seems thats also my issu when i "open" level it was causing the server to also open the level. i can now travel between server and main menu level server does not die π
2 for 1, what a win
its probably a bodge thats going to kill me in about a week but hey ho
it works now .
I don't understand well π₯Ή can you give me some advice?
bare minimum for performant ue dedi server networking is custom NIC with DMA ethernet
trust me bro, jane st. told me so
your Begin Play chain is called for every pawn and you arent checking if the pawn currently executing it is locally controlled
that 'Which Computer' macro is this!
That's terrible. Just use locally controlled
wow..I didn't know that!! I always used this macro...thank you so much!!
Is it ok to pass in actor references to a function that might be rpc'ed ? What would the alternative be?
That depends on your goal. You cant pass it from the server to the client and expect to be changing the server's values from the client through the reference
I may want to destroy that actor (on server side, replicated to clients)
Otherwise as long as the same actor exists on the other side the reference is resolved properly to the local instance. If it doesn't exist it won't resolve
depending on if there's more left in the "stack" of it
Then you just destroy it on the server, and if it's properly setup to be replicated it gets destroyed on the clients too
Hmm alright, thanks
Guys how to correctly make HUD? I mean health etc because when I make it on event begin play I am getting errors on server side telling me
[2023.01.01-15.23.02:425][467]LogScript: Warning: Accessed None trying to read property Name
BPDFCplayer_C /Game/ThirdPerson/Maps/TestMap.TestMap:PersistentLevel.BPDFCplayer_C_2147482485
Function /Game/ThirdPerson/Blueprints/BPDFCplayer.BPDFCplayer_C:ExecuteUbergraph_BPDFCplayer:0D6C
HUDs dont exist on the server
Super simple design:
You have a health variable that replicates with OnRep.
Inside the OnRep you fire a delegate/event: OnHealthChanged.
Your spawned HUD class binds to that event, and when it fires it reads the new health value and changes the display.
Also don't try to spawn UI on the server.
Dedicated or listen server?
dedicated server + session on it
i got rid of those errors on clients sides by checking is valid
but it is not working for dedicated server
Yeah you probably tried to do HUD stuff serverside. Gate it by locally controlled or whatever.
because I am loading it and making references on begin play but how then if not on begin play?
on my pawn
where to run it
beginplay is propably called on server too
Yes, BeginPlay is executed everywhere
BeginPlay -> is locally controlled? -> Do thing
Show your code
give me min i am not on computer
here is one problem when I am setting name ( this is get from default scene root) and then this is second problem errors which will show also on server both sequences are connected to beginplay/ oh no first is connected to event tick
here are showed errors on server created by my widgets
You have been given the answer, you should not be doing anything with widgets server side, thus you need to "gate keep" your widget related functionality, using a branch with !IsServer and/or IsLocallyControlled
This is why I typically recommend using the HUD class for managing the creation of your widgets and (where possible) having the widgets themselves handle the relevant logic specific to them instead of the character, controller, or just anywhere/everywhere etc.
I.E a "health bar" widget will get the relevant health value from the owning character (GetOwningPlayerCharacter) etc, etc.
okay and can these widgets problems causing also kicking players out of session? I suddenly got problem when 2 join they are not together in they like both in different map
If a replicated property gets set on a spawned character on the same frame it spawns, how can I guarantee that clients will trigger the OnRep function? Currently it seems like a random chance that it will succeed
It's likely a race condition since the OnRep property maybe replicates before the character is fully replicated down itself or something?
Is simply delaying the setter of the OnRep property by say 0.5f the solution? (feels a bit incorrect / imprecise to do that)
Manually update on BeginPlay as well?
@grizzled stirrup I usually do:
void ASomeActor::BeginPlay()
{
Super::BeginPlay();
if (SomeCondition)
{
OnRep_SomeProperty();
}
}
void ASomeActor::OnRep_SomeProperty()
{
if (!ActorHasBegunPlay())
{
return;
}
}
Cause OnRep can call before BeginPlay
And that can cause issues
There are functions in UE that silently fail if they are called before BeginPlay
Don't ask me why and which
I just stuck to this pattern and had no issues
Also ensures OnRep is called properly for freshly spawned actors
Ah ok thanks! In this case a manager is initializing enemy stats when spawning and the client needs to get these stats to init other stuff so I will likely need to somehow move the manager logic into the enemy itself
Great snippet for similar things
I've had so many inconsistent OnRep issues likely tied to this problem
Yeah it adds a lot of extra code sadly
And "SomeCondition" is pretty vague
You can ignore that, but in some cases you know if the Variable is actually not default anymore
E.g. if you know the boolean is false by default, check if true could be the condition
Of if you know a pointer is null by default
But just calling it 100% of a time is also fine
In BP can't you just set the variable and it'll automagically call the onrep since it's not really an onrep?
Beginplay -> Set Variable? maybe it needs to change I'm not sure.
In BP you have the same problem
ooh ya true if the modification makes it before you do this you're back to defaults
Not sure if BP OnRep is always calling or only on change
But yeah I exposed ActorHasBegunPlay to BP for this reason
But it's also not like I remember doing this all the time
Would an RPC have the same problem btw?
(arriving before BeginPlay has been called on client)
Say you do
if (AMyCharacter* SpawnedCharacter = SpawnCharacter())
{
SpawnedCharacter->SomeInitMulticastRPC(SomeStruct);
}
In this case it's a one time payload so a reliable RPC in theory would also get the job done but perhaps it also would fail due to the same issue
If the servers tells an Actor to spawn at location 0,0,0 and then tells the actor to move over time via Add Actor World Offset but movement replication is off.
If there is lag, and client gets the call to spawn the object at some point in the future, where will the object spawn? At (0,0,0) the spawn transform or where the server currently has the object's location?
Probably 0,0,0
Why probably and not exactly?
If movement replication is off, then it will never get an additional transform update
do you use the gamestate HasBegunPlay func here? Seems the Actor one is a private enum and not a func
Actor should have one
I guess GetWorld()->HasBegunPlay() works
I don't see one for actor
A public getter that is
My results so far seem to indicate that the spawn transform is not happening where it should be on client but where it is on server after it has moved.
I'm wondering if I need to create a replicated Vector Location and have client correct the spawned object by moving it on its begin play to where the server should be putting it on intial spawn given that I don't want its movement replicated
IDK if this is a bug, intended or an oversight on my part
Is this in your guide? I donβt recall seeing/hearing about this before. Seems important? Pin?
Also just to be clear, the clients will 100% of the time have the correct value of this replicated property (Even if it replicates before BeginPlay), it's only the actual calling of the OnRep function itself that is inconsistent?
It's not, and I'm not sure I want to pin it cause I'm not entirely sure what I'm fixing with this
Oh think I found another bug that may be causing the issue
I just know I had issues with this on The Ascent
Spawning at random lol
Server needs to replicate that chance
that'll probably cause some discrepancies
UE5 dodges this one :p
oh wait
no
If server decides to spawn it, then that gets replicated
so that isn't it
So when faced with the situation where you need multiple replicated properties to be down before calling a function (say a replicated health component health value as well as an OnRep variable that gets set when a character is spawned), if it can happen a little later than spawn time (only affects cosmetic things on the client), is setting a timer to say 0.5f before calling the function ever a decent way to get around this?
I suppose the correct way to do it would be to check in the health component OnRep function if the other variable in the Character has replicated yet and vice versa (calling the function if the check succeeds) but it could get a bit messy if more vars are involved
I guess with ping and packet loss there's never any real way to guarantee that all of the vars have replicated yet but a fairly long delay feels like it would catch most cases without spaghettifying the OnRep funcs checking for other replicated property states
Another solution would be to make a custom struct (even if it's duplicating data) to hold this initial data that gets replicated once
Is your stuff failing or just looking goofy for a second?
I mean, do your onreps fail in some way without other data or just look dumb, like HP = 200 but MaxHP = 100 etc...
Well it was failing before the BeginPlay double check that you and Exi mentioned. Now it works but I realized that I can't guarantee that the HealthComponent health value will replicate down before this property replicates and I need them both at the same time
So the hacky 0.5f delay wouldn't change anything visually but just in 99.9% of cases make sure all values are there
doesn't it at least not divide by zero and crap the bed with the default values?
Nah the defaults are fine (even if goofy) it's more that I'd like to initialize the health bar once when the enemy has initialized itself and it requires a few different replicated vars to do so
But I suppose I could just do it in a few separate funcs
You could wrap all the required items into a struct, and replicate that, so you know it all arrives in one.
YEah it's likely the best option even if it duplicates data a bit
Just nice to have the guarantee
Then, could you do βinitial onlyβ rep, so that the struct comes once with the starting data. Then individual reps after that.
Iβve been toying with a βstarting payloadβ struct once idea myself.
Once the struct with all data comes, you initial your hud etc and set a bool, then your done.
No race conditions. Etc.
So made a test BP and interestingly enough, the Actor is set to replicate and rep movement, but the spawning isn't happening client side
Shouldn't a replicated actor, that is on both client and server be able to spawn other actors for clients if the server version of it is calling the spawns?
Depends if the thing it's spawning is replicated
A replicated actor spawning non replicated actors on the server won't see anything on the client
It is a replicated actor, spawning other replicated actors
Then yes it will spawn them on client too
An important skill to develop is figuring out why that is
Post a log on the client when that actor calls begin play
There are some rules regarding owning connections for replicated actors
It does work I was mistaken
I set it up so that it only starts when 3 variables are set on Rep so that I'm sure everything is synced up
but I forgot to override those vars when testing
It also randomly just stops working
not sure why yet
stops working as in, stops painting
now that I think about it, those on rep should get fired on client
IDK why they weren't
Does exposing a float to the Spawn Actor not call on Rep?
Or is it repped to begin with and then following changes after are replicated?
That does not get called
From this
It would seem
I guess it isn't the job of spawn actor to call On Rep for the initial replication
Which seems silly? If the goal is for Spawn Actor is to Replicate, then replicate all initial params if they are set to replicate right?
It's like I'll have to call an RPC after the spawn to init it and start it
rather than use that and begin play
I'll give that a shot but seems hacky
Think I got it pretty decently now
Probably need to do some latency testing now... to really see. Gulp
BP doesnt have a replication callback
Its a property changed callback masquerading as replication callback
So any time anything chsnges the property, from replication or not
OnRep fires in BP
using is locally controled helped me!
thanks
im trying to send a client to a specific map from the server(like for a kick functionality) but no matter what, the client is sent to the entry map
does anybody know where to look?
oh well i dont know why i was trying to play with AOnlineSession and AGameSession
ill go the easy way
anyone that know what can cause this will not work on client side ? this code is in a playerControler
Did you specify that player controller to be used in the game mode? π
like that ?
this is my spawn sequence
is there anything else to do ?
it seems that appear after the server travel
update : it appear when we connect to the server
Did you ever figure this out? I enabled the plugin but it doesn't seem to do anything during PIE.
i cant find what i did wrong meh
There's a multitude of potential problems: not spawning the actor on the server, input bindings not being setup properly, wrong input mode. You don't provide by far enough context for fruitful help
Wrong gamemode, even if the one you have it setup properly, etc... like the list goes on and on.
You're going to need to do a little more work on your end and provide better context, debug more. When does it work for you, when doesn't it work? List the differences, share more context
@jolly delta Have you looked at example projects to see how they spawn players. The ColabViewer template project has lots of networking code and exmpales. Lyra also probably good to look into. I also should probably take my own advice and look at Lyra.
that seems to solve the probem
but i am not sure if its a good behaviour to do that ?
Depends
are you switching input modes a lot? Maybe going from UI back to game?
Then that would be something you have to manage
Hide the mouse, show the mouse, ex. going to pause menu or not
If your game is a top down game where you use the mouse to click but also want to control the player maybe they set the Input mode outside of game by default?
Does that break mouse controls for you? More context helps as I have no idea what kind of game you are trying to make
or what your goals are
There is also a Set Input mode to game and UI as well
by adding that is seems that most of my control are work as intend, sometime there is a skip on the mouseclick but not everytime
There is also a GetPlayerController->Enable Input node
And a Disable Input
which would let you enable or disable input for certain actors
So a few things that can effect input based on where and when you want there to be input or not
this one should be used where ?
Enable Input to enable input on the actor which will have Input Events
Node says "pushes this actor on to the stack of input being handled by a player controller"
But this is more #blueprint related than MP related
like that or this is hell ?
can't i set on the controller after possesing event ?
The target should be whatever has the Input Events
Whatever actor has this for example
yeah i tried many thing only input mode work in my case i don't know why
is it only when i connect to the server
I don't know what hell looks like, but I'm sure this worse than it
The solution you figured should be good. I figured that a while ago and it seemed to be an engine bug iirc
generally speaking one place should manage input modes
You tell that manager when you want UI input enabled, it keeps track of a counter or some other way, so when all your UI-needing input is gone it switches back to game input
And then you just set it by default to be game ingame
@jolly delta I'm gonna grab some sleep now but that's somehting you want to eventually look into
especially as you add multiple UI-based features to the game
No I didn't but I just realized someone replied to me so it may help you #multiplayer message
Hey all, got SImpleMoveToActor working in multiplayer (Listen server). However, if I run it - let's say I'm moving Player A. On Player A's machine, their character doesn't animate - just slides to position. However, Player B sees Player A's character animate. This is using the stock TPS character
Also, RepNotify is NOT run on server, right? That's run on the clients after the RPC is finished on teh server?
So if I want RepNotify to trigger another RPC, I need to call another one?
RepNotify is from Server to Client only. Not reliable. (It will get there eventually tho) To call a server RPC you would need to then Use a RunOnServer RPC.
Variable replication is good for keeping states about your actor. Since a player joining wont receive RPCs sent before they are in the game.
I had a question about if its normal to write RPCs with this pattern or is it better to just use a single event. The whole naming thing seems odd to me ya know. Ive seen some programmers prefer this pattern, but I dont understand why.
Use that single event or use a private function to keep the graph clean.
I'm trying to set up input with enhanced input but I am not sure I understand. Where should I call AddMappingContext? And where should I set up the bindings?
!HasAuthority?
Call it on the player controller BeginPlay
I think it is not necessary but you can use IsLocalController() to make sure
Ah, yeah I'm doing it in the pawn (because of different controls for different pawns) so I'd need that. Thank you!
Try this (in pawn or character class)
Which events are triggered during and after seamless travel?
Onswapplayercontrollers are not triggering at my end. Please help.
i use onclientacknowledepossession, do you think receive restart is better suited?
there is a postseamlesstravel in the player controller
Is it exposed to BP's.
i dont think so
probably not, multiplayer is not really bp friendly unfortunatelly
That event is only triggered if the PC Class is different in the new GameMode iirc
Cause otherwise the original PC is kept and there is no need to move data over
If at all resetting data would be needed
To save actor references I use TSoftObjectPtr and load each and every actor with the same name, so they can get resolved when loading is completed.
But if I want a replicated actor reference, I need it to be a pointer and that can't be saved by SaveGame. So do I save it as a soft object ptr on the server and just resolve it and assign the pointer to the replicated variable on load?
How can I set and get stuff from server Game Instance?
I'm doing it in c++, but I have the same there and it works great, thank you π
why would you do that? use game state or something else
@lament garnet Game state will keep date on level change?
nope
either use seamless travel and implement playerstate::copyproperties
or save data to disk before travel
then restore
what are you trying to do?
I found this useful for this very topic: https://wizardcell.com/unreal/persistent-data/
Before reading that I just made sure the game instance on the server had the relevant data, and when loading a level and having authority I'd fetch whatever is in there that I need so it replicates to the clients.
@lament garnet I have some variables that I use in multiple blueprints that I want to store somewhere else because Game instance is not working on the server and also I have some data that I want to store so I can use it after level change
So the clients would of course have their own game instance, but they wouldn't use it. Only the server would.
@sacred kraken How can I tell the server to use it instead of client
@glass anvil HasAuthority(), or when using blueprints using the authority switch.
But I would just read the article I sent, it's a bit lengthy but it helps a lot.
@sacred kraken So when I cast to GI to set something or get something I will ask for has authority?
I will take a look on the article
I wouldn't read it until the basics are clear though, I found it confusing before I understood everything in this one https://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf
That question makes me think you should maybe first get into the basics
@sacred kraken Okay thanks a lot for the material
Only saying that because I didn't know that until 2 days ago myself
Can you access that function in the blueprint?
no you need to expose that π¬
This one reason and the other reason is that I think ReceiveRestart() happens before BeginPlay
i really have no idea when its the right time to bind inputs.. ive just assumed its when the client acknowledged possession so i went that way
so receivestart is better then
I am doing it in BeginPlay
I had it in SetupPlayerInputComponent first
But now I do the context adding in BeginPlay and the binding of actions in SetupPlayerInputComponent
Is that wrong?
Event called after a pawn has been restarted, usually by a possession change.
Oh I see. So it works for me because I use PlayerStart and you don't switch pawns
It depends β’οΈ
In player controller you can use AcknowledgePossession(class APawn* P)
But in a pawn or character class you have ReceiveRestart()
thats right, good to know
You where right, it is better to use AcknowledgePossession
yeah the method name was the key for me here π
If Pawn replicate option is checked, The input key also can be replicated to pawn1 of client 2?
No, you have use a server RPC
Client -> Server -> Multicast
and instead of using 3 different bool variables, use one enum
in this way?? before using the one enum...
Yes, Client -> Server -> Multicast
Oh,,thanks! why the boolean valuable can't be used in this way?
You can use it, but for storing rock, paper or scissor, using one enum with this 3 options is better
Aha,,I got it! Thanks~!!
How would this work if you don't know which mapping to add? Because in my case the pawns hold the mappings needed π€
parameter is pawn, cast it and get your mappings
Hi guys a simple question, when creating a function that runs on a server or with the properties UFUNCTION(Server, Reliable, WithValidate) , if the function have some parametres , do i put them in the implementation and validate functions too ?
Check this message β¬οΈ @sacred kraken
AcknowledgePossession() is better if you don't have custom mappings for different pawns and you want to handle everything in one place
Yes, for example β¬οΈ
void ServerAddWeapon(AWeaponPickupActor* NewWeapon);
bool ServerAddWeapon_Validate(AWeaponPickupActor* NewWeapon);
void ServerAddWeapon_Implementation(AWeaponPickupActor* NewWeapon);```
Also, you don't need to implement the _Validate and _Implementation in the header
they get generated by default in the .generated.h file I think
Hi, does anyone suddenly have weird replication issues since upgrading from 5.0 to 5.1?
Some things just started weirdly not working, and I cannot quite figure out why.
Everything working, I even used the push model and it is working with no problem.
Hey, did you figure this out?
Sorry, one last question. Do you happen to know how to bind ReceiveRestarted in c++? I can't find a lot of documentation on it
its a virtual method, you can override it
or there is probably a delegate, something like onreceivedrestart
There is a delegate. It's not available for override it seems, so I'll look into how to use delegates. Thanks π
You can override NotifyRestarted()
Just as I found out how to create a delegate π
ReceiveRestartedDelegate.AddDynamic(this, &APlayerPawn::OnRestarted); I found out I can follow the delegate to see what the signature should look like
(Which is void APlayerPawn::OnRestarted(APawn* Pawn))
No clue why it receives a pawn though. Is that because it can be bound to from non-pawns?
Looks like there are more functions that you can override
In Pawn.h line 372
go to declaration until you end up in engine.h
That's what I do, I think
Ctrl+click does that but I end up in the cpp
Ah, f10
To switch to header file, sorry. I am not stupid, just tired, I swear
By default this is called on the server for all pawns and the owning client for player pawns.
Wouldn't I still need to check if I'm the owning client?
Because the server doesn't need the mapping, does it?
Oh, that's what the IsLocallyControlled is for
See, I'll get there. Eventually.
For IsLocallyControlled() to return a correct result you need a valid controller, So make sure to call it at the right place.
So just to triple check:
void APlayerPawn::NotifyRestarted()
{
PlayerController = Cast<ARockPaperPushPlayerController>(GetController());
if (!PlayerController->IsLocalController()) return;
check(InputMapping);
UEnhancedInputLocalPlayerSubsystem* InputSystem = PlayerController->GetLocalPlayer()->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>();
InputSystem->ClearAllMappings();
InputSystem->AddMappingContext(InputMapping, 0);
}
Oh, I didn't know there was a IsLocallyControlled, that seems much better
Isn't NotifyRestarted the right place then?
Don't forget to call the Super
Super::NotifyRestarted();
Ah, yes! I stripped that out to not show too much useless cod
I think it is the right place, but you need to check IsLocallyControlled()
is it possible to replicate actor with custom serialization? i remember you could make custom serialization for simple data types but I can't remember if you can actually do something like FArchive& Arr << MyActor
I meant you said:
For IsLocallyControlled() to return a correct result you need a valid controller, So make sure to call it at the right place.
So I wasn't sure what you meant by the "right place"
Not really, but there's not really much utility in doing so - it's the properties that are serialized
After the pawn is possessed by the controller, but test the current solution, let's hope it will work.
I did not - from what I gathered it's a bug in 5.1
yeah I meant can I replicate an actor UPROPERTY with WithNetSerialize via the FArchive
No, for that you need the package map
Then you do Map->SerializeObject
But FNetBitWriter should already handle that
So as long as you are inside a NetSerialize function, you should be able to do Ar << ObjectRef; just fine
It has a horrific operator overload that will do it
See FHitResult for an example
thx
My issue was that one of my parent BPs had a bunch of it's replication variables (like 'Replicates') reset.
It looks like SetupPlayerInputComponent gets called first. In fact, SetupPlayerInputComponent appears to be called upon possession
So I guess I could put all my mapping/binding logic in there
Huh, even better
It doesn't seem to be called on the server at all
So I don't really need the local player check.
Update: Double checked with a standalone server and nope, SetupPlayerInputComponent doesn't even get called. That's super good to know
What's the difference between bReplicates vs SetReplicates? As far as I know both work, but SetReplicates seems to be doing a lot more.
In fact:
UE_LOG(LogActor, Warning, TEXT("SetReplicates called on non-initialized actor %s. Directly setting bReplicates is the correct procedure for pre-init actors."), *GetName());
Weird that I can't do the same with replicating movement
In the constructor you should call bReplicates = true
It's a fix for actors which have not been fully initialized or even constructed being added to the replication system with the wrong properties.
For some reason, Epic "fixed" it by logging an obscure error rather than throwing an asset and/or preventing it from being possible at all
Oh, no I'm not running into this issue. I am just curious why it's inconsistent. I can use a property to enable replication, but need to call a method for the movement replication
It's inconsistent because their "fix" is terrible π
At runtime you would call SetReplicates
What should be the way to do it then?
But in constructor etc. you would need to set bReplicates directly
BeginPlay instead?
That's just silly.
Yeah it's really really not good
Epic - "Let's have 2 different ways to do this"
I've only ever seen the boolean way of doing things in all courses and tutorials I've followed lol
I still don't know what the "proper" place to put it is
Constructor:
bReplicates = true;
Anywhere Else:
SetReplicates(true);
Also - welcome back from vacation James π
Has it been quiet here π
But you made it sound like the constructor is a bad place to put it, or did I misunderstand?
Not really. Just noticed you were gone for awhile. Could only assume vacation, lol.
No it's fine, it's just that calling SetReplicates from there breaks things in unexpected ways
Aaaah
Setting the bool is fine
Phew, okay π
Cedric did a nice explanation of some CMC stuff a few days ago.
It actually may only be broken when using replication graph, as that's where I first reported the issue - but better to be safe than sorry
I just wish they'd fixed it in a way that made any sense
I wouldn't find it weird if I could set the movement replication field in the constructor, too.
Then it'd feel consistent for me, a pleb
Yeah that's really the issue, both should be behind Set## functions and the engine should handle the case with uninitialized actors a better way
Or do what Actor Components do, and have a SetIsReplicatedByDefault function for init time, and SetReplicates for runtime
UE is anything but consistent at times π
Another question I have is about binding inputs. I just moved the callback for a Move action to be UFUNCTION(Server, Reliable). It's being called in the _Implementation, but the input is empty. Am I supposed to proxy that input myself? So have a handler that calls another server method with the inputs it actually needs? This would make sense to me, but I want to make sure I understand
Without seeing code I couldn't say, but yeah typically if you have to send input to the server - you "accumulate" all input into a struct, and send that to the server in one place at the appropriate time
Generally you want to avoid calling RPC's directly from input functions, because they will fire at the tickrate of the client, which might be way too high
You usually limit/fix it to something more sensible
And also usually send it unreliably
CMC does exactly this, batching moves together up to a maximum delta time to reduce the amount of info being sent, but at the cost of slightly more latency
I don't know what cmc is
But also to ensure that clients running at 500 FPS don't hammer the server
Character Movement Component
Ah
Basically the only fully featured network movement in the engine
January is the month of the InstancedStruct blog post from Jambax. I can feel it in my bones π
Oh, is that the replicates time you can set when using blueprints?
oooof we'll see π
Or does that happen automatically when unreliable
an no, rep frequency is unrelated to server RPC's
All RPC's with exception of unreliable multicasts IIRC will send at whatever rate you call them
rep frequency is just for server comparing properties
Once you get the hang of it, you'll be like, "Ohhh - it totally makes sense". But then you want to get better and you want to learn how to do the more advanced stuff and you curse the Gods on why anyone would ever want networking in their game.
π
Well I wanted to make a single player game, but my wife requested me to build something we can play together
So now I have to
Yup - checks out.
AActor::SetReplicatingMovement just marks the transform fields as replicated then?
And any actual changes to the location I should only perform when HasAuthority()
Generally speaking yeah
Is Client in UFUNCTION the same as owning client?
Since having nothing there should mean client
Hi, i need a few infos about reliable/unreliable RPC (actually i have all of them as Reliable and yeah that's not a good way ikr that's why im here), does Unreliable RPC can be dropped and like never be called ? Actually a lot of my RPC are called after client predicting smth (so i want it's RPC to be reliable since i can't predict if it has been dropped)
So yeah idk about that
Typical example, ActivateSlot predicts the client stuff and then call the server rpc that will do kinda the same stuff but for the server
I don't know if this should be Unreliable or Reliable, client did it's stuff, server stuff should also happen, if this rpc is dropped client will just be not synced to server slot
Probably reliable
unreliable is when you can afford the RPC to be dropped and/or can recover from that
Or it doesn't matter ,etc.
Unreliable = play on fire vfx
Reliable = pick up key item
that's what i thought, thx
Thanks.
so what are people using now that steam sessions isn't updated to 5.1?
Hey there!
I have these AIs in a multiplayer, co-op game. I'm talking about 30-50 AIs simultaneously.
I'm thinking to, instead of destroying the AI when it dies and SpawnActorFromClass when it respawns, make it "despawn" instead; which means, disabling collisions, visibility, etc, and when it's time to respawn it, just make it pristine again as if nothing has happened.
All of this through C++.
Question: does anyone have evidence this approach is smoother (network and cpu-wise) than DestroyActor/SpawnActorFromClass?
Has anyone gotten this breakpoint when starting their project in DebugMode?
That's object pooling and a widely used strategy
Well, yes. However I wasn't so sure when it comes to multiplayer, and my rationale is b/c some attributes of my AIs are replicated, such as movement speed. Making the AI pristine means resetting this movement speed attribute, which replicates. So I was wondering if it wouldn't end up being the same as SpawnActorFromClass.
I mean, I'm pretty confident it wouldn't be exactly the same as SpawnActorFromClass b/c there are more involved than some replicated attributes, but nonetheless I'm just trying to validate whether this would give me, to say the least, an expressive performance impact.
This is the callstack:
Why is my level instance not loading at the location I specify??π€¨
Whats the purpose of using 2 functions anyhow? Couldnt you suffice with ServerActivateSlot and check authority? Im curious as to your choice (im learning)
Why would you check authority in a server rpc ?
ActivateSlot is called from input press, so on the client, client runs the activation logic on its own (to predict ui as you donβt want to wait server for that) and then it call the server one ther will do the same but for slot changes logic (unequipping current item and equipping new item)
And as the client one is called in an input, the rpc is called in the tick at a certain frequency so player donβt spam rpc by spamming input
Input -> Activate slot on client (ui + applying PendingActivationSlot for tick) -> tick detects that there is a pending slot, checking for last time it has been activated, if good call rpc
When a owning client/autonomous proxy pawn calls a Server RPC that changes the location, and both replication and movement replication are turned on... Does the server not replicate movement back to the client that called the rpc?
EOS
It is. SpawnActor is very far from free, and it's even more costly when it's an AI controlled character, rather than just a basic actor. Ofc it's going to be better networkwise
However much better that it's worth it for you, you need to profile
Right, I did find steam sessions are working though
As with every performance decision - first identify that you have a performance problem, then profile if your solution is comparably better given the change you are making
I may implement EOS too
My answer remains the same. EOS lets you work on all platforms without being shoehorned into Steam
You absolutely can use Steam sessions, but I don't see the rationale when a free solution is available on all platforms
yeah if you're earning less than 30k
EOS lets you work on all platforms
Is this true? I thought oculus didn't allow it
It also works better than steam sessions for debugging when you are working alone, because you don't need multiple pc/router setups that you do when using steam sessions
but I'll check it out later
just using what I'm familiar with at the moment, I don't have the time to learn a new system
Sure thing
What? Are you talking about using Redpoint's Steam?
Because of the copious amounts of free Steam solutions π
If you're a developer earning less than $30k USD/yr, a Free edition is available. Check the website to see if the Free edition is right for you. If you need blueprint support, check out Online Subsystem Blueprints.
Yeah, that's Redpoint's Steam implementation. I just use the Advanced Sessions stuff that like...everyone that gets started uses. Haven't ran into any issues yet.
Yeah I've used steam sessions in the past and I know it works to test replication that's all I need right now
it's a shitty little 3 day old project to test how fun it is
I'm sorry, I know I am not part of this conversation but I thought that you'd pretty much have to use all of them (EOS, steamworks etc) depending on where you publish, if you want your players to have a nice experience.
Is this not the case?
I remember reading oculus doesn't even allow your game if it includes steam (trying to find where I read that now)
I'm not sure, I've only make personal projects
Hmm okay
What's up with AActor::GetLifetimeReplicatedProps(), my IDE doesn't seem to think it exists. When I try to find it all I can see is:
GENERATE_MEMBER_FUNCTION_CHECK(GetLifetimeReplicatedProps, void, const, TArray<FLifetimeProperty>&)
This sounds like it's not a thing to override (like BeginPlay or SetupPlayerInputComponent) but a member function to define which will then magically get picked up
You need to implement that function on any actor that has replication.
I found that part, I'm just confused why it doesn't seem to exist
Have you checked what that macro does?
I'm trying to, but I'm not sure if I know how yet.
Same as trying to figure out what this does:
#define DOREPLIFETIME(c,v) DOREPLIFETIME_WITH_PARAMS(c,v,FDoRepLifetimeParams())
right click -> go to definition, or just search for it.
That's the second time today someone said that :p
I am doing that
The problem is this:
aka, I'm not good enough at c++ to figure out what this is doing yet
That's just a check to see if the function exists. It doens't do anything else.
Maybe it's just rider being goofy then
If you have a variable marked as Replicated or similar, it will declare the function in the generated header I guess.
For the DOREPLIFETIME macro you need to include UnrealNetwork in your cpp
I didn't know that. So I don't have to specify it in my header at all then? I should figure out how to view the generated header
Rider found "Net/UnrealNetwork.h" for me, I meant that I didn't understand how to read the macro code to figure out what it does. But I think the first argument is the class, and the second the property.
Found it
Unless you don't have a variable marked as replicated
And yes, the first is the Class, teh second the property
Sorry, I mean I found the header, but it doesn't have GetLifetimeReplicatedProps in it
And you have a variable with UPROPERTY(Replicated) in your header?
Well just add the implementation, UnrealNetwork and the DOREPLIFETIME and it should compile
It does, yeah
I couldn't find GetLifetimeReplicatedProps in the generated header because I had to do a build first. Bit chicken and egg
Completely unrelated, DrawDebugString is dope. I've been making widgets to print values for 18 months.
PrintString isn't enough?
Not with 30 objects I think
Unless it does also follow the objects
Then I now learned even more today
No it's Log and Top Left Screen
Ah like blueprints
If you need it to be on the screen, then yeah
But it's still only debug after all
Not meant for anything else of course
Yeah.
It's useful for stuff like this
Printing stuff about the objects, especially when doing multiplayer. Or when you have a lot of AI and need a quick way to see their mode
Yus
So I made something to throttle RPCs from my action binding because earlier someone mentioned that I might clog up networking otherwise. But now I have a question:
Is there something built-in I can use to throttle RPC invokations?
It seems like the sort of thing that can be made generic
Before you make assumptions about performance you need to verify, how are you determining that your RPCs are a performance issue?
Generally speaking RPCs should be used sparingly, and never to a point where they would be a performance issue
If you are using RPCs to the point where you are, that's a design flaw in your implementation, not a problem with the RPCs
very broadly speaking
For example if you are updating your actors position OnTick through an RPC ... the problem is what you are doing, not what you are using to do it (RPCs). Whilst what you are using is also a problem, the real solution is to dig deeper. I hope that makes sense.
What is best practise when I want add for example replicated Base for planes letΒ΄s say and they will have own health when it will be destroyed it will dissappear for start I just want use 2 big cubes one red one blue, should I use actor or pawn?
for this purpose
thanks for tips
Eh - updating position on tick through an unreliable rpc is fine in a vast majority of cases.
I'm pretty sure that's how the engine does it internally as well. Haven't ever confirmed that though.
hey, i need to set a camera to on the top of the right player on client side, but it seems that there is probleme with i. To do that i send an event on client after a onposses (on server)
The engine uses the replication system, which is not the same as RPCs, as it lets it optimize the delta to send
I wouldn't jump to unreliable multicasts being performance heavy (they aren't), but yeah it's wasted effort when you only care about the latest value of something.
That said, if the choice is between unreliable multicasts and normal non-push-model replication then it might be a tossup if there's lots of these actors in the world. Though the solution to that is to use push model.
Among other things, there's a vast amount of optimizations that have been built into the replication system for variables that isn't available to RPCs.
It's mostly about patterns in programming. If you get used to just doing everything through RPCs, that's what you end up doing because you know it works.
Rather than using a specific pattern or tool to solve a specific problem
Correct π
And even better if you don't network the things you don't need to network π§
anyone tip with this ?
Well is a player or AI going to control the plane?
planes are players (me) base will be just letΒ΄s say big cube in the air and we will attack on to it
when it will be destroyed team who lost base will lose match
Hello π
What's the best way to connect to a Dedicated Server without using Online-subsystem steam, epic???
at the moment i use the Console command "Open" and it works fine, but idk if this is the correct way.
Thank You π
it is correct I dont know any other
π
if u are not using sessions
I just dont know how I can set this base is for team red and this is for team blue and then when one of them will be destroyed how to know or say which team lost
tips?
PlayerCharacter, PlayerController. Those are the base classes you want
What you are doing is a direct connection, that's fine early on. Later on I recommend EOS
okay i will use character, for plane(player (me)) I am using pawn because its easy to fly with it
i do not need to open other port thqn the server port right ?
@verbal tendon Is it bad to make a direct connection? Would a connection over EOS really be better? What's the difference?
Easier to manage, no need to change later when you will inevitably need to. Just set things up right from the beginning
is anyone has an idea how to fix that ? Warning: ServerMove: TimeStamp expired: 134.055450, CurrentTimeStamp: 135.090897, Character: BP_TopDownCharacter_C_2
Are chaos vehicles stable in multiplayer? Or do I have to make them kinematic ? (if they rely on physics, haven't checked)
Hello, any idea why the servertravel command doesnt work in packaged game? It says command not recognized in console. Even lan connection seems to not working, even when its working in standalone :/
i have question about dedicated servers so i know i can connect to dedicated servers using "ExecuteCommand |open [ip]|" but what if it fails to find it ? there is a way to handle it ?
Hello!
I bought the following asset: https://www.unrealengine.com/marketplace/en-US/product/pro-hud-pack-v2-navigation-tools
The way this works, is that it takes an actor to set the waypoint marker on your screen, so in my C++ I spawn a temporary actor at the end of my LineTraceSingleByChannel
I only allow one to spawn at a time, so far everything works locally.
I'm trying to figure out a way where I can share my ping markers with other players.
Trying to wrap my head around how I should approach this, I was thinking to create temporary actors for as many players in a team ( 6 for example ).
Not sure yet how I would assign markers for each players in a team yet ...
I would then replicate all those temporary actors to all clients somehow and then force a sync to the hud to display updated markers.
Does this sound about right?
Hi, if i have an actor that's is owned not controlled by a player, what's the way to check from this actor if it belongs to the local player ?
get owner == get player controller(0) ?
I'm using the playerstate as owner
But i think i will just get the player controller from it yep
and also probably u will need use "is local"
IsLocal on what ?
player controller
Mhh why ?
try it π
trail end error is a 20% of programming 
GetNetConnection
Comparing net connection of the player and the actor ?
No, just checking it's not null
Mhh, that's not enough to know if that's the owner π€
Anw it's working comparing with the local PC
It is. It is basically what the engine does to detect if the actor can fire a server/client RPC
Maybe it's because i don't have set up NetRole yet
Nah, has nothing to do with Roles. But I would have debugged the function and saw what is really happening
But if the other method works for you then it works
Doesn't have to be a direct owner
But has to be at some point
Otherwise the actor isn't owned by the client
I just don't understand how it could work, since the connection will be valid on the server
(In a listen-server context)
So you have to check the listen-server PC
return GetNetConnection() == GetWorld()->GetFirstPlayerController()->GetNetConnection();
This work
I'm not sure I follow, and the syntax is weird, you don't do that
Literally
Connection = Actor->GetNetConnection();
if (Connection)
This way you only get true on the autonomous proxy
No matter where you call it, it will tell you if the actor is owned by the client
If client-side then the current client
If server-side then w/e client
I don't have autonomous proxies yet, that what i was saying :p I missed something to give the autonomous role, still searching
I'm not implying you have to use any Roles, as they are set for you most of the time (you almost never explicitly set them)
What I'm implying though, is if you look at the the one line implementation of that function you should realize that it works
You just didn't debug it enough to realize what's going wrong
Because of the language barrier I could be understanding you wrong too
Maybe :p
What's causing this?
Inside of GameModeBase I noticed that Event Handle Starting New Player, happens before Event Begin Play. This is problematic for me because I'm setting up references inside of Event Begin Play that the starting new player needs to know about. What should I do?
Seems you have multiple session interfaces
yea
The player joins and is assigned to a team using their Player State, but that reference hasn't been setup yet because Event BeginPlay (where I'm setting it up) happens after.
Why you don't do your logic before beginplay ?
I mean GameState reference not player state reference
Hmm. I wonder why I'd have multiple
Dunno, but a IsUnique ensure is triggered :p
InitGameState is where GameState is initialized, you could take advantage of that
Also called before BeginPlay is called on GameMode
omg know what hahah this blueprint code was like one of the first ones I ever made and is riddled with beginner errors
I figured out what was wrong
I just casted to the game state because the reference is going to be setup in the next few frames anyways.
You shouldn't replicate it because only the client that a controller represents should have it replicated. An AI controller doesn't have an associated client, so it shouldn't be replicated.
Why are you trying to replicate an AIController?
SetRemoteRoleForBackwardsCompat
It's backward for what ? Was it added since Iris ?
Is it best to use arrays for something like a possessable/respawnable flying drone like rainbow 6 style? I have an issue where the host possesses the clients drone if the client's drone is destroyed and respawned. I've tried just setting a reference to the drone but the host steals it if the variable gets updated by a client(it gets set on drone spawn).
Show your code, that sounds goofy
Sounds like you're spawning stuff on the client.
And potentially running server-oriented code on the client
I'm spawning on the server and setting every reference on the server, maybe that's why?
this is in the soldier character
i can repossess my soldiers fine from the drone with no problem
if i spawn a drone on client>server>client, the server takes the 2nd clients drone if the server spawned one already
Why use a bool and not just a DroneActor reference an IsValid checks
Yea i tried using isvalid (controlleddrone) but it didnt seem to work
You want spawning and possession to be separate right?
yeah basically it should spawn 1 and then be able to possess and repossess
In Character:
SpawnDroneButton -> ServerSpawnDrone
ServerSpawnDrone -> Spawn the drone -> set MyDrone -> set MyDrone.MyCharacter
N -> ServerTryPossessDrone
ServerTryPossessDrone -> if Mydrone is valid -> possess MyDrone
In Drone:
LeaveDroneButton -> ServerTryPossessMyOldBody
ServerTryPossessMyOldBody -> if MyCharacter is valid -> possess MyCharacter
Although I'd rather keep the refs in the PlayerController but that's whatever
i wonder if set MyDrone.MyCharacter is where im going wrong
even if its unpossessed?
i had to set ownership for UI stuff because im doing some weird workaround for the scoreboard while possessing a drone
its like they all share the "mydrone" variable
I think I got it working now. Thank you
Is an actor that's spawned clientside considered to have authority if you're checking from clientside code?
I've got a custom anim notify happening from a clientside spawned actor. The Notify function is returning true though when I check HasAuthority on the mesh component that owns it. Doesn't make sense to me that a fully client spawned actor would run anim Notify events server side.
yes
has authority != is the server
Authority means you have authoritative ownership over the actor - you have the last say in everything about it. An actor spawned on a client will be authoritative for that client because it literally doesn't exist anywhere else.
Ty, gonna try GetNetMode instead to solve this then
is custom transport the only way to get good perf out of ue net driver?
hello, this same issue i am facing .. any solution you got for this ?
sequence bReplicatePlayback server to client success
but client to server not work
Any Idea?
are you logging in using the EOS_DevAuth exe with two different accounts?
And does it only not work with dedicated servers or also doesn't work with two packaged games that are clients?
Use RPC when a client needs to change something on the server.
UDefaultLevelSequenceInstanceData is used to bind game characters and sequence character positions.
The sequence just moves the character and keeps state the position.
keep state works fine on the server, but not on the client.
I want the position to be copied on the client as well, but the position within the sequence is not copied.
Have you developed for multiplayer with other areas of your game? Or with other games?
If not I recommend having a look at the pinned messages on this channel.
Is it fine to set a replicated field's value on the clients? I know it won't just replicate up, but my thinking is that the server will correct it if it turns out it was wrong. This way I can optimistically render changes so it feels snappier. On a scale from 1 to 5, how wrong am I?
I do that too. Your thinking is correct, it does get corrected by the server IF the server disagrees. But if you set the variable client side and also change it to the same value on the server it wonβt have anything to disagree about. The trick now is to be careful when you use that because if itβs something like health or stamina you have to see what happens if a cheater were to try and change that value client side every frame. 1 not wrong.
Yeah but, go ahead and change health client side, it will keep getting corrected anyway won't it? This is stuff like stepping on your own grenade
Other damage is sent to you from the server I suppose
If the server says you died it doesn't matter that you pretend to have full health I guess π
Yea apply damage is server side by default and seeing your own cheater health on the hud as full is not doing any harm.
But for something like stamina check before a dash can occur is kind of tricky because the check to see if you can dash should happen server side to prevent cheating but that introduces input delay.
So I check stamina client side, do the dash if they can then check server side if they have enough energy to dash and also dash on the server. But now if a cheater tries to always have full stamina it creates a problem so I ended up counting a delay between dashes and teleporting back to last update location and setting velocity to 0 if they are dashing at an impossible rate.
hello, when i create session with p2p policy , join session happens without any problem. I cannot join only for dedicated server session.
it's the same thing i am facing which @real ridge faced ..
what's your error
because I had to set udp TCP port forward to 7777 sometimes 7778 too
then I had to get from my provider public ip
join is success but connection getting timed out and re-directing to base map .. i tried with switching off firewalls but same problem
okay are Ur up public?
first step
if no u will get timeout
u need ask provider to give u public ip
i had to also
if this is set, can i test in same pc ? server and client connection
no u need 2 machines one where is server running second where is client
if u are on same machine u Can test only via open local ip
oh, so this is the issue because we are running from our side.. if we put this build in dedicated server, we don't have to those steps said above ? like getting public ip
like in aws
U need public ip anyway for network where is dedicated server running let's say at your home u have laptop and desktop u will run server on desktop and Ur network need public ip, i have no experiences with running this server on Aws so i cant tell you we test only on our networks π
oh , thanks for clarification and do both builds ( dedicated server, client ) require different defaultengine config files ?
artifacts i have setup and i properly edit corresponding artifact between server and client before taking build ..
no same but u need different Eos settings i mean those codes from Dev portal π I don't have screenshot here but it is called artifacts
when u are packaging client use client artifact as default
when server use server artifacts as default
for server , trusted server policy i have kept and for client, custom policy with ticking almost all options ..
I personally have 2 artifacts just changing name of default on the top
yes
yes, thank you so much for clarification
hmm maybe if u will wait 5min I can make screen how my settings are if u want
project settings of subsytem ? and also, are there any next steps to be taken care of ? to test at home
one thing is cleared, to use same config files for both server and client
only public ip and set router properly
yes engine.ini config is same
ok got it .. thanks
starts with this are hard I had many problems for example now I cannot join on server on Windows 11 even ports are set properly and everything
