#multiplayer
1 messages ยท Page 480 of 1
I know yeah. And I'm going to post it in a second (4.22)
80 MB
ignore the name of the project lol
is anyone familiar with the multiplayer shootout example proj from epic?
i have a basic question, im curious how the clients are automatically connected to each other when using PIE with two clients. i guess my confusion is that wouldn't the clients have needed to first start @ a main menu widget and host or join a server? im looking for the logic epic used to autoconnect two clients but all i see is the usual logic for hosting/joining a session using widgets
does that only work in PIE, does anyone know? or is that something shippable?
btw @thin stratus in case you dl the project I was doing this while we were speaking but It didn't save
@strong knot This isn't specific to the shootout example. You can do this with every project in PIE. I don't think they implemented custom logic for the shootout example
@pallid mesa ill try debugging on my end, but this was the bool I was telling you about
The Advanced Play Settings of UE4 have a "AutoConnect" setting
That is on by default
@strong knot
wooow i thought i was going crazy for a minute
If you are testing 2 player starting from MainMenu, you would even want to turn this off
Cause in the MainMenu they shouldn't be connected
@high current right, but since it's movement none and then reseted to walking I doubted it would be necesary
@strong knot You can connect to an IP when starting a standalone game. That would result in the same thing.
rofl
hahahha
well thank you for downloading tho, I'm breaking my neck trying to see what is wrong there
thanks @pastel totem and @thin stratus !!
@pallid mesa I'll look at it over the next minutes/hours
Have to work on Hoverloop in the meantime
Will fill the compile time with it
okay, good luck in hoverloop, I'm going to try your suggestion of totally disabling the cmc (didn't work)
while traveling
which makes sense in a way
also thank you so much y'all for all the input you are giving
@pallid mesa initial attachment is replicated tho
when i attach a weapon to my character, i do it owning client and server, but other clients see it attached fine
@meager spade Is your weapon using replicated movement?
hello i have a quick question, is there any way you can get the steam server port the server is running on? i know you can get the ue4 game port, but i don't see an easy way to get the steam server port. any help?
guys for im implementing count down timer for my multiplayer game which i use cpp. cuz this is my first time working arount multiplayer i dont have a clear perception.
so here is what im gonna do if u have better idea plz share it.
im implementing the timer count down in Game State and send the Current time to a local class like Game Mode and with that i will be able to show the time on screen using Blueprint widgets
GameMode doesn't exist on Clients
You can just get a replicated or simulated timer variable from the GameState in your Widget
GameState is already the replicated class to share the start of the game
@brittle karma
@thin stratus i tried that way but i failed casting Game state in BP, u said something about filling GameState Variable i didnt quite get that
You are accessing some "MyGameState" variable
Which is never filled
Only because you set the type of the varaible doesn't mean there is something saved in it
These variables are pointers, which point to literally nothing by default
You gotta learn that otherwise C++/Blueprints is gonna be a shitshow for you
Instead of using your MyGameState varaible
just do "GetGameState"
And cast that
Also don't create the UI in the GameState. Create it in the PlayerController locally (isLocalPlayerController with a branch on begin play)
Guys i have one little question. If i have a variable in the player state which is set to rep notify, and then the server modifies the value of that variable, is it the same to call a multicast event on the server pawn instance of that player state as calling a simple custom event in the pawn i get in the OnRep function of that variable?
@thin stratus aha thanks
If you call it and someone hasn't joined yet or is far away from the player, it will not call.
At least if the Actor isn't marked as Always relevant
RepNotify on the other hand will also call if players join late or come into relevancy
As the variable gets replicated then
So its better to use the OnRep
If you need to replicate some sort of state, yeah
The thing is that it doesnt work as intended
I just have a widget component in my characters that displays the player name. So in the player state i created the PlayerName variable. Then when the OnRep_PlayerName is called, what should i do to update the widget to display the new name in the other clients?
I mean, the other clients can see the new name of the player
That's a simple race. Your PlayerState and your Character don't exist at the same point.
So you'd want to do it basically twice
Once from PlayerState OnRep to Character
And once in the Character grabbing it from the PlayerState
Not on BeginPlay though, as that's not valid
PlayerState is only valid once the Character is possessed
And then also only if replicated to client
Which is why I always advice you all to learn C++ for Multiplayer games, cause UE4 lacks tons of functions in BP
C++ has a simple OnRep_PlayerState in pawns/characters
Perfect place to grab it
I dont understand what you wanted to say here "And once in the character grabbing it from the PlayerState"
Why would it update the name in the pawn version of other clients?
@thin stratus as u said i used GetGameState and cast faild again. is it becuz GetGameState returns Game State Base and my Cpp class is just Game State?
You need to set your custom GameState class in the GameMode
Otherwise it's not used
@gleaming vector for your GC stuff, you can add those UObjects to root set
@thin stratus that did the trick, thanks
and then just manage manually from the struct destructor
@thin stratus And why the multicast from server player state worked for what i want to do?
@pallid mesa Think I fixed it
@thin stratus Sorry for asking too much dude, i think i uderstood what you wanted to say. You mean that i can grab the player state variable value binding it to the widget text?
How you do it in the end doesn't matter, but Character and PlayerState aren't valid at the same time.
That was the point, so the thing is that i dont know how to call a function in the Character when the variable in the player state has been replicated
there are some errors that says Accessed None Trying to read property CallFunc_Create_ReturnValue. what does it mean?
everything works fine . i implemented a Count Down timer and it works fine(error happed after implementing the timer) both for server and client and everything seems to be fine when playing. so what is this error ? BP Runtime error? fyi. the fps rate goes way down after 20 seconds
i found a video that explains what this error means
https://www.youtube.com/watch?v=7uDQnQty0-4
In this series of videos I show you how to fix some of the more common errors found when developing games in UE4. If you have an error that you want explaine...
AccessedNone is a C++ based error
It's just not very well explained for Programming Beginners in Blueprints
Peeps expect every variable to have some sort of value.
You make an interger, it has a 0 as default.
A bool is false.
A Vector is 0,0,0 etc.
But the "Reference" variables, which you use for Objects and Actors (and everything derived from that) are empty by default
They are called "Pointers" in c++ and are pointing to "null" or "nothing"
If you access them while they do that you get an accessedNone error
You always need to get an instance of an actor that you can save into them first
You can imagine them as a box with a label. E.g. Character.
You can save Character and all Child Classes into that.
Ways to get these instances are: Overlaps, LineTraces, using the ReturnValue when spawning/creating something (SpawnActor/CreateWidget)
Or static accessors, like GetGameState
So you could make a variable of type "MyGameState"
Which only allows MyGameState instances to be saved into
And then do "GetGameState->CastToMyGameState" and save the result into it
That's all I can tell you :P it's hard to explain pointers in a few sentences
That's okay, (disregarding the performance drain of casting every frame)
@thin stratus first thanks for information, i am programmer i know those things (: i have implemented timers before for single player game
but one thing
when i play the game it prints "Hello"(Cast failed node) two times on screen
so why is that happening? im wondering becuz both server and client runs the way i excpect
Who prints it, Server or Client?
client
Also :D i am programmer i know those things Right, but you asked what the error means, so that's kinda half true then.
but server should do it right?
If the Client does that then it's a simple Replication Delay.
Multiplayer is not Instance
Server spawns the GameState
That takes a bit to get to the Client
So the first few frames the GameState is invalid
alright then, but as u explained the reason for Access none is that there is a Variable with default value in blueprint . as i sent the screen shot,
there is not any variable i used Get Game State, but the error says there should be some null value. and it refers to the Player controller Bp class which adds the widget to the view port
@pallid mesa you there?
yes, I'm around, still with the issue hehe
i solved the Access none problem by changing the playercontroller like this(if anyone wonders)
He uploaded that today
another one hahaha
@meager spade give me one second, I'm with zlo trying things here and there
I'll prepare an update for you
I took a stab at the project for a short while, then I had to do other stuff, might give it another go if its not solved by tomorrow
is there any way other than OnRep to know what property replicated
and when
because i have an object that like, holds settings
but it also has some state vars
so i can't use PostNetReceive to test when the menu should update
the only other option i can see is a LOT of OnRep_ events and i'd rather not do that
@high current thank you hehe, yeah this will probably take some days, there are like 4 people paralelly looking into it
we found some side bugs related that might clarify a bit the whole scenario
so i have a widget calling a function in a non playable actor, i want to always run this event from the server, so do i need to set up an instance and call the player run as server event from the other actor then call the original event, or is there another way without jumping between blueprints?
If you aren't owning the Actor in question, no
thanks, guess ill just keep hopping then ๐
PawnPrivate is null on a PlayerState that's controlled by AI. Wut
Why is this a thing???
when @tropic fjord ?
Always
I don't understand why
Maybe I need to override something in my child PlayerState
it doesn't seem to be replicated
It works fine when I use 2 Players
When I use one that's controlled by AI, it breaks
AI's don't normally have PlayerState
I know
unless you make them
@meager spade you had a run in with that this week
Maybe I can use the Instigator? ๐ค
pretty sure he had the AIController flat out ignore that boolean
Yeah i did but I got it working
You had the issue where PawnPrivate is null on a PlayerState that's controlled by AI as well? @meager spade
It is null on my ai
Right
I had to set it manually
I think its cause if ai controller vs player controller
I need to do more digging
I spent little time on it
@pallid mesa that only reinforces what I suspect is happening, ill check to see if i can fix it tomorrow, but it seels like you are calling events on the wrong client (or the notify has the wrong branches
its not @high current
well, i had the AIController not set itself as the Pawn's owner
when using one of the blueprint functions, think it was SpawnAIFromClass
there are some... mishaps in the Game Framework
but if the AIController doesn't set the PlayerState on Pawn server side
it just doesn't work
if it does, replication callbacks will handle client side
Yeah, AIController doesn't seem be able to GetPawn() either
Odd
I'll just make a new variable and use the Pawn I get from OnPossess, I guess
Bit stupid, though
struct FSetPlayerStatePawn
{
private:
friend APawn;
FSetPlayerStatePawn(APlayerState* PlayerState, APawn* Pawn)
{
PlayerState->PawnPrivate = Pawn;
}
};
this is odd to say the least
Yeah, the entire way it's built confuses me....
Actually, I might have a fix
I'm actually an idiot
Ignore all my messages
LOL
@winged badger that ping was weird, i expected a follow up:d
I forgot my Super::OnPossess() call inside OnPossess in the AIController..... @winged badger @meager spade I'm dumb
๐ฆ
Interesting. Mine's setting fine now
Can call GetPawn from both AIControler and PlayerState
Yeah, that's strange
yeah, could very well be, I didnt look trough everything in the project he send, breaking the engine is always fun
working with a broken engine, is funn-ier tho
It's impossible for a client to show the same state in actors as the server I'd the latency is non 0 right ?
It always has to be behind the server by it's latency
This makes client lag compensated server time of limited utility
As you want to be running behind, otherwise you would constantly be skipping the first part of animations when they happen
The only thing you can see real-time is the autonomous proxy
well yes, but that also gets fed replication updates which are bound to have latency
depends on your setup ofc, but a an auth proxy for client one is sim proxy for client 2
client 2 has delay
server also receives updates with delay as well, so if client 1's own auth proxy fucks up, after a short while of back and forth between the server and the client, the auth proxy will be corrected
I should be calling it auth proxy, soz
its auto proxy
Is it possible to pass in a pointer to a replicated component in an RPC?
@high current the auto proxy becomes simulated proxy on all the other clients so those will be delayed
Yes but I also said that
alright, i apologize then
@indigo robin you can do custom logic to simulate the position of the proxies forward based on latency
this already happens for example, if you have a 30 tick server and clients are running 60fps
they will update the positions of the proxies based on the last update from the server inbetween updates from the server
of course the futher you simulate them forward the better chance they have of being at the wrong position, but the smoothing UE4 does can make up for that
oh i tagged wrong person sorry :p
How can I call an event from a client to the gamemode?
Example: the player logs into an interface, the gamemode received an event "OnPlayerTriesToLogin(user, password)" ?
I've figured out something: bind an event in GM of the Player Controller. This seems to work, but are there other solutions? Also how do I call a GM event from UMG? Should I always keep a reference from the player controller?
im stuck on making a character selector.
i have a variable in my game instance that holds the value of the selected character. i set this variable before i join or host a server. in a standalone game, if this variable is not replicated when i attempt to host a server (server travel button) it will cause my game to crash when it tries to spawn the actor in the world, if it is replicated then it works as intended.
(when replicated) i select a character (lets say the default mannequin), click server travel and it spawns me in with the correct character. then on another client i select the character on the right, click client travel, and join the server as the mannequin. it spawns the client in with the same character as the server. im assuming because its replicated eventhough its not suppose to replicate?
anyways, heres some code of the gamemode and a screenshot
void ATheHouseGameMode::HandleStartingNewPlayer_Implementation(APlayerController* NewPlayer)
{
Super::HandleStartingNewPlayer_Implementation(NewPlayer);
UE_LOG(LogTemp, Warning, TEXT("Handle Starting New Player"));
if (UGameInstance * GI = NewPlayer->GetGameInstance())
{
if (UTheHouseGameInstance * GameInstance = Cast<UTheHouseGameInstance>(GI))
{
UE_LOG(LogTemp, Warning, TEXT("Got Game Instance"));
if (ACharacterBase * Character = GameInstance->GetSelectedCharacter())
{
FVector Location = FVector(-400.0f, 50.0f, 190.0f);
if (ACharacterBase* SpawnedCharacter = GetWorld()->SpawnActor<ACharacterBase>(Character->GetClass(), Location, FRotator::ZeroRotator))//CRASHES HERE IF SELECTEDCHARACTER IS NOT REPLCIATED IN THE GAME INSTANCE
{
UE_LOG(LogTemp, Warning, TEXT("Spawned Character"));
NewPlayer->Possess(SpawnedCharacter);
}
}
}
}
}
the testing was done on a standalone game outside of the editor, and each character is a different class that is derived from ACharacterBase
after thinking, the crash im assuming is coming from an invalid pointer in the game instance. the game instance SelectedCharacter was pointing at a ACharacter, but due to the transition it was no longer doing so, instead i need to get a pointer to the class of that character? if so, how can i get a pointer to a class
hello guys. i'm using AWS Gamelift to create multi-session. Player connect to the host will go to the lobby. When the host press start button which i'm using ServerTravel to the game map, the session get destroyed. What can i do to make the session stay active after server travel?
An overview of how travelling works in multiplayer.
If the session is being killed it's because the game is doing it somewhere
Travelling doesn't inherently destroy the session
does anyone know if it is possible to enable CharacterMovementComponent replication while the character is attached?
It doesn't do anything when the actor is attached to something
It is
via AttachmentReplication - but naturally you should attach server-side only to achieve that
How is the NetCullDistance supposed to work in the OnRep functions of the PlayerState class?
Well then I am lost, as just yesterday we established that attaching to component isnt replicated
Player States aren't culled by default
@high current If you attach an actor to another actor and it replicates movement, the attachment will replicate
@chrome bay So if i have variables like PlayerName, GuildName and so on they should be placed in the Pawn?
Ah, yes that is true, but the client wont consider the two bodies attached
Unlikely, since that data is for the player not the pawn
@high current it does, it attaches the root component to whatever 'attach component' is, including socket etc.
See FRepAttachment and OnRep_AttachmentReplication()
The problem is that the widget that displays that info is in the Pawn, and i dont know how to pass the replicated value in the OnRep events in the player state
Just get the info from the pawns player state
Using a bind in the widgets with a reference to the pawn?
Can it be done with an event?
IMO it's better design to have the UI query the game for info instead of the game telling the UI about info
Just use the widget tick event to update the text
Widgets all already tick anyway, and ticking is far cheaper than evil bindings
Binding would be a query technique?
No, just widget component in the pawn
Why binding is worse than ticking if they both execute each frame?
Oh alright
@chrome bay its wierd as yesterday we were debugging an attachment case with exi and vor, and the conclusion was to attach on rep for all clients, anyway.... Sorry for that then
I will do it like that, but i still would like to clarify some aspects of the PlayerState class
They're handy, but don't use them too often as they will ultimately drag performance down once your UI reaches a certain size
Alright
If i have a GuildName replicated variable in the PlayerState, every client will get that change even if they are too far?
As you said the PlayerState doesnt have cull distance by default
Player States are always relevant yeah, so they don't cull
But they are there for persistent player info
Say you add a scoreboard later, you want to get the players name no doubt
Nice
And just a last thing dude
If i am in a OnRep event in the PlayerState, and i put a SwitchHasAutority to then execute GetPlayerCharacter in the Remote, what player character am i getting there?
Its confusing
As OnRep is executed in every client
Every local character
If you run it trough the owner
Then you will only get a valid object for the owner of the player state
So i cant use that reference to update the widget i mentioned before, as other clients wouldnt see the change of the player state owner right?
You can
If you use 'get player pawn' {0}
That is rhe pawn of the recieving player locally
Which owns the hud
Not on pc atm but that should be the way to go
Let me test and i will tell you the results
I have the pc here
So i wouldnt need to use the tick event as Jamsh suggested?
@high current I have just noticed there is a PawnPrivate variable in the player state
The tick event approach is a more generalized way to structure UI
Never used that one
That is prpbably only valid for the owner though, so not what you want
Worth a try to
I have tried the GetPlayerPawn and it doesnt work
With the tick event it works perfectly
But i havent understood why using the GetPlayerPawn doesnt work...
Im going to send some pics to try whats the result and what should be
The result i get using the OnRep in the player state
At the top left you can see the corrent player name that should be shown above the player head, it is set with a RPC from player state server to owning client so it works perfectly
Now the result setting a reference to the pawn in the widget and extracting the info of the player state from that pawn ref in the widget tick event as @chrome bay suggested
Well you are just running into a timing issue
Usually the PlayerState exists long before the Character does.
And depending on latency and stuff, your OnRep in the PlayerState might call before your Character is spawned and possessed.
Let me try using a delay node
The tick solution works cause it's basically polling the whole time until everything is valid.
No, delay nodes are not the solution
Just for curiosity
You could get away with just binding it and polling it + null guarding (isValid) for now.
And fix it if it ever gets a problem performance wise
Perfect!
Yeah you run into another issue, which is that the Widget in that has no proper owner
Usually when you create a widget by hand, you pass the owner
A Pawn spawns and creates the Widget long before the Pawn is possessed
That could ask everything....
So it has no valid owner
So you can not use GetOwningPlayer and such
You could set the owner afterwards, but you'll quickly find out that nested widgets don't update, so you'd need to build your own recursive call for that
But it should work using the GetPlayerPawn in the OnRep event of the PlayerState?
The other idea, if you want it event based, is to make sure you cover all cases
You can't be sure the Pawn is valid when the OnRep calls, can you ;)
trigger the initial update in onpossess and let updates after that work through the onrep?
You have two points in which you can react to this
The Pawn has an OnRep_PlayerState in C++
And the PlayerState should have a Pawn variable by now iirc
Doesn't have an OnRep though
half of UE multiplayer stuff is finding out when everything is setup, you also hve to check for what happens when actors leave/enter relevancy too
Playerstates are always relevant, so at least he doesnt need to worry bout that
@river hazel That why i asked before about the player state cull distance
I would use OnRep_PlayerState in the Pawn to grab the PlayerName and set the value in the Widget.
Now that covers one way. It could be that the PlayerName is not yet replicated.
So you have to catch the other direction too.
OnRep_PlayerName won't work I think, cause you have no access to the Pawn it belongs to.
A variable exists but isn't replicated.
So you could make your own Pawn variable in the PlayerState and OnRep that.
Letting the Server set the variable OnPossess
I usually prefer dealing trough the PC with this stuff
Not possible as simulated clients don't have access to that
Lol it was more complicated than i thought
Yeah it's annoying to get the name into the Widget
I would still suggest just binding it
Use OnRep_PlayerState to pass the PlayerState to the Widget.
and the just bind to GetPlayerName
Yolo
:d
I looked for the typical Health scenario, and you had one example in your compendium, but that variable was in the pawn so the case is different
Yus
(Amazing compendium by the way dude)
^
Cheers
So tick event is going to do the trick
And fuck everything
Event based seems very complciated to do
depwnds on the stuff you layer on afterwards
Not Tick directly
Just bind to the Text of the Widget
It's ticking too though
But well
Cleaner :P
Jamsh said that tick is better than binding because binding is called even if the widget is not visible
But in this case the widget will be always visible while the players are visible
Fair enough. My stuff all binds. Not having problems yet. ยฏ_(ใ)_/ยฏ
So i think binding would be the same
I know that Tick is an issue in general
Because as soon as it is
You can go back and fiddle with it
Yeah but if you have performance issues cause it ticks when it's not visible, you most likely have the same problem when it ticks being visible
Everything was solved, thank you so much guys, you are amazing
Yus
But seems to be the only clean solution, the tick event
When i finally play hoverloop, if i have fps problems, ik what to blame now :)
Oh i almost forgot, just one curiosity about the compendium eXi
/shrug
What was the context for that mostly
I think its the cull distance and so on
Might be me just wording things shitty
But jsut to make sure
It's not my first language after all
Excuses...
Well it is not bad written at all as player state is always relevant but pawns not
Anyway, Anje did you put an is valid on the tick?
Yes
I'll keep in mind to remove that mostly
Then ur good to go
Im a lover of IsValid node
no idea what I wanted with that
What is that?
Maybe the mostly means that there are parts in it that are owner only haha.
I have to fix that
Losts of optimizations for big player counts
It's a system that allows Fortnite to exist
Rep graph is for that
By putting Actors into Buckets of how important they are for a player
And based on that they replicated more often or not at all etc.
I think on PC, only the 3 closest enemies are in the top priority bucket
On mobile only 1
I am curios how the rep graph adjusts if you use a scoped weapon
@chrome bay loves talking about this wonderful, bugfree system
Can probably tell you something about it
If the poor guy has time
Anyway, props for the underwater hoverloop lvl, i know its not your department but them caustics are nice
This Fortnite...
Thanks, I will forward it!
Speaking of it tho, been meaning to ask, how many line traces are you using for the hover rafts?
Tf.... Autocorrect
To get some smooth hovering, it's I think 8 atm
Could show you, but the PlayFab Plugin isn't compiling xD Can't start the project
We have a few additional ones, like 2 or so for other things, like ground contact or finding a surface that counts as "Gravity"
Recently realised my hover movement can easily turn into spiderman movement...
Technically yes, if you keep the Gravity direction optional, then you can easily adjust it to do that
Which is what we do. The HoverComponent takes any Gravity Direction and just works from there on
Ah, you're working with Force?
We have Physics/PhysicX disabled
Its an old ish project
It's all Vector Math
And then adjusting Velocity based on that
Can't network physics stuff otherwise
Ikr
Is there some documentation about good practices on multiplayer stuff?
Don't use rep graph unless you're comfortable poking around engine internals
it's buggy as hell atm
Had a run in with that wen doing tribes ish custom cmc movement
Or just getting frustrated when things dont work?
Don't think so. It's mainly about knowing what Classes to use for what.
If you know the basics about Replication and Ownership, as well as RPC vs RepNotify
Then the only thing left is where to place what
GameMode,GameState,PlayerState,PC,Character, etc.
I know what your compendium explains
And then maaaaybe some stuff about prediction on client side
I think i place things correcly, but you know, im never 100% sure
So doing gameplay effects on the executing client directly
@chrome bay no yeah, i am hoping i dont have to use that, next univrrsity year is 1y long project, but the BR wave is over so I will try to steer away from doing anything above 12 players
Mostly i would like to know how to control asyncronus execution in the engine
I mean, the beginplay of this class can go faster than this one
So maybe this reference is not valid at this moment
Just techniques or tips to control this type of events better
Anje was just asking and i got curious about how rep graph handles weapon scoping in(in regards to player relevancy for replication
rep graph is something you write
for your game specifically
the default just uses the exising virtual methods on actors/objects
Aight
@steady tendon another thing is knowing when to use async event execution and when not to
Not directly a MP matter
But running events asynchronously can help avoid some bugs in MP
But running events asynchronously can help avoid some bugs in MP
Alright, anyway im getting better and better with the practice
Its like i dont want to see more Delay nodes with 0.1 seconds to wait till something is valid, i feel my code is ugly with that
Hahaha
Like a pawn waiting for its PS to be valid via a delay node which runs from cast failed right back into the cast
:d
Yeah, obviously... But you know what they say, if it works it works
you're all fired
well, the famous bug I've shown is not BP exclusive
James plx I have a family to feed
About the issue, we are trying to find an ABC work around
and probably report it to UDN later this week
we are maybe facing to a dangling PS and 2 PC's possessing the same pawn
all because of a late payload on netcull
how static array is replicated? as a whole just like TArray?
I have such a property for my inventory.
FHeroBackpackSlot BackpackSlots[32];
I don't want it to be replicated completely every time an element gets changed.
The only allowed usage of a DelayNode is with a 0 in it.
And that's not a joke of sorts.
^
does it compute differently with 0 as the input? (I know for a fact is a frame skip)
Say that you have a ability cooldown in an MP game, how would you guys handle that, considering you also have to do UI for it
timer
Say the UI is a progress bar
hey guys. if i want to implement the health system for players, should i use RPCs? or Replicated Variables are doing the job?
Would you run a timer on server and do something like a timeline or animation locally?
@brittle karma a replicated variable being altered on the server is enough. I recommend you doing it onrep so you can call the "death" function when Health <= 0
@brittle karma unreal already has a damage system which serves as your RPCs
So the rest is variable work
@high current almost everytime you create a timer you need a timerhandle to cancel it or invalidate it just in case
@pallid mesa thanks, where is the proper place to implement this? Player controller, Game State or Pawn itseld?
the health belongs to the pawn
@high current is it already on c++ too?
@high current the timer handle provides the time elapsed
however what we do is letting the owning client know they need to start an animation with a clientrpc if that timer is critical and needs to be called from the server
you can then compensate with the player latency in case you need accurate animations
If yoy need the the rest of the players to know your HP, consider making the player state aware of the pawns health
well health doesn't belong to the PS, but if you want to treat it as some sort of score
I guess you could
So if its a ui progress bar you read the timer handle on tick? :d
you could do that or just trigger an animation with a variable in which you calculate the play factor of the anim
^yeah
test and see which one is more convenient for you, I would go for the anim route
Anim sync is much better
but you know you have the timer handle for whatever you need
one little trick, make the animations a bit longer than the actual effector
not too much longer, just a tiny bit
I have done a system with server game time syncs and events for begin and end, but i was ticking anyway so thats why
And used ui anims
Another time I had to rush a prototype and did server replicated timelines
There i had dynamic cooldowns and needed to modify stuff mid cooldown
But if i have more time ill probably do timers
I did something similar with typical buff system using just 1 timer for any amount of buffs. Lets say i have Buff A with 5 seconds left and I want to apply a new Buff B (with 10 seconds time duration). In that moment i substract the timer elapsed time to the remaining duration of Buff A, then i add Buff B to the array and the last step is to reset the timer with the shortest remaining time of all buffs, in this case will be Buff A
Then the server sends RPC to the client with the new Buff B and the duration it has, enough to handle everything in the widgets to show a countdown or something like that
When the server timer finishes, it removes the buff that had the shortest buff time and resets the new time with the shortest buff time of the rest in the array, then notifies client with RPC with the removed buff
@high current I dont know if it is related to your question ๐๐๐
Everything is, we are just discussing here :)
im logically stuck, players overlap items and pick them up. the pickup item class calls a function for the instegator pawn and updates its inventory by increasing the variable number of that item. now i want to show that number on screen.
so i implemented a function inside Player Controller like this.
int ARollerPlayerController::LaserLeft()
{
for (FConstPawnIterator it = GetWorld()->GetPawnIterator(); it; it++)
{
AMultiplayerBallsBall* LaserOwnerPawn = Cast<AMultiplayerBallsBall>(it->Get());
if (LaserOwnerPawn)
{
UE_LOG(LogTemp, Warning, TEXT("Laser Owner pawn is :: %s"), *LaserOwnerPawn->GetName())
// get laser amount for the playing pawn
return LaserOwnerPawn->GetLaserAmount();
}
}
return 0;
}
but it always return 0 for client side
and that UE log always returns this :: Laser Owner pawn is :: BP_MultiplayerBallsBall_C_0 which is server pawn's name
logically by a for loop i am getting all pawns in my game, so it should call the LaserOwnerPawn function for client too
shit, i guess i messed up when i used return in for /:๐
@HACK: Workaround until https://forums.unrealengine.com/unreal-engine/feedback-for-epic/1369596-allow-blueprints-to-call-serverrestartplayer is resolved.
Was this ever resolved in UE4 builds?
Currently, there is no mechanism for calling ServerRestartPlayer in Blueprint.
There is also no mechanism for calling RestartPlayer in Blueprint that respects
Has anyone ever taken an already existing UObject, renamed it to a new outer, and tried to Replicate it under that new outer's ReplicateSubobjects function?
I'm getting an issue where when that UObject is received on the client, it still has it's old outer
how can i get player controller inside other class? fyi. i want to get the player controller of the pawn who overlapped some items.
void AMultiplayerBallsBall::Server_UpdateLaserAmo_Implementation(int Val)
{
CurrenetLaserAmo += Val;
//send updated data to the screen. how?
}
is it even possible to access to client PC from Server Function?
the compendium has a nice page about that
i just found that. i should read it. thanks
of course. when i first saw the writer's name, i just said hell this is the guy on discord. thanks for the effort exi.
offtopic The moment you see WoW Server dying from 80 players fighting PvP on the World map.
Damn that War Mode is well implemented :D
And the Server literally died
Server got rolled back from that. Hey if you (random UE4 dev) feel bad about your UE4 multiplayer lag, remember, Blizz can't do it either.
eh, as long as we use floating points, no one can do it perfectly
That being said, the only games which impressed me in regards to networking, are the battlefield series, titanfall
and lawbreakers
battlefield has rly clever lag compensation
titanfall manages to run uber smoothly with an insanely low tickrate, and lawbreakers hit insanely high response times
link to the article
someone shared it on twitter last month
very well said, I'm still impressed how back in day world of warcraft could handle whatever you threw at it, and how now there are certain issues in the core netcode.
And don't get me wrong, they have some of the smartest network optimizations in place
but again, containing all the players in a single point while all of them are relevant for each other is, and will be one of the hardest challengers a developer would have to handle
Actually in Vanilla/Classic, it would've worked.
We had 40 vs 40 Battlegrounds working just fine.
We had 40 vs Main Town Raids working.
The current Retail version just has so much going on, with hundreds of variables that are new and have to be replicated etc., that it's not doing it anymore.
- I feel they moved back on server strength
so I created a simple shop widget that my player can open and click a button to spawn a vehicle but when I click the button the vehicle is spawned only on the client, not the server, which means the player can't interact with it at all. any ideas how I could fix this?
here's my script for it:
https://i.imgur.com/hk6ZhP0.png
I have seamless travel, however in my GameMode I have a PostLogin event that assigns players their teams, and the event was intended to fire when the map is loaded in.
Is there an equivalent to PostLogin that fires right after seamless travel?
the problem is that postLogin already fires when players join the lobby, so it won't fire during seamless travel
really don't like BP for multiplayer stuff, but in the above example that will only run on the server, never the client. also using the Get Player Character node with a fixed index is not how you would make something compatible with multiplayer
the only situation is that you're PIEing in non-dedicated, and you're interacting with whatever this is as the first player which is essentially the listen server host
also when it comes to server RPCs, the client calling the function must be the owner of that actor
use "GenericPlayerInitialization"
instead of PostLogin
it gets called both at the same as postlogin, AND after seamless travel
* Handles all player initialization that is shared between the travel methods
* (i.e. called from both PostLogin() and HandleSeamlessTravelPlayer())
*/
virtual void GenericPlayerInitialization(AController* C);```
@granite peak
Did anyone use the GameInstance or LocalPlayer Subsystem since it became available?
I have a plugin with functions to login/access our backend and I usually placed this into the GameInstance, cause of Lifetime and such.
However I wonder if placing it into a GameInstanceSubsystem makes sense or if that is the wrong usage of that Subsystem class.
Yeah totally do it. The subsystems are just a convenient "extension" with a managed lifetime.
Saves you time having to setup a manager and maintaining its existence, initing it etc etc
I moved our GameLift manager over to a GameInstance subsystem, really wasnt much hassle and essentially operated identically as what i was doing before was creating a UObject during Init() anyway.
Plus you get those nice auto generated Blueprint nodes to grab it as well.
Yeah subsystems are awesome!
Coolio.
@fossil spoke Funfact, GameLift or GameSparks (can't recall) had a USceneComponent instead of a UObject for their stuff before.
However that was a little bit too much for me to watch so I told them they really don't wanna do that :D
@pastel totem @fossil spoke One quick question: Is that ONE Subsystem per Class (LocalPlayer, GameInstance) or does it allow multiple?
Yeah you can do multiple
Awesome, thanks!
I wonder though if I would keep things like the login state in the GI or LocalPlayer
A LocalPlayer does not survive map changes, right? I wonder why Epic puts the login stuff into that in UT.
- you would have one LocalPlayer per Splitscreen user, which shouldn't even login.
I will use the GI I guess
No I don't think it survives map changes.
GI is the better option imo
I have a skeletal mesh actor which is simulating physics on the server and replicates movement.
The replication works fine, even when attaching it to something. But when I detach it again, the transform doesn't replicate anymore...
I never had this issue, am I missing something?
Attach and Detach is done on the server, as well as physics replication
Integrated Steam into the game, but the trouble is that you cannot test the dedicated server and the client at the same time, if you start the server, it takes the account from the Steam and the client cannot get the Steam account, you can do something so that you can test everything on one account ?
Strange, other games like rust, garry's mod, cs games, allows using one machine and one steam account
@twin juniper It's more subtle than that
You can't log in to two Steam accounts, and you need two accounts for matchmaking / joining sessions
If you disable the Steam subsystem, you'll be able to join the game
Multiplayer code - having two games talk to each other - doesn't use Steam in any way
So these games do exactly that, to ; they just let you connect to the local server on the PC without matchmaking
In UE4, this is done by using the null OSS
Of course, the drawback to this is that in UE4, using Steam is an all-or-nothing matter
The Steam Server needs no Account
It needs the Steam DLLs.
It should also be very much possible to host a DedicatedServer on your PC and join it with the same PC.
Did that plenty of times with other Steam titles.
Just that UE4 is shitty with Steam for whatever reason.
@bitter oriole @twin juniper
And these Games can't use NULL OSS, cause they show up in the Steam Server Browers for others.
best example would be Counter Strike
Okay, well, I don't use dedi so I really don't know, thought it'd work like for regular clients.
Sorry for the bad information
All good, no one has good information on steam DedicatedServers anyway
I just know that you don't need an Account for it. Cause you can launch multiple Dedicated Servers on one machine.
Even if no client is using it that would already mean you need x Accounts logged in on one machine :D
also means that steam interfaces that depend on client running don't work on dedis
I have a server RPC that spawns an actor but for some reason it spawns 2 each time. This Switch doesn't help and the sequence is not firing twice (?)
Anyone ever had to deal with a Platform that requires third party services to be opt-in?
Kinda wondering how it should work if you have a backend system, that is completely required to play the game and a user says "I don't want to link my XYZ account with your backend.".
Just kick them out of the game :D?
Luckily it's a F2P game
@thin stratus Yes -- what usually happens is the platform will request that you use their platform-specific user ID for the player(s) by default. We had our own DB of players and used it to prevent duplicate use of usernames amongst other things but when it came to this particular platform where we were forced to use the platform-specific ID, we used it as a display name but registered the user with an added character in the backend if the username had already been created. Then, in-game we displayed their platform along with their username and if two users had the same name, the platform icon would separate them.
This set-up doesn't require the user to agree to being signed up to the database or to even know that this happens at all because we didn't collect any information aside from their username and our privacy policy / terms of use covered that.
The RPC can also be in the Character
But the idea is the same
KeyPress -> RPC in a ClientOwnedActor -> Trace the Car -> Possess the Car.
And where is it failing?
You gotta do some debugging yourself :P
Is your function fully executing?
Should the raycast for picking up an item be done in the client or server?
Server
@solar stirrup server
You can perform it on both
But the Client would only do visual stuff
So the delay is not the big
Aight
With high latency, wouldn't that cause some issues with the server's raycast missing the item? Or is that just acceptable
Well we are talking about prediction
The Characters Movement on the Server should, at the time of the RayTrace, but somewhat the same
The movement is predicted too so
High Ping will never be nice
For getting into vehicles etc, I do the trace client side. If client thinks they can get in a vehicle they tell the server, then server does some sanity stuff
I.e checking distance etc
Bit easier that way
does anyone have any good sources/links on how to setup mordentral's advanced voice (from the advanced sessions plugin)?
a client overlaps an item and add the item to its inventory(others cant see that so nothing to replicate), when item gets overlapped it calls a function for that instagator pawn, and becuz server should handle this, so it calles an RPC function and in the _Implementation part Player Controller gets called(becuz every one has specific player controller its a best place for that isnt it?) is it a true implementation? or becuz i call player controller inside an RPC it will always will return Server's PC? cuz when ever client overlaps an item, it counts for server /:
Can my RPC function be virtual?
the _Implementation / _Validate part can yeah
That used to be the default in ye olden days with GENERATED_UCLASS_BODY
aight
I suppose I should only make the RPC itself public and the _Implementation and _Validate functions protected right?
or will the engine not like that
Not sure to be honest, but i doubt it matters. You never call those variations manually anyway
Yeah but I don't want other devs to accidentally do that haha
Well, would probably be cleaner anyway
I always have them next to each other, just makes it easier to read
good point
If I need to validate a Server RPC which isn't critical (moving an item from a slot to another), do I really want to use the validate function instead of checking inside the implementation?
IIRC Validate kicks the player for an invalid RPC right?
it'll kick them if it returns false yeah
most of the time to be honest I don't find it all that useful, but it's handy if you know a player is outright cheating
But then you may want to ban, kick with a message etc. I think it's just a bit of a relic tbh
in 4.23 Server finally no longer requires WithValidation
@fleet raven That's amazing, so you can skip the validation function entirely?
Will clean up so much of my .cpp files if so
Do you need to specify something like WithoutValidation in the header or just omit WithValidation?
just remove the WithValidation
99.9% All my validates are in my headers with return true.. going to be weird to get used to removing that
Me too
nah it'll be fine
Is there a ever a list of these kind of nitty gritty changes posted anywhere?
Maybe the full release notes will mention it
just skim over the commit titles every few days
Also do you generally upgrade any production projects you might be working on to newer engine versions? Just keeping a wary eye out for things that might break? I did hear some advice to pick an engine version for a project and stay with it, but some of these 4.23 changes are so tempting
Sorry a bit off topic I'll delete in a min
I upgrade our project on release day every time and never had a problem
Damn that's very encouraging
Thanks!
I guess as long as it compiles and the log isn't yellow or red, it's all good ๐
Yeah I usually do the same, even for previews (though not on any live product)
of course there's always going to be some work migrating things and fixing random stuff but no show stoppers
Just things like includes moving and functions being deprecated right?
I never use preview versions
I'm not good enough with C++ to fight anything more complicated than those
And yeah I'd stay away from preview
I wouldn't use them on anything far along
yeah mostly just updating the api
migrating our random bug fixes to the engine/removing those that aren't useful anymore
etc
Ah that's a step I don't even have to worry about thankfully
Using binary build
currently doing that by duplicating the branch and then rebasing the copy to the new engine version
that lets me resolve conflicts for every individual commit instead of having a single merge make a mess
I wonder if that strange bug in 4.22 that was absolutely eating up bandwidth per player for no reason is still around
Not even sure if it's been reported, just talked about here. I'll submit a report if not
haven't heard of this issue, any details?
One sec it's in the logs
same, news to me
PlayerCameraManager->bUserClientSideCameraUpdates = false fixes it
Sends an RPC on tick and doesn't do anything if you don't need it
Erebel found it
For players that have high framerates it's a gigantic bandwidth cost for nothing
oh wow that sounds egg
I was trying to figure out why my simple 2 player co op game was easily saturating the bandwidth
Turns out it was just the framerate combined with that bug
Night and day difference when it's set to false and of course that scales with the amount of players
turned it off but doesn't seem to make too much of a difference
Can enums be replicated?
yeah
neado
is there a simple way to stop an actor from replicating to new clients without cutting off the replication to existing ones?
IsNetRelevantFor maybe?
I'm not sure how I'd determine whether the client already knows about the actor
and returning false would stop replicating it to existing clients
Ah I see what you mean
In that case nothing I can think of, I mean you could tear it off and the clients that already have it wouldn't kill it, but wouldn't get any future updates either
tear off would completely close the channel right? so they wouldn't get the signal when the server has finally deleted the actor
yeah the clients would take it over and have to destroy it locally then
hmm
Although, I've never bothered finding out what bNetForce does if you pass it into Destroy().. maybe that does something useful
bNetForce allows the client to destroy replicated actors
ah not that useful in this case then
can I just point out how epic this comment is
10/10
oh well
I guess I can stick a replicated var in it with cond=initialonly
and when the client has it on init it just goes and destroys it again with bNetForce=true

that doesn't entirely work as intended but good enough
im doing some netProfiling and im chopping things up here and there, but one thing that i cant seem to understand is AttachmentReplication
seems to be something that replicates because of attached actors like you would expect... but why does it keep replicating thousands of times even though the property doesn't need to ever change ??
in scene there are 400 actors attached to 200 individual actors, so it should change ~400 times right ?
not 6000+ lol
You sure it's not just replicating to multiple clients?
only one client running
Couldn't tell you without debugging it but yeah it's for replicating the actors attachment to something else.
i have another property on those same actors that are set to "initialOnly" and they only fire off 400 times like you would expect
Both ReplicatedMovement and AttachmentReplication are replicated using REPNOTIFY_Always - it might be that the server just flings it out all the time
oh wow
Not sure off the top of my head though, usually that's just a client-side thing IIRC
Yeah, I'm sure that's client-side only
its in the server's netProfile thing though?
the server is considering AttachmentReplication for replication even though its never changed, and is sending it to the one client
it might be like you said a sideeffect of repNotify_Always
Oh, yeah well it will always consider properties - but it shouldn't send them unless it doesn't match the last-sent value
It does store the relative transform as well as the attach point, so it might be that tiny changes cause it to replicate
Going to dig into that repnotify always hunch now because that would be infuriating if so
you have to be shitting me
I really hope I'm wrong, but RepLayout::DiffProperties_r always considers a property different if it has REPNotify_Always
Why is that not documented anywhere ffs
So does ELifetimeRepNotifyCondition take priority over ELifetimeCondition?
No that's slightly different
but ELifetimeRepNotifyCondition basically will replicate a property even if it hasn't changed if set to REPNOTIFY_Always
that doesn't seem right
it would make fortnite send thousands of useless attachments per second
Well Fortnite uses a lot of network dormancy, but otherwise I couldn't say
Trying to navigate my way through this spiderweb of code, but this is disconcerting:
{
bDifferent = true;```
I'm hoping that's just client-side but still trying to confirm
I suppose I could just test it lol
brb
if (Role == ROLE_Authority) {
//store the pawn which overlapped the item
InstegatorPawn = Cast<AMultiplayerBallsBall>(OtherActor);
InstegatorPawn->UpdateLaserAmo(LaserPower);
}
guys the code block above only runs by server right? but when i play with client this block gets called
i have a question, i think this would be more tailored to the game instance and player controllers. im setting up a simple character selection menu, when a character is selected it stores the UClass of the character in my game instance (this is getting set before the player joins a server). ive tried about 4 different methods on getting ahold of this specific UClass to match it to the player controller with no luck. the most recent method i tried was (this is after joining the server, trying to set the UClass while connected) creating a struct that contains the player controller and the UClass and storing it on the servers game instance in an array of those structs. This didnt work as it seems the player controllers change after a level load lol. ive completely started from scratch again on trying this. im looking for ideas on ways that i could have the player select a character at the main menu, store the UClass of that selected character on the game instance (already done), then when the player joins the server, i would like the server to get ahold of the UClass of the player somehow, preferably without the client sending it if possible, as well as have some sort of unique ID for that player stored with the UClass on the server for changing levels.
so client sets character selection before joining server. client joins server (server lobby level), server stores the client ID with the selected character UClass. the game starts and all clients travel to the game level, id need an idea on a way to spawn that characters UClass (can store it on the servers game instance) and have the correct player controller possess it. im not sure how i would be able to figure out which player controller would correspond to the correct selected character
@brittle karma yes that code would only run on the server. how are you testing to know if the code is being ran on the client?
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, FString::Printf(TEXT("%s"), *InstegatorPawn->GetName()));
depending on how it is being called, the server could be running the code. how is the function being called?
its inside Overlap event, whenever the item gets overlap this gets called, however this should only respond to server, but whenever client overlap somthing this reacts like its server
void AP_Laser::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
//destroy the item when overlapped
Super::OnOverlapBegin(OverlappedComp, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);
// Server Should Be Authorize for this replicated actor
if (Role == ROLE_Authority) {
// some code
}
}
is the laser like a bullet thats being shot?
yes
are you spawning that laser on the server when you shoot?
like so it only is shooting the laser on the server?
well that overlap even is being run on the server then, so your Role == ROLE_Authority check will be true
let me rephrase and tell me if im understanding you
the client clicks their mouse to shoot which calls OnFire. OnFire calls a server RPC function so the laser is spawned on the server?
yes the spawning part is inside Server_OnFire_Implementation
alright, then that overlap event is being ran on the server, which is why Role == ROLE_Authority is true
let me describe this way
i have a laser pack in the scene which i implemented the Overlap event in its class. now when i overlap that Pack i expect only server call the if block. the spawning laser to the scene has nothing to do with an item
when i play with client, the if gets called too. why?
its like this. i myself put those things items into the scene
out of curiosity, in the if block try
if (Role == ROLE_Authority)
{
if (Role < ROLE_Authority)
{
UE_LOG(LogTemp, Warning, TEXT("THIS IS A MESSAGE FROM THE CLIENT"));
}
}
THIS IS A MESSAGE FROM THE CLIENT should not appear in the log. also keep in mind, testing multiplayer related stuff in the editor can make some issues that are not actually issues apparent, so for testing mp stuff i recommend testing outside of the editor
i dont think its actually running on the client, i think its just the editor throwing you off
no the message didnt appear
that's a weird sequence of ifs, to the point that it will never log
yeah it would never happen
unless you meant the second one to be RemoteRole
because its running on the server, it was more so to prove a point unless im still not understanding shayan's question properly
the overlap even is being ran on the server, even when a client walks into it, so the Role == ROLE_Authority is going to run
now this makes sense
did that clear it up a bit?
yeah very
sweet
guys one question im working on it like the whole day but i cant figure it out.
when ever i overlap this item i want the pawn who overlapped the item add it to its ammos.
now i do it this way. in Pawn class i call a RPC (server)function so server is responsible for updating the pawns ammo numbers. this here everything is fine everyone get the accurate update, now as we know Player Controller is the best place for having the info about clients ammo info and send the information to the UMG
is it ok that im calling PlayerController inside RPC function? i think it always call the server's PlayerController cuz when ever client puts the item it counts for server
on the players character (or weapon/ammo component, wherever you have your ammo), make your ammo variable replicated. then have the server simply modify your ammo variable. when the server modifies your ammo variable, it will translate down to the client as well
you can see a quick example of this in my health tutorial video. ill explain how im doing it
the player presses E that calls a function that sends a ray from the character to about 5 feet infront of the character to pick something up (in your case, the overlap event). if the ray hit something, it calls a Server RPC function that sends the ray out again but on the server (in your case, this would be the same as your if (Role == ROLE_Authority) check because only that code is running on the server). then if the server hit something with that ray (meaning your if (Role == ROLE_Authority) check in your overlapped event returned true), then it simply modified the health variable (in your case ammo) thats on my characters health component (or your weapon component(wherever you have your ammo stored)). because the health (ammo) is replicated and being modified from the server, the client will have its health (ammo) value change as well and the client is not the one change its health (ammo), so simply trying to change the ammo value via something like cheat engine wouldnt really work if you set it up properly which it seems you have
In this video we setup the base for our health and doing some code improvements. We will be setting ourselves up to take damage in the next video. Download t...
well thanks for the help. Amazing ๐
np and goodluck
now time to post my question since its lost in the wall of text lol
i think this would be more tailored to the game instance and player controllers. im setting up a simple character selection menu, when a character is selected it stores the UClass of the character in the clients game instance (this is getting set before the player joins a server). ive tried about 4 different methods on getting ahold of this specific UClass to match it to the player controller with no luck. the most recent method i tried was (this is after joining the server, trying to set the UClass while connected) creating a struct that contains the player controller and the UClass and storing it on the servers game instance in an array of those structs. This didnt work as it seems the player controllers change after a level load. ive completely started from scratch again on trying this. im looking for ideas on ways that i could have the player select a character at the main menu, store the UClass of that selected character on the players game instance (already done), then when the player joins the server, id like to be able to store the selected characters UClass (thats stored in the clients game instance) and that players playercontroller(or other way to identify the player on PostLogin/HandleStartingNewPlayer_Implementation) on the servers game instance so that when the game goes from the lobby to the actual game map, the players selected character can be spawned and they can possess it. i cant figure out how to store the info i need on the server(i can store the UClass easily but cant figure out what i can do to let the server know which UClass belongs to which character in the PostLogin/HandleStartingNewPlayer_Implementation functions since the playercontroller changes from the lobby to the actual play level). just looking for ideas to try out
Has anyone had luck with dedicated server building on 4.22
Iโve been cooking / building dedicated server on 4.22.3 w/o issue
@ocean geyser You can do it via 2 RPCs on the player controller. The first RPC is fired from the server to the connecting client on PostLogin, call this one RequestPlayerClass or something, all it does is trigger the 2nd RPC which youโll send from client to server. The 2nd RPC can grab the class from the client side Game instance and then pass it in as a parameter to the server. Then when the server receives that 2nd RPC from the client they just spawn the actor with the class reference and possess it
Interesting, I'm building the UE4 Development Editor now from source, we'll see if I get things to work.
Tried doing this a few months ago on 4.19 and it wasn't working no matter what I did
@ocean geyser when does the player join the server? in the lobby or on a level where you need to spawn the characters?
because what you're describing sounds like a hard server travel
if it is (players connected to the lobby, then reconnect to the game map)
first, you should really use seamless travel, especially if its in combination with steam
and second, even with hard travel you can override PlayerState's CopyProperties function to transfer the UClass* (or w/e you need to) to a new PS, even if its of a different class
it is with a hard server travel right now as i havent bothered to integrate steam yet while testing. i thought you had a new player controller even with seamless, if not then that would be very convenient for this. im trying to make it work with both seamless and non seamless, i have a new idea in mind on how to do it by generating a random ID for each player upon them starting their game and using that as means of identifying them. thanks guys
90 minutes later the editor is done building... lol
Setting actor tick enabled. Is that something that needs to be replicated?
id think so if you wanted it to run on client and server, i would think it depends on where its set from. if its set to be enabled on the client then it will probably only run on the client, if its done on the server then its probably done on the server
hey, @winged badger or @pallid mesa have either of you tried to rename a UObject to change it's Outer before replicating it?
not really, no. That sounds very specific, what are you trying to do?
@gleaming vector @ me I gtg sleep 2:30 am here ๐ค
ah, go to bed
you can always leave me a message, I'll read it tomorrow then
but, I have some object (Item Stack) that is part of a "World Object" (basically, the dropped item in the world, it's an actor with a model), and when I pick it up as a player I put it into my inventory and destroy the Item World Object
in singleplayer, this works just fine
however, in multiplayer, I can't replicated down the Item Stack when I switch it from the world object to the inventory
unless I rename it to give it the same outer
as the object replicating
however, on the client, it didn't get the rename
if you want it to destroy on all, you should destroy it from the server
i dont want to destroy the item stack
I want to move it from the actor that holds it to the inventory on the player
or decrease it form server
of course that is done on the server
also move it form server
the problem is that when you go to ReplicateSubobjects, it replicates down, but on the client it still sees the old outer
so the client complains and doesn't accept the replication
i hit this in DataChannel.cpp:3240
if ( !SubObj->IsIn( Actor ) )
{
UE_LOG( LogNetTraffic, Error, TEXT( "UActorChannel::ReadContentBlockHeader: Sub-object not in parent actor. SubObj: %s, Actor: %s" ), *SubObj->GetFullName(), *Actor->GetFullName() );
if ( IsServer )
{
Bunch.SetError();
return NULL;
}
}```
pool the world entity object until you get your memo on your inventory
you might be suffering from premature destroy
I don't update the inventory on the client until I get this object though
but what you say sounds totally, fine. You need to change the outer, yes.
and it fails to read this bunch
this all makes sense though, because the name (including the outer) is supposed to be stable
and I'm explicitly changing it
mh.. I'd need to see the execution flow. Try watching for this object on the different roles when you pick it up.
put a breakpoint and see if it does something weird
I'm just wondering how I make it work in this situation
i have
it all comes down to the fact that the act of renaming isn't replicated to the client
I don't actually know how that renaming you are doing works. But if it's easy enough for you I'd try to replicate it manually and see what happens, really, empirically.
I'm just doing this
{
//We can't do this on clients
if (GetOwnerRole() != ROLE_Authority)
{
return false;
}
if (!AcceptsItem(Item, ItemSlot))
{
return false;
}
if (IsValid(Item))
{
Item->Rename(nullptr, GetOwner());
}
//Place the item into the slot
FArcInventoryItemSlot& Slot = GetItemSlot(ItemSlot);
UArcItemStack* PreviousItem = Slot.ItemStack;
Slot.ItemStack = Item;
//Inform the world that we have placed this item here
OnInventoryUpdate.Broadcast(this);
OnItemSlotChange.Broadcast(this, ItemSlot, Item, PreviousItem);
GetOwner()->ForceNetUpdate();
return true;
}```
are you also replicating the name you are changing?
Item->Rename(nullptr, GetOwner());
I'll take a look tomorrow into this
it changes the outer
first param is the FName
if you pass it nullptr, it doesn't change the name
second is the outer, again, give it nullptr it doesn't change it
it's one of those fun engine functions that do two different things
I meant the actual code hehe, but still try to move this "IsValid(Item)" to the top of the function call so it gets called not only on authority but on the client. DISCLAIMER: I'm not sure in which context you are calling this function
this is only called on server
no prediction of adding items to inventory
because that was just a headache and I gave up on it
since it would have to be transactional and undoable
and that was a lot of work
fair enough ๐
so i just said fuck it, i'll just do this on the server only
Any of my interaction systems got prediction and they just work fine
so... yeah, not needed (unless you are a geek hehe)
client tells the server "hey i know about this world object and I want it in my inventory" and it replicates back through TArray replication
okay, so try momentaniously to let every client know about that outer change
using a multicast or something along the lines
I'm not sure how, I can't reference this UObject once it gets into this state
see if with that anything changes, and by then you can draw some conclusions with your issue
since the client and server disagree about the name
I'd have to hold the item stack around
the ActorChannel class straight up stops deserializing any bunch that references a UObject in this state
maybe i should just completely invalidate it
and force the client to construct a new subobject
give it a new net guid and everything
Okay.. I think I comprehend now the situation, but at this point without debugging glasses couldn't tell
the easy way of course is just rebuilding your object
yeah
the biggest issue is that it's polymorphic
so I don't know if subclasses will even rebuild it properly
and that's just a bug waiting to happen
but if you can pass it around is even better. Another option is having a dummy object on your inventory to save your data. Like a little mono-pool
problem with that is that it's thought for a DOD approach rather than a inheritance approach
yeah
I'm going to try a full rename and invalidate the netguid
that will mean the client treats it as a brand new object
but, that would break any attempt to hang onto the object pointer
hmm
let me know how that goes ๐ probably zlo will be around tomorrow, he might know the "proper way" unfortunately the kind of design patterns I've used never faced such a problem
yeah, I'm just asking anyone who may have done something similar
I also have a UDN post about it out there
I really want instanced item stacks
that can be blueprinted
i have so many ideas with these
If you need a quick solution, just create a new object, really.
yeah
but like I said, that breaks any attempt on the client to hang onto an item reference
just leave it as a TODO. But at least you'll be able to keep prototyping
oh, I can prototype in singleplayer
or, as long as the first actor to hold onto the item stack is my player
it replicates fine
the problem is when you rename it
so, picking up an item off the ground
that breaks any attempt on the client to hang onto an item reference it depends on how and when you create your object
anyways Roi, I'm falling sleep XD
yeah, go to sleep
talk to you tomorrow, let me know if anything :)
thanks for staying up and at least listening to the problem ๐
๐
Hey guys, I just finished building my server.exe for a dedicated server, but it's crashing with the following error
i am doing pickup related stuff also atm, my main problems are more related to making an event running as server update the player widgets :/
Has anyone seen this error before or might know how to resolve it?
LogLinker: Warning: Unable to load package (../../../../../Desktop/UnrealEngine-release/Engine/Content/Animation/DefaultAnimCurveCompressionSettings.uasset). Package contains EditorOnly data which is not supported by the current build.
LogWindows: Warning: CreateProc failed: The system cannot find the file specified. (0x00000002)
well that'll be why
you're probably hard referencing that asset somewhere but it's editor only
does the player controller change even when you use seamless travel?
@ocean geyser Yeah, I guess I need to go through then and see if I have something that needs to run on the client during tick. If the player drops a weapon, after a moment it'll automatically fly back to their waist socket. So if it is dropped, it'll enable a book, if that bool is true on tick, it'll lerp from wherever it is, to the waist location and then run an attachment. Would the location of the object be handled simply by replicating the object and movement or would i need to replicate that whole thing ?
it would be better imo to replicate the event rather than replicating the objects movement. such as when you drop an object, call a multicast from the server
if i have a function run as server, is there a way to stop all functions in that from running as server also,
can you be more specific? what is it your trying to do
i am adding an item to a player inventory. i have a function called OnPickedUp which runs from the server, it then calls an add item function from the players inventory while still as server , that event then calls an add item (internal) function from the players inventory still as server. that add item internal function then calls a function to update the players slots. at that point, it is all widget based which the server can't access, so i need it to stop running from server and use the initial players references
@ocean geyser It's a VR game, so I have a timer set. When the player stops gripping the weapon, a 2 second timer starts, and after 2 seconds it sets the bool that will lerp the weapon from its current location to the belt, but I call it on tick since the lerp needs to be called over and over to make it all the way there. once it's in range of the belt socket it attaches it. and then disables the bool.
it then turns off the tick of the weapon as it doesn't need to tick when it's attached
there is more after the initial add item function that needs to run after as server also, so i only need to go back to the client player temporarily before continuing as server
just a thought, what about either calling an RPC from the server to the client, or replicate your inventory items array with the condition of owner (so it replicates only on your client) and then set it as replicatedusing with your function that updates your player slots?
the array is being replicated fine, but i can only updated the widget info from client, but the server can't access the clients widgets so the player has the items but can't see them atm. i guess ill have to handle it differently through multiple calls instead of chaining them in the add item function
crossmr, when the user lets go of the weapon, replicate the weapons movement, then once its attached disable the weapons movement replication would be the easiest route but wont look super smooth to other clients
Hmm.. yeah we don't want it to look too janky.
well it should only take a few minutes to implement if you already have the rest of your code setup, give it a try and see what it looks like. it shouldnt be to bad, but more so little stutters
okayy thanks I'll try that
So I got my dedicated server to compile and run - Success
It's loading the dedicated server map I have setup
Will a blueprint print string log to the console? I'm not seeing any output and the advanced session isn't showing up in steam server browser
sorry think i got what you meant, just need to work out how to do it properly :/
i ended up doing this, which i believe works, i still have other issues to take care of, but by the looks of the debugging it seems to have worked, will have to do more to work out if it actually did. so thanks for the idea it helped a lot
guys why is my Client RPC running on the server?
I know I have it set up rightUFUNCTION(Client, Reliable) void ClientOnInventoryInitialized();
and then in the .cppvoid UInventory::ClientOnInventoryInitialized_Implementation() { UKismetSystemLibrary::PrintString(this); }
I am calling ClientOnInventoryInitialized()in PostInitializeComponents()
how are you testing? with 2 players in the editor?
if an RPC makes an interface call, is the interface call on the target actor also being run "on the server"
Trying to understand networking in UE4:
Let's say a multiplayer racing game, does it make sense to store the color of each cars in a variable "Color" in the car pawn, set it as "RepNotify" and in OnRep_Color to change the color of car (via material parameter)?
Thanks!
as far as i am aware, interfaces (not talking about the blueprint interfaces)/widgets are client only, so if you try to access the clients widget from a server you usually can't, could be wrong
@ocean geyser 1 player PIE