#multiplayer
1 messages Β· Page 692 of 1
I will just unhook the PoseTick stuff from the CMC again
.............
That highly depends on your loading screen. I can't answer that
its just a ui screen
Yeah but where do you add and remove it?
I add it before the servertravel (see screenshot), and it get automatically removed when the new map opens
What callback do you use for the "When map opens"?
Not sure I have any callback (or I misunderstand?) , after I travel from lobby to gameplay_map, anything related to the gameplay_map is initiated in the gameplay_gamemode or the player_controllers
Hm, this looks really messy tbh
Hard to say what's going on and why it's not working
Could come down to a faulty setup overall
Interface for something that doesn't need one.
A delay, which is always bad for networking
CharacterInfo, if you are moving with Seamless ServerTravel, doesn't need to be send like this at all
YOu can store that in your PlayerController or PlayerState on the Server and move it over via CopyProperties (PlayerState) or OnSwapPlayerControllers (GameMode)
So yeha, idk, lots of things that seem out of place
I'll look into it, thanks! (pretty new to MP, I followed this ue4 course to set up the lobby / server system https://www.youtube.com/watch?v=Vw3d9Kwd6v8&list=PLM5xJtuLgIuz1NQcei5lE09TY5M4CMOwA )
Can't comment on tutorials :P Never watched those
I know Unreal's own Lobby Tutorial is garbage
Like, really garbage
So if that tutorial is based on that, then good lord
:d
so I have a more basic question, can lag sometimes mess with the order in which functions are supposed to trigger ?
Let's say I have a loop that triggers function A for the loop body and trigger function B when the loop is completed. Can function A triggers after function B because of lag ?
If I'm traveling from lobby to gameplay, does it have to be active on both lobbygamemode and gameplaygamemode ? It's currently only active on lobby-gamemode
It doesn't have to, but you should have it active on all gameplay ones anyway
WE usually have an overall GM class
Which has a MainMenu and a Game one as a child
And the Game one that further splits into Lobby and Gameplay
And Gameplay then has custom things (e.g. TeamDeathmatch)
And the Game one has SeamlessTravel on
I honestly don't really understand the issue
--
Is there some sort of cookbook for simple prediction? Not even movement.
E.g. "Do your action locally, send all info to the Server, if something is wrong, send correction." But with like a minimal setup that is generic?
Multiplayer often needs even the simplest of stuff to be predicted if it's player input caused.
An example is: Character has Energy (float). Player presses Key. If enough Energy, player turns into Stone. Energy drains. If Energy low or player releases Key, player returns to normal.
Predicting this with setting an OnRep boolean on the Client before sending the RPC is simple. But the float is not really
It gets drained over time, so on tick. Means if it's replicated it would constantly get overridden by the server. If not replicated it could go out of sync.
Send energy float to server? Send corrections back? Save "moves" on Client?
The Prediction Plugin would be handy if it was ready. Never looked at it. Not sure how far it is for UE5
Read something about clients not travelling
Have you checked the logs on the clients where it doesn't work?
@shy hill this holds true for all RPCs, not even lag related. Order of execution for reliable RPCs is guaranteed within the same actor for the same connection, but that's about it. For every other scenario there is no guarantee on order of execution
Also I seriously recommend reading up on EOS, it has so many benefits over Steam for development, but it does take a while to configure properly
Does anyone know if dedicated servers have a game instance, my guess is no / they only are given to player driven connections?
They do
GameInstance is unique and essentially represents the Unreal instance
So then logic running in game instance must be guard claused if it is only meant for clients
I think that is IsRunningClientOnly()
Thanks for your help!
I am trying to get an actor to NOT replicate. I've turned it off everywhere I can find in BP, as well as set it in the constructor. But I get the character on both client and dedicated server and BeginPlay is, of course, called on both server and client.
Anyone know why my character is replicating from my dedicated server when I explicitly told it not to replicate?
Can supply code and screenshots on demand.
I want the character to only exist on the dedicated server
most likely start with custom game mode and controller that spawns pawn only on server. but what will be on clients?
a bit weird use case imo
I have a class that spawns the server character. This class is created in and lives only in the gamemode. To be sure I use "HasAuthority" in the spawning code (even though it should only exist on server, just to be sure). I also only get 1 log entry regarding spawning, so it should have only happened once (on server).
The playercontroller calls that function from the class in the game mode (on the server).
My use case is some custom networked movement with client side prediction, server reconciliation, and lag compensation. I'm mostly doing it as a practice so don't bother giving alternative approaches π
No matter the use case - the ServerCharacter is replicated, somehow. No idea how as it's spawned only once on a server only class (existing on the gamemode).
I've turned off everything replication in the blueprint of the character and i've set bReplicates to false in the servercharacter construcotr
Youll need custom code, server spawned actors will replicate thier spawning to clients regardless of whether their variables are replicated in their actor
Meaning just turning off replicates is just making the variables not replicate to the server/clients... The movement component if it has one will still replicate and it's spawning will still replicate.
Is there a way to disable replication when spawned?
I haven't personally tried it as I've not had a need, but I think you can spawn an actor on a client and have it not show up on the server... Using the authority check... But not the other way around...
Not without custom code particularly your own version of the spawn actor
hm that is odd that that's not an option. How would you then have a separate server and client character and only adjust movement/other stuff when you want to?
You mean LAN? As in one of the players is hosting a game and friends can join? Or do you mean a character no one can see except the server?
Right now the plan was to have a ServerCharacter, with a ServerAIController, and then separately a ClientCharacter with a ClientAIController.
yeah a character noone but the server can see was the idea
to have my "server truth" and then the clients would adjust whenever I request them to
I can show you, I actually made a diagram
Yeah that will require your own version of spawn actor of class. Unless you just hide it visually with "only owner see" bool
Maybe I should just hide it and turn collision off... might be the way to go
There's booleans on actor class to set whether something's going to be rendered... The character will still however exist
so interesting that it's not even an option.
If the server is going to have some kind of influence over the characters that the clients are playing then they probably need to exist on the clients as well anyway
Otherwise you're just asking for a headache
Like a DM character that secretly runs the dungeon while the players are running through it
I like headaches π I'm wanting to implement client side prediction, sever reconciliation and lag compensation on my own basically
Nice... I see you're diving head first into all of the advanced categories of networking
You forgot to add replicated chaos physics
π
π
I guess it doens't matter if the owning client also has the servercharacter initial state if we just don't render it
As long as the client's characters have no influence over the server's character and they don't see him
I've seen some people's iterations of dedicated server that has like a observer class actor
And they just hide him under the map
lmao that's smart
And honestly it really does make sense why it's like that... This whole engine is catered to an online third person shooter game
so. If i want to completely hide and disable collision, all I have to do is set a boolean?
Spawn it only on the server with an authority check... In the owner pin get a reference to the server... And then set the boolean for "only owner see" to true and no one else will see him
To disable the collisions you would just do it the same way as always just make sure to set the character to flying movement mode
I'm not doing BP i'm doing C++, but i'm guessing it's called... let's see... bOnlyOwnerSee ? π
Otherwise they will fall clean through the map...
Only owner see yeah
As long as the owner is set to the server authoritative character controller... Only they'll be able to see it
ah so I can't find that boolean on the character. .. it's on the mesh?
It's on anything that's rendered so if you have a mesh yes it'll be the mesh if you have some particle effect it will be the particle effect
alright
If you have multiple things that are actually rendered... Particle ...mesh.. whatever each of those need to be set to only owner see
alright, i'll see what I can do, thanks
Glad I can at least give some pointers
Setting the fly mode would be on the movementcomponent "Can Fly" right?
Its the movement mode enumerator
Mode "flying"
Can fly needs to be true but im pretty sure the enum just over rides it...can fly just determines if it can enter that mode
alright
@verbal tendon @thin stratus Re - Clients not travelling to the next map. I think I found the cause and what seems to a fix.
I disabled the loading widget and noticed that the client was travelling to the map, but for some reason the player-controller didn't swap properly (from lobbyPC to gameplayBP )
OnSwapPlayerControllers was supposed to fire before the delay of 0.4, but it sometimes trigger after, so the cast to BP_gameplayPC (which initiate all the player controller stuff) doesnt go through.
I increased the delay from 0.4 to 3sec and it seems to fix it (I guess that's a dirty fix, and having the function triggering on OnSwapPlayersControllers would make more sense ?)
Delays are always shit
this
Like literally shit if you fix multiplayer issues with them
One Ms longer load time and it's broken again
If you think you found a fix, and your solution involves a delay, you're most likely not understanding what the problem is/was. So it's prone to just breaking again, or not working on all clients
You need to get a handle on the framework of ue4
What classes exist when
What do they call when
Etc
The more you follow the existing stuff from UE, the easier it gets
but but... why are there delays in every tutorial I watch ? π Jk! I'll try to get rid of them
I assume this is the same for retriggerable delays too? is the best way around using them just to create timers by function/event?
It's because the majority of tutorials are just illustrating a way of doing it. That is not necessarily the right way or the cleanest approach
Every tutorial is to be taken with a grain of salt, it's giving you ideas and inspiration. It's not supposed to be something you copy paste 1:1 in most cases
As you learn more this becomes more self explanatory, but I know it's hard at the beginning, because you have no other frame of reference, so the tutorial you see has a lot of situational value to you. Knowing 1 proven way of doing it is ifinitely better than 0 ways of knowing how to do it.
However once you've seen this being done 5,10,20, 100 times. Not only will you know how to do it, but you can also spot pitfalls, painful mistakes that you've experienced. Things become clearer as you amass more knowledge and experience.
(Retriggerable) Delays, Timers, Timed Events, the problem is not what you use, but the common denominator: time
If you are using time to solve a problem, you most likely don't understand the problem. A better solution is figuring out things along the lines of "Oh this isn't working, because I'm calling an RPC before the actor has replicated to the client." or "Oh this doesn't work because my objects have gone out of existence when switching maps"
Figuring out the problem, understanding the root cause, and then working a solution from that is infinitely better than slapping in a delay and then saying "But it works on my machine!" π
Up until now, I sometimes assumed that delays were the most efficient solution to certain problems, understanding it's never the case is good to know π thanks for clarifying !
I have a relevant example just to be clear. I've recently had to fix something using time. It was along the lines of: MaxAttempts = 10, try this until MaxAttempts are up then abort, sleep 100ms during the loop
Yeah that makes sense.. but the statement of delay's being shit, is that only in terms of if you are using the delay to 'fix' a problem, but the actual use of a delay in general is still okay to use?
However this was because (1) this is an editor tool, not anywhere in game logic (2) I understood why there was an issue. A spawned process that was executing a source control command was acquring a OS file lock that wasn't being released by the OS instantly after the command finished executing. So I needed to wait for the file lock to be released to schedule the execution of the next command that needed write access to said file
So that's interfacing with third party applications. If I had access to the source code and all of this was happening inside of the project's logic - there would be no delay&retry. I'll stop here before I go too deep into the rabbit's hole, I hope that's clear enough
It's totally fine to use time as a concept if you're implementing a feature. Every Actor's Tick is an example of that. If you're using time as a solution to a problem you don't understand, therein lies the problem
Cool, thanks for clarifying!
I mean it's a very general rule of thumb in programming. You absolutely need to understand the problem you're solving. You need to understand what's causing the issue, and why your change is solving it. Otherwise you're just playing russian roulette with your codebase if you're working alone. If you're working as part of the team, that will just not fly.
Its more for "Hey, this doesn't work. Let me add a delay. Oh it works now."
That's the shitty thing
But peeps propbably already told you that
I can say that I haven't had to do any polling or delay in any of my multiplayer projects in the recent months/years
Sometimes it might be a bit tricky to know when to access a specific pointer
But often it's relatively straight forward if you follow along with what UE wants from you
Because the tutorials suck. Most of them do. Do something small on your own and you'll learn 10x faster.
What's your general pattern for "DoThing when objects A, B, C are all in a nice synced state"?
I don't think I really have a general pattern, cause it depends on A, B, C
But the most general pattern I know is to ask each other
Once
E.g. Let's assume you have Customization Data for your Character on your PlayerState
Which is a reasonable thing
Now when this all replicates for the first time, it can be that the PlayerState or the Character are first on the Client
When the Character is first, it will ask the PlayerState, which is not there, so nothing happens.
Once the PlayerState replicates, it will tell the Character.
And other way round, if the PlayerState comes first, it will try to tell the Character, which isn't there.
when the Character replicates it asks the PlayerState.
So they cover each other
If the object itself is there, but no data yet, you can use a combination of bool + callback
E.g.
void ASomeCharacter::Init() {
if (GetPlayerState()) {
if (GetPlayerState()->bDataReady) {
ApplyData(GetPlayerState()->GetData());
} else {
GetPlayerState()->OnDataReady().AddDynamic(this, &ThisClass::ApplyData);
}
}
}
void ASomePlayerState::DataReady() {
bDataReady = true;
OnDataReady.Broadcast(Data);
}
Ok so another approach might be that an early object has a registration function and when someone shows up, they register and trigger a check. Last one to the party starts the show.
Yeah
In C++ you can also try to make this work with a shared Onrep function
But again, depends on A,B,C
In C++ multiple properties can use the same OnRep functions
So you could put all 3 onto the same, and when OnRep calls you can check if they are all ready
Epic does something like this in UT
Yup, that's how I usually do it. Because whilst at the start it might just be two places that need to be syncd up, later down the road more can join the party, without a bunch of code needing to be refactored
Well something along those lines, you get the idea, the rest is just an implementation detail
Can you use Dev Auth Tool to login with two accounts on the same pc for testing multiplayer?
2 standalones used to work - .uproject, launch game
PostNetReceive might be less confusing
Im using eosplus and doesnt seem to work for me
Yes you can, that's one of the big advantages
You can test your MP locally with two accounts on a packaged build
Awesome, thanks
If you load a character from not relevant to relevant, it essentially loads it like it was just spawned on that client right? Meaning, through construction and begin play?
That depends on how smooth you want the game to be. Typically, ultrarealism games fire bullets from the muzzle but most other game dont because itβs too clunky
I say spawn at muzzle always.
I believe construction scripts never run on network clients, but the Begin play will run every time it becomes net relevant
Firing projectiles from the muzzle also has some unusual implications for how your reticle needs to work
If I was in that position, I would have my reticle be a three-dimensional object moved around the world through line traces from the muzzle
Yes - the actor is actually replicated to the client again as the actor is destroyed on the client once they lose relevancy. Begin Play definitely fires, but not sure about construction script.
why is the projectile movement comp deemed bad in multiplayer games?
I don't think it's bad, but it's probably not sufficient on its own.
It doesn't handle anything about replication itself so clients desyncing due to lag or otherwise are going to see the projectiles rubberband all over the place.
prediction wise?
or performance wise ?
Prediction.
If you have thousands of simulated projectiles you're going to have perf issues but not because of this component specifically.
I still couldnt solve what that Interp thing does in projectile movement comp
I always make it lerp by myself to prevent rubberbanding
so then the rubberbanding is because of movement replication syncing ?
yes
if so then could not replicating movement and doing it all locally work ?
sure, until a client desyncs because the simulation isn't deterministic
for something purely visual and only lasting a brief period that'd be fine
if I use my own custom and simple logic it could though ?
desync between client and server is a fact of life, you're not going to logic your way out of it.
as I dont think anything moving that fast needs to be accurate
I cant completely have them in sync
as I said, for something purely visual and only lasting a brief period of time it'd be fine
but I can use latency or the gamestate's time to start projectiles from different points in time
thanks
wait so if u dont use projectile motion what do u use
If you want to smooth the location store the client transform on OnRep_ReplicatedMovement and lerp to actual transform on tick
For grenades or slow moving things you might need to smooth it
tbh I might just use smooth sync for grenades
projectile movement component is fine - but it isn't sufficient in and of itself as it doesn't resolve differences between client/server positions.
Eh.. I wouldnt
or anything I dont expect to move at infinity mph
Again, you can use projectile movement just fine. But you need your own logic to resolve differences from the server.
PMC is great if it's a server auth logic
Custom solutions are great if its purely visual thing or if you are having perf issues
1200 RPM SMG has entered the chat
Smooth sync should left the chat π
its for grenades only
Ah, gotcha
What 1200 RPM equal as fire rate? π€
if velocity, actor move
0.05s?
yeah
sorry, i have an event dispatcher in a controller class, and i'm trying to bind to it in a level class, but i get Warning: UNetDriver::ProcessRemoteFunction: No owning connection for actor...
what actor? it throws that just trying to print a string, but isn't that sort of the standard way to do a RPC?
is it because i put the event dispatcher in the controller and not the character?
Depends on your game design. I would use the same approach as 3rd person games but of course your shoot direction will be closer aligned to your view direction than a true 3rd person setup.
You can even not use actors
Spawn projectile = add struct to array in a subsystem for me
PMC is ok but idk why the hell they don't have an option to use line traces instead of shape sweeping for pointlike projectiles.
Also I'm pretty sure they use Euler integration so ew
if you want the most predictable projectiles for sync reasons you'll want to use Verlet but if you have any drag simulation you'll still desync a bit the longer the flight times are. If you have no drag and just constant gravity, Verlet is perfect.
You wouldn't happen to have something I can reference on how to distinguish between the two accounts?
That message is an indication that you're trying to send a client->server RPC on an actor that is not owned by a client.
Like normally a player can RPC through their Player Controller, their Possessed Pawn and their PlayerState as they are all owned by the client's controller. They can't send RPCs on other actors that are not marked as owned by them.
i guess the thing i don't understand.. i'm not trying to call an RPC on another actor, but on the server?
like i have this procedural generation, and it works great if i hook it up to begin play on the level's event graph
i just want to, in dev, trigger that from a client
What actor are you running the "Run On Server" event that allows the client to trigger it?
i've got an event dispatcher in the controller class
An event dispatcher is something completely different. That's something that allows a blueprint to send out a message to other blueprints that bind to that event dispatcher.
If you're trying to trigger something from the client on the server, you need an Event (not an Event Dispatcher) that is set to "Run On Server".
oh gotcha, the event is in the level blueprint
Ok, so if it is, the player doesn't own the level blueprint.
right
You'd have to do it from the player controller, their character or player state. Player controller probably makes the most sense.
the thing is.. you get what i'm saying, i just want to manually set off a server event
it feels super weird to do procedural level generation in a player class ?
It's not about doing the generation in the player class.... It's a matter of you are wanting to send a message to the server, you need to do it through an actor owned by the client.
The generation can take place anywhere once you're on the server.
the tutorial i was following used the event dispatcher to do that
the server catches the event, it just refuses to actually run it
with the No owning connection for actor... message
sorry, thank you for chatting about it
Any input from a player is always on the local machine. When you do a keypress of any kind, it's 100% of the time running on the client.
The only way you send a message to the server, is through one of the events that I posted above - one that says "Runs On Server". however, it will not execute on the server unless that event is being called on an actor that is owned by the client. The level blueprint is not owned by the client, so if you're calling a "Run On Server" event on the level blueprint, it will never work.
What you can do is put the "Run On Server" event on the player controller - an actor that would be owned by the client. What you'll have trouble with is getting that signal back to the level blueprint. This is where you could potentially use an event dispatcher to communicate to it, however, your level needs to be able to bind to the event in the player controller instead.
Event dispatchers do nothing in terms of networking. All they do is trigger a signal from one class to any others that are bound to it. If you trigger an event dispatcher on the client, it'll only ever trigger what happens next on the client's version of the actors. If you trigger it on the server, it'll only ever pass the message along to any of the server's actors that are bound to it.
you're just repeating yourself, i understand this
" your level needs to be able to bind to the event in the player controller instead."
how do i do this
i understand, how the heck do i bind to an event that comes from a player
Well, since you're trying to use the level blueprint, the dirty way would be to do a delay of a couple seconds on the level blueprint's begin play (time to allow the player controller to exist) and then again dirty way is get player controller 0, cast to your player controller class, and bind to the dispatcher on it.
that's what i did, it does not work
it gives the error message
the warning, i should say
Post your code.
the delay doesn't seem to actually impact anything that I can tell
i get that it's something about binding to the event here instead of the controller
but i don't get how i can bind to the event in the controller and get to the level
i guess
It's about where the event is.
I press button on my player controller. My player controller reports to server. Server passes along event dispatcher message to level blueprint.
Yours is currently (probably):
Press button on player controller > sends along event dispatcher to level blueprint which receives message and attempts to report to server, but it cannot because the client cannot RPC through the level blueprint > attempting to do the thing but it cant
does the thing you pasted actually work
Yes
i will study it.. i do not see the difference
your level blueprint and mine are the same except for the delay, and your event dispatcher being on a character instead of a controller
how?
fuck dude can you just show me instead of making me squint
that's what you have?
you bind to the event
bind event -> event
the target is my controller class, yours is a character class
That's not the issue. Do you not see how yours says "Executes On Server" and mine does not?
My "Executes On Server" event is happening on my other class that my client owns.
Yours is happening on the level blueprint which your client does not own.
you have it labelled "Level Blueprint"
this is my controller
this is a joke, nevermind
Yes, that was my level blueprint. On my level blueprint, the event dispatcher is NOT calling an event that says "Executes On Server".
We're communicating about these two events. They are not similar.
is your event actually running on the server?
Yes
so to get it to run on the server, after all that, you're telling me that I need to specifically uncheck the box on the event that says "run on server"
That is part of it yes. The other part is you need to call a "Run On Server" event on your character that triggers your event dispatcher.
dude.. i have been trying to explain to you, that that works, it frigging WORKS
that is not what i'm frigging asking
what is this community
I'm sorry that you are failing to understand.
so how do i replicate this event to clients now that i have turned off replication to get it to work
i seriously give up, never mind
i am walking away from the computer
this is insane
You turn replication back on by putting a "Run On Server" event in your character that executes your event dispatcher. If you have more questions, please feel free to ask.
I didn't find it confusing actually but yes, also a way
how might one achieve a fog of war
like moba style
could i just erase something depending on a collison sphere, then unrender anything with specific tags not under that?
is there a better way of doing it?
if a replicated property is exposed on spawn and set when spawning the actor, is it a guarantee that the value will be included on the client when they run BeginPlay? (i.e. is there a chance BeginPlay runs before the property has replicated and has the default value instead)
no, on client Actor spawns -> replicated properties are set -> OnReps are called -> PostNetInit -> BeginPlay
what do you mean by distinguish?
so it is a guarantee?
guarantee as far as one can possibly make it
ok cool thanks
we had an engine bug that had replication part of that not run once
interesting
I'm getting some occasional strange bugs when someone joins a server that already has a bunch of people in it
trying to figure out if there's some sort of replication race condition
on release day, on an actor that is responsible from keeping map in sync...
welp that's unlucky
and only if the host changed any map settings before client joined the lobby, otherwise worked fine
but yeah
you have to take it as a guarantee
as there are so few of those around
other one is GameState having fully replicated before any Actor calls BeginPlay on clients
you're saying this is also a guarantee?
I saw this comment from some guy on youtube that has me slightly worried:
"The problem is that everything seems to be replicated pretty chaotic from the server to the client. Something can be replicated before something else it depends on. Even the NetDriver can be nullptr on the world object in a replication notification. I used World->GetNetMode don't referencing it from the world works, you can't expect the world to be initialized on replication. You even can't expect BeginPlay was called on an actor before it's properties notifications are replicated. It gets very messy to fix this all. Basically you need checks everywhere if stuff you need is already initialized and if not save it for later."
he is wrong
Uhm, yeah XD
server doesn't replicate to clients before they have a valid world
Because actors live in a world
Understanding the bascics of UE4 is kinda important
before doing Multiplayer
Otherwise it's easy to fall for the messages of doom from false prophets
yeah he's saying it was causing crashes when people joined a server sometimes
π
do note that any component member replication is not covered with the above guarantees
I guess he just misunderstood the bug and accidentally fixed it in a way that he also didn't understand
XD
even though they use same ActorChannel to replicate
right
you do have more problematic setups
where while your pointer to say, PlayerState will get replicated before your Pawn's BEginPlay
the PlayerState Actor itself will not
so you have a valid NetGUID, but it can't be resolved
yeah I think I've seen several similar sorts of things
OnRep will fire when it is resolved though
above example is pretty much guaranteed if your level is not empty
Pawn's NetPriority is 3 by default, PS has 1
Pawns will come first
although i do recommend raising PS NetPriority, makes initialization run smoother most of the time
NetMode: Play as Client
Quantity: 2
This works as expected
prints out Client 1 and Client 2
But this one is baffling me
prints out Client 2 (where is Client 1?)
You're not showing the logic that calls the RPC
You're most likely calling the RPC on an actor on client2 that is not client-owned, so it executes locally only
it comes from a State in a State Machine from Logic Driver plugin where all settings for the SM is set to Server only
That's very vague, again, wherever it's being called from most likely lives on client2, and it's not client owned
so the RPC is executed locally and then that's that
Without more concrete information the diagnosis doesn't change
Also I haven't used that plugin before
ah lemme get the actual bp, i made those smaller screenshots so its easier to post a shorter question but i think i may have introduced other issues
GetDJCharacter -> gets Client 2's character BP
StartPerforming -> sends RPC to owning client (Client 2) to do DJ stuff
StartObserving -> sends RPC to everyone, so that they get the DJ's actions
The issue arise here, where i actually get Client 2 only with this BP
(if i remove LocalPlayer it has printouts, but thats not what im expecting, i'm expecting Client 1's PC to print out a statement because he would be a local player on that PC)
Is it possible to use the Steam OSS with a dedicated server and client running locally? I can test it fine using NULL OSS, but with Steam it fails to connect. I'm not using Sessions or Lobbies
When is all of this called?
Is it a chain of events that's called at BeginPlay or later during play?
Later during play.
It is called when it enters Performing state in the State Machine.
And it enters Performing state after a series of events
- character opens Sign Up UI to enter a queue
- character Registers as DJ
- server state machine recognizes that player array is not empty and moves from Idle to Waiting to Performing states
also note i edited my previous post after running more tests (from NOT printing at all, to only printing Client 2)
What was different when it wasn't printing at all?
possibly human error, im sure i clicked compile after doing some changes, and even has green tick, but after recompiling again it shows Client 2 (which is consistent with the issues im facing)
how would you replicate UI animations to all clients?
through playerstate, playercontroller, interface, gamemode?
I use c++ but I think you need to use the normal replication function client-server in bp
This looks like it's lobby logic. You have an RPC in the lobby playercontroller/pawn that calls an RunOnServer RPC that then calls a MulticastToAllClients
Or whatever client-owning actor you want to have the RPC logic on
Being mindful that PlayerController only exists on the local client and for all on the server, so you can place the RunOnServer RPC there but need the Multicast RPC somewhere else that exists for everyone
so i have a TArray<UJob*> where UJob is a UObject. i want to replicate it but i just found out it crashes and i cant really find any helpful stuff where its crashing since its crashing inside of unreal PackageMapClient.cpp:2601 with Exception thrown: read access violation. Object->**** was 0xFFFFFFFFFFFFFE2F. heres the call stack https://pastebin.com/9Hm5RvsP and heres the calling code. ive marked where its crashing with >>> ```cpp
void ASBPlayerController::ServerInitPreference_Implementation(FPlayerPreferences preferences)
{
UE_LOG(LogPlayerController, Verbose, TEXT("Recieved preferences from client"));
/// TODO validate and probably dont send the entire preferences, maybe make a new struct with the essentials.
PlayerPreferences = preferences;
const TArray<UJob*>& jobs = GetGameInstance()->GetSubsystem<UJobGameInstanceSubsystem>()->GetJobs();
UE_LOG(LogPlayerController, Verbose, TEXT("Sending jobs to client (%s)"), *FString::FromInt(jobs.Num()));
ClientInitJobs(jobs);
}
void ASBPlayerController::ClientInitJobs_Implementation(const TArray<UJob*>& jobs)
{
UE_LOG(LogPlayerController, Verbose, TEXT("Received jobs from server (%s)"), FString::FromInt(jobs.Num()));
K2_ClientInitJobs(jobs);
}and heres where its crashing in the generated code
static FName NAME_ASBPlayerController_ClientInitJobs = FName(TEXT("ClientInitJobs"));
void ASBPlayerController::ClientInitJobs(TArray<UJob> const& jobs)
{
SBPlayerController_eventClientInitJobs_Parms Parms;
Parms.jobs=jobs;
ProcessEvent(FindFunctionChecked(NAME_ASBPlayerController_ClientInitJobs),&Parms);
}``` anyone know whats going on with this?
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Is it something specific to the Pawn for OnRep_PlayerState to run on client only and not Server? I believe if I define a variable with UPROPERTY(ReplicatedUsing = "OnRep_FunctionName") the OnRep_FunctionName would be called on server, simulated proxy and autonomous proxy of the actor, right?
They only ever run on the Client
OnRep callbacks never run server-side, apart from in Blueprint because Blueprint is stupid
And they aren't really OnRep callbacks (in BP)
Ok so the pipeline would be something like: "Ready button clicked"-> "Calls RPC on the playercontroller" -> "Calls gamestate multicast"?
so i think there is several problems with my code and none of is it what i actually posted. nothing in UJob is marked as replicated and it does not have a GetLifetimeReplicatedProps override. ive added both of these, but now i have the problem where no actor owns these jobs as they are created for, and owned by, a subsystem. am i able to replicate these at all? or should i just set them on the PlayerController the replicate them that way?
@plucky prawn: https://jambax.co.uk/replicating-uobjects/
TL;DR, the UObjects have to be replicated as a sub-object of an actor
Or network-addressable
No, subsystems can't replicate anything
ye big sad
So it's common to spawn a proxy actor to handle that
// AMyCharacter.h
UPROPERTY(ReplicatedUsing = "OnRep_TestNotify")
int32 TestVariable;
UFUNCTION()
void OnRep_TestNotify();
// AMyCharacter.cpp
void AMyCharacter::BeginPlay()
{
// Call the base class
Super::BeginPlay();
if (GetLocalRole() == ENetRole::ROLE_Authority)
{
TestVariable = 69;
}
}
void AMyCharacter::OnRep_TestNotify()
{
ENetRole role = GetLocalRole();
if (role == ENetRole::ROLE_Authority)
{
UE_LOG(LogTemp, Log, TEXT("Server notified"));
}
else if (role == ENetRole::ROLE_AutonomousProxy)
{
UE_LOG(LogTemp, Log, TEXT("Client notified"));
}
else if (role == ENetRole::ROLE_SimulatedProxy)
{
UE_LOG(LogTemp, Log, TEXT("Proxy notified"));
}
}
I'm able to see both Server notified and Client notified on the output log when I test this. Is there something I'm getting wrong? When I use the same Logs on overridden OnRep_PlayerState I can only see the Client notified
Yeah something is off there
A more definitive test might be to use GetWorld->IsServer() instead of Role == Authority
Using Steam Advanced Sessions plugin - Specifically Advanced Voice.
What is the difference between a Remote talker and a Local talker?
What is easiest way to get reference to self after anydamage?
like it takes server
ENetRole role = GetLocalRole();
if (GetWorld()->IsServer())
{
UE_LOG(LogTemp, Log, TEXT("Server notified"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("Client notified"));
}
Welp, this now gives me two Client notified, I'm more confused
Where in the CMC could I reliably reduce and increase a float variable so it stays in sync?
PerformMovement or so?
Will try PerformMovement
Are you sure you're playing a networked game in editor? I.e. launching a server and client not two standalone?
Yes I'm running PIEs on net mode Play as Client. I tried both with IsServer() and GetNetMode() == NM_DedicatedServer but in both cases I only get logs that indicates the client, even though I have a dedicated server and PIE client(s)
Wait, if I run 2 PIE sessions I also do get Server log for PlayerState with GetLocalRole() == ENetRole::Authority check, not with a single PIE
I'm honestly lost here, I was just trying to learn GAS and on a tutorial I heard ".. OnRep_PlayerState() runs on clients only.. " and wanted to see how they do the logic since to my knowledge OnRep functions should run on every device that have the actor
No the way it works is that OnReps only ever execute on a network client
Because they are called from the replication system when a property is received.
And never at any other time
Which is why it's sometimes common to call an OnRep function manually after setting a value on the Server
Blueprint confuses this because it calls the "RepNotify" function whenever a variable is changed - it's not even a replication callback, it's just a "fire this function whenever this value changes" callback.
Why Epic felt the need to handle it differently in BP I'll never understand
Wdym by this exactly?
Like you want them to be calculated separately without syncing between client and server?
Can someone point me to some relevant documentation/tutorials/whatever on this? Basically I can find/filter/join my steam dedis as an individual client just fine, but now I'm a little lost on how to implement a party system so multiple players can queue up together and join as a team.
Would the party interface be relevant to this?
virtual IOnlinePartyPtr GetPartyInterface() const
You have unwittingly stepped into a minefield
For the record, there is no default implementation for the party interface for any OSS.
Some people have done parties with beacons, but the long and short of it is you need to do the whole implementation yourself and there's a plethora of ways of doing it that are all game specific
Maybe EOS has something, but I've no idea
Yeah I figured as much, I had to implement a lot myself just to spin up and manage the dedi instances. Finding documentation past this point has been frustrating though
Yeah, frankly there isn't any
Well, at least in some way that's relieving to know. I guess I'm on my own here. I'll look into beacons
CDO - class default object lets you access the default values for properties that are assigned via editor/c++
Otherwise if it's specific values for an instance of a spawned class, then it needs to exist for you to be able to access them
You can always expose access to that data in other ways
Really depends on what the problem is that you need to solve
So right now if I start up multiple games eosplus is being found and then logs in to steam on the first instance. But, the second starts up as null system. My goal is to be able to test inviting friends, EOS voice chat, multiplayer sessions that requires two computers and two accounts.
How to make this work? I want spawn chest when player dies and use player inventory. In any damage event that "DeathLoot" is from server and not from player who recently died. How to fix that.
So player who died have proper have "DeathLoot" variable but server didn't die and it takes that variable from server? If I print that variable in loot actor its empty but if I put print it in "SetDeathLoot" it prints correct.
When dealing with multiplayer, the instance of the object you're working with usually both exists on server and client. Depending on whether your code is being run on the server or run on the client is what determines who's (servers or clients) instance you're manipulating.
Currently, you're running Any Damage which is a server event and that calls the "Set Death Loot" event which runs on the client. When that event is fired, the client will proceed to set their death loot array -- the server doesn't know what that value is since it's running on the client, so when you do your spawn of the "Player Loot" actor, that "Death Loot" array likely doesn't contain anything.
To correct this issue you need to set the "Death Loot" variable on the server itself but that may not be all. I'm not 100% sure, but I think you may require a rework of your inventory if you never set up replication and have been handling everything client side instead of having the server manage it - and I think this is the case as you're using a Map type variable which are not replicated.
@sinful treeSo is there any way to take "self" reference in server event that is not server but damaged client?
When you have a replicated actor in multiplayer, the server and the client have an instance of that actor. It is not about a "damaged client" it is a "damaged actor". A reference to "self" only means the instance of this particular object.
Take the following example. I press a button, sending a reference of myself to the server. It then checks if my value I passed along == "self". In this instance, it will always return true.
When discussing Server / Client in multiplayer it's more about where the data is being executed; whether it is being done on the side of someone playing the game, or on the hosts' side. So again, a replicated actor will exist on both the client and server, they both have a copy of the same thing. If you're wanting others to get a copy of the inventory the character had, then the inventory should be getting managed on the server's side.
okay thank you
I'm thinking how hard it would receive also that damaged actor pin to anydamage. In c++?
Any Damage is executing on the actor that is being damaged.
you could set that input as a variable somewhere
when you create those actors, you could add your parameters to the actor class as a variable
and then you'd have a handle to get at them whenever
oh maybe i misunderstand, if the challenge is getting to those parameters at all
you know.. I too have been grappling with level files
is there a hard reason to not replicate those actors to clients?
i'm kind of in a similar jam anyhow, i am not sure
This tripped me up when I was first converting BP networked code to C++ networked code. 'Twas a bit frustrating personally.
Hey, how can I prevent bot AIControllers to be seamless traveled?
This part of seamless travel handler is the problem
It just checkes whether a AController (can be AI) has a PlayerState and Bots have PlayerState
but I don't want them to travel
as far as I can find, there's no way to mark "Don't Travel" or a pre-travel Filter method to use to remove unwanted actors
that works for server only logic
any tips on how to set the GameNetworkManager that is being used?
I don't know where this is being setup if I want to change it to something else
Is there a way to sync two movement components together? Probably not, but I figured I'd ask.
It'd be a pawn movement component (a ship) and a character movement component (a player walking inside the ship).
Reason why I'm asking is that the depending on the manoeuvres the ship takes, it could move/throw the player around. Of course, both would need to be in sync so that the saved moves finish with the same results at the end.
I think, but I'm not 100% sure, while your pawn is on the ship, you want to attach your pawn to the ship. If they're a certain relative distance away from the ship origin, then you want to detach the pawn from the ship.
But yeah I'm not sure how well that will work with the CMC either ._.
Yeah attachment works
But it's mostly the velocity/acceleration/Gs I need to also be synced
Which won't be just by simple attachment, clients are always gonna be a little behind
Is it normal Cast to "gamemode" fails always when playing dedicated server instead listen server? Wanting to do respawn.
event called from third person run on server event
When you are running a "Executes on Client" event that means it's running code on the client side. The game mode does not exist on the client side, nor should you be letting your client tell the game mode the new transform - respawn should be handled almost entirely server side.
Okay ty! made it work that way.
Is a reason why in the build version on server, this find always returns -1. No problem with PIE.
Inventory is an array of INV_SlotStructure. Initialized all to empty slot structure.
Hey all, what is the best way to get the current session settings (host name, max player count, etc) from a C++ GameInstance class to a BP so that we can update a UMG widget? I tried making a BlueprintCallable function that returns an FOnlineSessionSettings pointer but the code doesn't compile, with error Unrecognized type 'FOnlineSessionSettings' - type must be a UCLASS, USTRUCT, or UENUM. Removing the BlueprintCallable tag allows this code to compile no problem
Is there something like Launch Character which is multiplayer lag friendly* by itself ?
Like something where i don't need to build around the client prediciton
Creating a custom function that returns that info is the best route. FOnlineSessionSettings isn't blueprintable.
Hey Guys, I made a change breaking my dedicated server, but I am only getting an error code 3 in visual studio when I try to run the dedicated server. Running it stand alone, I am running it with -server -log but it just closes right away. Do you have any suggestions to find out what is causing this?
What would I return instead then? Just void? What I was hoping to do was get all of the session settings and select what I wanted out of it in the BP
You'll need to make a custom struct then.
That would work
start debugging directly from VS and launch it there. Also check your logs as it may have info
My dedicated server isn't started since I moved from EOS to EOSPlus. My client builds fine though and I have no issues... Has anyone run into a similar issue? I'll post the stack trace below:
I'm not sure why the dedicated server is starting up and trying to initialize the user interface since there isn't a user involved... hmm
Hello, I'm running multiple client windows in editor -- it seems like they all share the same game instance object, can someone confirm that's true?
If so, does anyone know some way for each window to have its own game instance?
What are the rules if I want to send a TArray<UObject*> through RPC? Do I need the GetLifetimeReplicatedProps override and properties with replicated specifiers? Or will it just send the whole thing as-is?
By UObject* I mean a class I made that derives UObect and the array is of this type so if needed I can add whatever is needed to replicate it.
I think just mark it as a UPROPERTY()
you shouldn't need to replicate to explicitly send it through rpc
Not sure if it apies to game instance but there's a "use single process" setting.
Best would be to testing on multiple computers but also try just launching instead of PIE.
ok cool, yeah I do test on multiple machines with a dedicated server, but it's quickest to dev with a client acting as host in editor
It's also important to know that the earliest class which has replication logic is AActor, so if you only extend from UObject you'll also need to do extra work in order to replicate those objects
Do you build or just launch?
for testing my code once Im done I build dedicated server and client packages, then connect through IP
but as Im deving I find it fastest just to use PIE
You can just launch a dedicated server too. That's what I'm getting at. No build
Sync, launch, done
5 seconds
oh interesting, how do I do that?
say I want a server and two clients using my current code
I don't get it, I'm saving a pointer to the player character on the server, I'm using GetPlayerState but it's null
the player state is
ptr to playerstate?
Yeah, when getting it through the character pointer it's null
Is the character controlled by player?
yeah
Ye I was aware that UObject doesn't have its own replication stuff but I was wondering if it was somehow different if I was sending it through RPC and not "normal" replication
I don't remember if that can be done without the object supporting replication https://jambax.co.uk/replicating-uobjects/
this link helped me with replicated uobjects
Hmm, thats really wierd.
Where are you calling GetPlayerState.
Cuz for example if you call that in beginplay, or prior to character being possess, it will be null.
when the player dies
HodlGod?
I think I turned off replication somewhere in death event lol.
Or maybe character is unposessed.
Unposessed character have no playerstate.
thanks
it only took a few hours
Haha
Are root motion animations safe when it comes to lags ?
I think it will lag
If u really want root motion, enable client side movement in character movement component.
Not finding anything with that name in my CMC.
Also kinda feel like it can't be that simple to fix since i already had to override the CMC with the client side prediction in C++ π
I think its bAcceptClientLocation in CMC iirc
And in that case, try not to use root motion, else you have to do some black magic stuff
Hi
I am using world composition with sublevels, but if server player is too far from client, client falling down through the ground.
Can anyone help?
Am I correct in thinking that if two repnotify properties are updated on the server on the same frame, I can't assume that the client has already received both updates in either onRep()?
I.e. if I want to do something onRep that depends on another replicated property being sent at the same time, I should implement something like a semaphore such that I do the action from one onRep if the other has also marked itself as having completed
Or, of course, combine/serialize the properties together
Hey long time old friend. I literally just found this out today wondering why the playerbame wouldn't show up on the dead body π. Wish I had gotten to you first
Hello, above I'm trying to enable input on the character when the game starts. But only the server receives input. Clients' input stays disabled.
I've tried to pass the player controller with the event with no change
Can anyone help me here?
Ok false alarm, my bad. Client just wasn't updating the mouse sensitivity correctly and was returning 0
correct you can't assume that. What you can do is merging these two variables in the server if possible, you'll get rid of some complexity (atomicity) But yeah you already answered yourself haha
ok makes sense, thanks!
It's like similar to lazy initialization in software dev
guys i am getting this error while tring to join a game through lan
LogNet: TravelFailure: LoadMapFailure, Reason for Failure: 'Failed to load package '/Game/FirstPerson/Maps/UEDPIE_0_FinalLevel''
i am playing this on the editor
on 2 devices
both devices run this game on the editor
Server Seamless Travel doesn't work in editor
If you want to test 2 players in MP with ServerTravel you need to do it on a packaged build
PIE is a second class citizen
ok
is there a way I could see the callstack when a server shuts down?
like what is causing the server to stop running
Check the log file.
Alright, so i faced pretty hardcore network corrections(on high ping) on the client when moving and i found out that this will only happen when the CapsuleComponent of the character is replicated.
Now i wonder if i should just not replicate it
LogNet: Error: UEngine::BroadcastNetworkFailure: FailureType = ConnectionLost, ErrorString = UIpNetConnection::HandleSocketSendResult: Socket->SendTo failed with error 21 (SE_EADDRNOTAVAIL). [UNetConnection] RemoteAddr: 127.0.0.1:17777, Name: IpConnection_0, Driver: PendingNetDriver IpNetDriver_1, IsServer: NO, PC: NULL, Owner: NULL, UniqueId: INVALID Connec I'm trying to play as client but I'm getting this log
it sends me to the default client map instead of the map I have open and I want to PIE
What about just launching?
turned off my vpn and it worked 
first time the issue happens
What's exactly the problem with this mode on the AnimInstance_BP ?
Even with lags it seems to work okayish enough
(Tested with 750 ping on server + client. I also still don't know if i should really do that on both here)
Afaik just packaged, but feel free to test
We test multiplayer with launching but do no traveling at all so havn't had to mess with it
Is anyone actually using the NetworkPrediction Plugin already? I haven't heard much about it anymore. I love the Insights that they have a video of on the readme (I could have used that ages ago when debugging the CMC)
Actually, i take it back. It's not okayish π
Ah, Dave Ratti isn't working, or at least won't work, anymore on that plugin as they move away from Epic. Wonder who takes it over and if there are more updates to come.
Readme says no further big changes coming, just API stuff. Hm
That's... concerning
"Well, we don't need it for Fortnite..."
I'm trying to do a seamless travel with ClientTravel (travel type relative and bSeamless turned on) from MAP_Server1 to MAP_Server2 but the client gets stuck and tries to load MAP_Server1 again
MAP_Server1 running on port 7777 and MAP_Server2 on port 7778
any clue on why it fails?
I can't recall ClientTravel being a Seamless operation
Only ServerTravel
After all you are connecting to a new server, which has to go through the whole login process
the options do make it seem like it's possible -
the logs if it helps, ClientTravel gets called on server player controller
That sucks. F's in Chat π¦
Doesn't seem to have been touched for a good 18 months now
I have
isnt rly ready for anything other than testing i woukd say
Sad
Most interesting for me is the insights and the possibility of linking multiple things together
But well, guess we wait a few more years
Or I code it myself
main thing im looking forward to is the integration with GAS
It was the main thing I was looking forward to
Don't care about lumen or nanite, mass sure, but this more than anything
Feels moderately tone deaf if I'm honest
wow that caught me off guard
all best for Dave, he gave us soooo much. Thank you Dave <3
It always seems the ones who do stuff like this are the ones who leave
Same thing with the ART creator, can't even remember his name
aw, bummer
coughs blood what :\
Im having some trouble figuring out how to have have spawn locations to be relative to the player. Similar to apex or fortnite lobby where your player is always in the middle.
o7 it took 1-2 hours but I didn't expect the code to do me dirty like that lol
<@&213101288538374145>
hmm let me erase the link from that image
so whats the point of a subsystem if it cant be replicated? or anything that it owns (is the outer of) also can not be replicated?
Subsystem = modern singleton
I heard it can be replicated but causes weird side effects
i see
Point of subsystems are they are accessible from everywhere very easily and you dont have to manage their lifetime
ok so.. i have a subsystem which is supposed to be server only (its not right now but thats not really the point), and it owns some UObject types. im trying to send the TArray<Ubject*> over RPC to a player controller but its crashing. i tried following Jambax's guide for replicated UObject but its still crashing, and i think its because the subsystem owns it and not an AActor
i could try to shoehorn in some kind of ownership of the subsystem but it doesnt really make sense. i just want to send some stuff over rpc :(
hi. whats the difference between steam subsystem and advanced sessions? are they the same? I am still confused in setting up different of ways to connect to steam. thank you
advanced sessions is just normal sessions with.. advanced options? it exposes more of the C++ api to blueprints so you have more control over how your session is created
steam subsystem afaik exposes steam api for your sessions so you can use it for multiplayer
someone else might have some more details on the difference but i think thats the gist of it
thank you will read more of it, just finished some basic replication tutorials and I am in the point of learning connecting to steam.
May I ask if I have 1 to 4 player multiplayer game that I just want to have it via listen server, whats the easiest way to setup and play this game on steam given my basic knowledge on replication.
no problem. just create a session and people will be able to connect. you will need a steam_appid.txt to use steam though
alright will need to learn more. thank you π
One way I can think of is by having the the local client spawn in characters instead of relying on the server to spawn in characters for each player. This also has the benefit of not having possessed characters. Then it's just a matter of doing management of each character on the local client. Any data that needs to be replicated about the character (such as the appearance or name) should be replicated through the player state using OnReps and then locally you can manage which playerstate belongs to which character and update anything about the character required.
I'm fairly certain you can use "begin play > has authority > local >" on playerstate to know when a player has joined the lobby. To have only your player spawn in a certain position means you do a check for if the owner is valid on the playerstate - if it is valid, then that's your player state and you can spawn the character at the "center" spawn point you want to use, if not, it's not your playerstate and it should spawn in the first open "other" spawn point.
That totally makes sense, thanks so much
when actor relevancy is updated ? is there any interval ?
Tank spotted in the wild
You have to use an actor proxy - there's no alternative that works properly. The outer of a replicated object has to be an actor for complete stability.
I do something similar for my command system. There's a command manager world subsystem, and it has a data actor which handles data replication.
Thank you for confirming this. Is there a good design for what I'm trying to do? Or should I replace the subsystem with an actor?
Oh I see
Depends what it is I guess, but there's nothing wrong with having the subsystem-actor combo
So the subsystem spawns in its own proxy actor which owns all the replicated objects?
yeah
In my case I have an actor per-connection, but only because I want per-connection specific data from it too.
The gamemode notifies it when players login to create the replication proxies
Ah I see
I think I might have needed something like that originally since I wanted to replicate to specific players on login, but I've reviewed my situation and decided that it doesn't matter since my jobs don't change at runtime so why not replicate them normally
You can ofc always just use an actor as the "job" object instead and spawn those
Ye true. I figured actors had additional overhead and they really don't need to be spawned into the game so I figured UObject would work better
But I'm starting to think I have no business using UObject and I should use AActor for everything and disable tick
They have a little, but the advantage of this method first and foremost is you only need to consider one of those jobs for replication if it changes.
If you replicate them as subobjects, every single one has to be checked each time
- you can disable replicated properties you'll never use
Oh very nice
Sorry, are you referring to your method when you say "this method"?
You have more finely-grained control this way
Yeah
Using an actor just means you can get fine-grained control over the replication of each one. Whereas if every job is a sub-object, they are all locked to the replication properties of the owning actor.
Similar to how components are
yeah they would have to be
otherwise they won't resolve properly, or at the very least, they would have the wrong outer on clients. Client-side they will always use the actor as the outer.
I see
This is way more confusing than I anticipated
I mean not now, you have cleared it up very nicely thanks
I'm pretty much coming from garrys mod where I could network whatever, whenever.
yeah UE's quite different no doubt, but for good reason a lot of the time
Ye fair enough
So I've been using UE4 for like 4 years now, and I still don't know what BP 'Component Replication' actually does. According to docs, it replicates the BP component, but through all of my testing it doesn't replicate anything more or less or have any effect. E.g. what effect does this have on the Character Movement Component (CMC), as it replicates automatically?
Actor Components can replicate properties and call RPCs just like an Actor can. The component itself needs to be set to replicate, and it's owning actor needs to also be able to replicate. It's restrictions and use identically follow it's owning actor's rules.
Uh, any idea why a root motion animation would play super fast on the client when lag is on ?
All the other animations from the AnimBP are still normal even with high lag
@kind star the thing with the CMC is that it's using the character for the rpcs and has no variables it replicates
Ah ok, thanks. So if the component has network functions it will allow those to be called using the player controller's connection to the server? It would be nice if those properties that replicate would be spelled out better in the engine, so far everything I've ever tried to set on a component do not replicate. I can work around it, but just one of those things to wonder x)
Thanks Cedric
@kind star FWIW it does this because replication on components incur the extra cost of a byte to identify which component on the actor is replicating (UE routes all RPCs through the actor in the end, Epic are just optimizing aggressively because of how heavy CMC is)
Easiest way to consider it is that ActorComponents are just an extension of Actors. If your actor isn't replicating, the component won't either regardless of how it's set up. If the actor cannot RPC to server, then neither can it's components. If the component or it's actor isn't replicating, the component won't received replicated properties even if set from the server, etc.
that smol meow is u π
with a sniper rifle
that meow was my profile pic for the longest time, whilst noscoping people with the AWS in CS 1.6
im really confused on how making a float such as mana get set by the server for the client
cpp or bp im just like lost
so uproperrty(replicated)
and thats it??
or do i have to make a function that tells it too
That's all you have to do .
There's various things you can do to change the details and events, but that's the basics.
wait thats all. i just make var replicated. thats simple
LNK2001: unresolved external symbol "public: virtual void __cdecl Ucppcharhelper::GetLifetimeReplicatedProps(class TArray<class FLifetimeProperty,class TSizedDefaultAllocator<32> > &)const " (?GetLifetimeReplicatedProps@Ucppcharhelper@@UEBAXAEAV?$TArray@VFLifetimeProperty@@V?$TSizedDefaultAllocator@$0CA@@@@@@Z)
im assuming thats what u mean
ok so i need to use bReplicates=true
that too
does that work in a character component or is it finnicky like a timer
There's no need to be ashamed! It's not the size that matters, it's how you use it
π
It' s almost like there's a manual, siliex.
thats what she said
And then you laughed and linked this? π
https://www.youtube.com/watch?v=f488uJAQgmw&ab_channel=KollektivetTV2
Music composition and production/lyrics/performance:
Fridtjof StensΓth Josefsen
Jakob SchΓyen Andersen
Mix:
Rudi Simmons
Directing/Editing
Mikael Samuelsen
Online/Visuals
BjΓrn Amundlien
Managing Editor
Marit StΓre Valeur
Se Kollektivet hver fredag kl. 17:55 pΓ₯ TV 2!
Programmet ser du ogsΓ₯ gratis pΓ₯ TV 2 SUMO: http://webtv.tv2.no/webtv/sum...
i cant figure this out
according to this doc all i needa do is this
but then i get something about dll linkage
LNK2001: unresolved external symbol "public: virtual void __cdecl Ucppcharhelper::GetLifetimeReplicatedProps(class TArray<class FLifetimeProperty,class TSizedDefaultAllocator<32> > &)const " (?GetLifetimeReplicatedProps@Ucppcharhelper@@UEBAXAEAV?$TArray@VFLifetimeProperty@@V?$TSizedDefaultAllocator@$0CA@@@@@@Z)
so instead of AActor * Owner
would I do UCppchrhelper * Owner
It doesn't need to be called owner
that's just an example of something being replicated
ok so whats before the *
?
is that what i want to replicate
AActor* Owner is just an example of a replicated property
and then what goes after just a reference?
ye
AActor* Owner is just an example on that page of a property that is replicated
apply what they did to that property to yours.
it's marked with UPROPERTY(Replicated) so do that to your property
they added a function named GetLifetimeReplicatedProps and put some code related to the property in it, do the same with yours
is this just an intellisense thing or actual build error
where are you getting this Owner thing from
is that what ur tryna say?
this is quite the level of Not Getting It
the docs
?
No, the docs do not say anything about that.
it doesn't say ANYTHING in the docs about this, AActor* Owner is a property
float Mana is a property
o
ok this makes more sense
ahhhhhhh now i got it
im sorry bout that. that was dunmb
when i run the editor now it gets stuck at 75
what is that anything to do with anything we've discussed here
cuz it just happened now after the changes?
stop tagging me
also look at your C++ constructor
you're probably doing something dumb in it
I mean, the bit you posted before here isn't right either
SetIsReplicated isn't static
my b
Is it possible to replicate an RVT, or perhaps the drawing of an RVT? I need all players to have the same RVT texture data
Actually it appears to work just fine as is, sweet
edit: nevermind, with more than one client it doesn't work, hmm
anyone in here have any experience with overriding the base character movement component to be smooth over time instead of instant in multiplayer? Trying to figure the easiest/best way to do this that isn't super ugly
If I set an audio component to replicate (the component specifically with the actor also set to replicate) and a new player joins as the audio component is playing, will the new client update the audio component on their end to match the current audio's position of everyone else?
Edit: or is that redundant?
this is not something you'd ever need to replicate
I wouldn't be surprised if audio components are not even spawned on dedicated servers
any reason why client health is now showing grey but server health is fine ? the health variable is replicated.
Hey guys! Do any of you know how to setup a basic advanced sessions system? Or have a template I can use for my game?
What is a basic advanced session
Thereβs a plug-in called AdvancedSessions
I need a basic system for creating and finding servers
4.72
Itβs wayyyy simpler in 5
Basically this is the same nodes
Iβm still at beginner stages
CreateSession JoinSession FindSessions
Itβs that simple
All these OnlineSubsystem plugins do is change the transport layer from steam to oculus or Nintendo or LAN
The API is the same
Itβs like 5 minutes in UE5: https://blog.unrealcoach.com/posts/steam-ue5/
Basic Steps to Integrate Steam with UE5
i could litteraly do this in 15min at my skill level and Iβve been watching long multiparty tutorials .-.
also sessions is #online-subsystems
Is there a way to make it so itβs 8 players connecting to a session and no host that can play?
Shameless self promotion Iβm available for coaching if youβre wasting time with videos DM me
You want dedicated for that
Gotcha
Not significantly more complicated but does require more thought
Fair
Hopefully after that all I gotta do is fix the actual pvp and make teams and ranked modes etc
I got alot to do .-. I should make a trelli
well you're talking about a lot of things there, since with ranked modes you'll probably need some backend infrastructure to track that
seriously scratching my head i cannot figure out why this has stopped working
this is giving me flashbacks to so much stuff rn
i know its likely some really simple and right in front of me but i just cant see it
well without context, it's impossible to know what I'm looking at
The health
Context
well that's like 5% of the overall context
how is the health managed? how is the UI updated?
Yeah this could be 90 things
my apologies yes it is the health variable it is replicated and was working but after tinkering with the round timer it no longer seems to show on client
oh damn, BP. but why are you using this in a multiplayer context?
i worked before so i didnt see an issue what would be a better way ?
well this will just get the first character in the world, regardless of if it's actually you or not
at least UMG widgets have this
i just tried switching out the get player character for the get owning player pawn but didnt make a difference
Hi! i'm trying to test my dedi server with a friend with hamachi/zerotier but i'm having troubles
does anyone know if there's a standard change required in order to connect with a vpn?
well at least it'll be always getting the correct pawn
thats true just a pain its not showing on the client.. adding the HUD to the viewport is handled in the gameplay PC so i dont understand why it is not showing correctly
well debug it, it's not even clear if it's a UI or replication issue
disable your antivirus, in hamachi you can see if the clients are connected
RPC to spawn the HUD is a bit overkill
you can create the widget on beginplay why rpc?
i have just done a print string for the health variable and it is only showing the server
No antivirus or firewall on the pc, i'm gonna try with radmin. With hamachi we can't even ping each other
once I did that, I just needed to disable the antivirus, I tell you this in case you are not sure if hamachi works
How is a sky heavier on replication than a character? And whatβs with the ugly font rendering as if you disabled cleartype in windows
should you replicate sky in the first place?
Depends if thereβs some kind of authority on time of day and weather conditions but it still seems excessive and it replicates at 60Hz
I used radmin and it worked in a sec, no modifications needed. Just anyone else needs it, radmin works like a charm
it's the ultra dynamic sky, it has the day/night system enabled
that's why I'm asking if it's good
Yes but itβs still using an excessive amount of data and a high update frequency to do it
One of the pitfalls with buying marketplace stuff
okay, I'll set the update frequency at 10
and I'll test
are the values fine for the character?
Probably until it isnβt, just the sky stood out like a sore thumb alongside the ugly fonts
Thatβs some Windows 95 font rendering
okay, yeah
I think is fine now
there is a setting to synchronize the bp with the clients, but that didn't change the values
are the other things fine?
I also saw that I should limit the server fps, something like this: [/Script/OnlineSubsystemUtils.IpNetDriver]
MaxNetTickRate=60
NetServerMaxTickRate=60
LanServerMaxTickRate=60
NetClientTicksPerSecond=60
bClampListenServerTickRates=true
MaxClientRate=10000
MaxInternetClientRate=10000
Is okey to start optimizing while still on bp?
what do you mean with still on bp
oh sorry, i tought that was on bp
I mean just design it to not have horrible perf to begin with. Make the game, and make stuff faster if it has to be.
Can I link player data to steam id
--
Has anyone lately made some sort of gametimer (ticking down) that is properly synced? I usually have a very naive version where I just sync the value every 10 seconds and otherwise let everyone count down via a looping 1 sec timer.
But that doesn't really take ping into account
I just want to confirm I get the concept correctly, if I increase the NetCullDistanceSquared on my PlayerState and decrease on Character, I can get attributes on PlayerState from the defined distance while Character and visuals are not replicated/visible on my local device, right?
PlayerState should be always relevant
Oh, yes it is by default. So I don't need to play with NetCullDistanceSquared either, I can just reduce the Character to prevent unnecessary replication over distance and still be able to check it's health, team, any attributes etc. right?
Yes
Got it, thanks
Send a timestamp instead of an ever-changing value, and make it relative to a globally synced timer like the gamestate::serverworldtimeseconds
(Or a better version of the latter)
It's not -that- bad it just doesn't account for ping π
That ServerWorldTimeSeconds, in the past, have turned out to be really off
Yeah, I rolled my own timer in the end to do prediction etc, and just drive everything from that
I basically just need a straight forward setup of a timer that counts down. May it be 5 second countdown before the round starts, or 120 seconds of the whole match
I would just use the game state timer. That's what we use in HLL to sync some things and it's been fine
It doesn't really matter factoring in ping, because everything else that happens will also be delayed by ping
And how do you set/reset it?
Right now I basically have a repNotify var that overrides a local timer var
And that local timer var is counted down
I'd just poll it repeatedly
Every 10 seconds the Server sets that to resync
Whatever UI element is showing it can just poll the values, so it handles the timer resyncing all the time
Fairly sure that's how I did these timers: https://youtu.be/4cb8nUyyR2c?t=47
The UI element is doing that anyway, or rather it's ints, so I can just update it every second
It's more about the sync between server and client
If you want to be more exact you can give every client a local delta based on their ping
Not sure how much precision you want here, but that'd be one approach if you want more
I mean, let's say it's a 3-2-1 countdown. Would be nice if the game wouldn't start at -1 visually
This also factors into account if the timer matters a lot that the local actions they do will still be picked up by the server, rather than the round timer being over when they arrive at the server
1 second delay is unrealistic, but it does feel a bit mΓ€h for the client
James timer in his small game looks way more synced
GIven that's a client?
It feels like it properly starts when the timer hits "0"
Can't remember if that's a client or not now
!
But if you think, the match transition is also going to be behind by the same ping factor
So it still feels very close to perfect even if it's not dead-on
Yeah I understand what you mean
I still have issues with such a timer in terms of setting/resetting. Specifically if it's driven by OnReps
If that OnRep is set to the same value twice it won't call
(which is funnily enough a bug in UT)
Ahh, I do that by integrating both the timestamp and match state together
So you send a struct when the timer is set?
Although, in theory if the timer is a timestamp, it'll always be a different value
So a future timestamp?
yeah
Current + 120sec
yeah
And Timestamp is GameServerSeconds or w/e it's called?
yeah so instead of comparing to local world time, just use the server world time from the GS
Because it's a fixed timestamp in the future, it sort of auto-handles that value resyncing all the time
Okay, yeah I tried to avoid that cause I have really bad experiences with that. It was way off in The Ascent for whatever reason
I think that's how I dealt with it there anyway
But I know in HLL, we use that timer to deal with our ability timers, like planes flying over etc.
I think I used it for a timer on the Drones, to count down how long they still have
But I think I used it to account for ping
Which might have been the bad idea
Those are synced with that timer then a little bit of interp to stop them snapping around as it updates
E.g.
float timeRemaining = (RepStruct.TimeRemaining - (ServerTimeSeconds - RepStruct.Timestamp)
Something something, don't know if that line of code makes sense
But that way probably a bad idea
yeah I see what you mean
The idea was to say "Server started 10 second timer at timestamp 2000 and we are at 2005, so the timer is only 5 sec remaining" but that broke quickly haha
Yeah mine was End Timestamp + Length
relative to GameState::ServerWorldTimeSeconds
(or some other synced timer)
How much did it explode by?
Given the duration of a few seconds, it felt really stupid
I think the trouble is if you use the starting timestamp, if the timer is out-of-sync by some factor when you start it'll always be out of sync by that factor
Whereas using the end timestamp it sort of "hones in"
Cause the timer was sometimes over for a while, like 2+ seconds, or still going on and the drone died
And stays relative
Ahh.. the never-ending discussion of synchronised timers π
Thanks physics
What you say James is something that does and doesn't make sense, which either means I'm too stupid or that what you say shouldn't make a difference haha
π
If EndTimestamp = StartTimestamp + Length, it shouldn't matter what you send, or?
What Jambax said
ignoring the overly optimized way of saving a property
It's more that the timer will keep the same desync state it had at the start for the duration
If you have a high delay, your servertime is already behind locally
so the formula compounds the amount of time you're behind
and your 5s remaining turns into 2s remaining
But whatever the Server sends is the same or not o.o
If I send Start = 2000 and Length = 10, or if I send End = 2010, why would that be different?
Doesn't help that I can't put into words what I'm thinking π
Well because the ping + sync is changing over time as that timer continues
So it sort of looses sync as that changes over time, or at least looses sync with the rest of the game
Okay so your actual countdown, that produces the final number to display is:
EndTimestamp - GameServerSeconds ?
yeah
Okay, makes sense
clamped between the 0 + timers length
Let me check a sec, I'm doing this for my dropships and the sync on those is pretty good
Yeah
I'm using the "End" time + a length
And then UI shows that relative to the "actual" current server world time
Though that probably should factor ping in too.. IDK
struct FGameTimerData
{
float EndTimestamp;
float Length;
}
// Server
FGameTimerData GameTimer = { GetServerWorldTimeSeconds() + 10.f, 10.f };
// Everyone
float TimeRemaining = FMath::Clamp(GameTimer.EndTimestamp - GetServerWorldTimeSeconds, 0.f, GameTimer.Length);
So something like that
Not actual working code, just pseudo stuff
Max(0.f, NextTime - ServerTime)
So yeah, what you have there
Then ServerTime could also factor in the ping if you wanted to try and make it closer perhaps
Which it seems is what I'm doing
Not for now. Just wanted something that is easier to actually use.
Being able to set a Timestamp that always changes ensures that I can trigger the OnRep properly
yeah
E.g. to change visibility of a widget or so
failing that, could just force it with an embedded counter in the struct too
True
But right now it's mostly BP and we all know how fun it is to modify BP Structs
Oh for sure π
But yah TL;DR, I think end timestamp + length seems to produce the most reliable timer
It makes sense atm
Not sure how easy it is to maybe embed a ping into this whole thing, but that's also not important atm
I'm so confused what is the benefit if you hack a discord account?
idk just dont click on fake discord nitro links u wont get anything
It's not actually the discord account
Payment information that might be used on other platforms?
it's for hijacking the steam account
And some people's steam accounts have lots of goodies to be traded away
Reminds me of the whole streamcommuninty thing with bots a while back, where you sign in and they nick all your csgo skims
@chrome bay Do you happen to know if the WorldServerTimeSeconds reset when SeamlessTraveling?
Ah I see, Epic is already trying to calculate the difference in WorldTime wit hthis ServerWorldTime
void AGameStateBase::OnRep_ReplicatedWorldTimeSeconds()
{
UWorld* World = GetWorld();
if (World)
{
const float ServerWorldTimeDelta = ReplicatedWorldTimeSeconds - World->GetTimeSeconds();
// Accumulate the computed server world delta
SumServerWorldTimeSecondsDelta += ServerWorldTimeDelta;
NumServerWorldTimeSecondsDeltas += 1.0;
// Reset the accumulated values to ensure that we remain representative of the current delta
if (NumServerWorldTimeSecondsDeltas > 250)
{
SumServerWorldTimeSecondsDelta /= NumServerWorldTimeSecondsDeltas;
NumServerWorldTimeSecondsDeltas = 1;
}
double TargetWorldTimeSecondsDelta = SumServerWorldTimeSecondsDelta / NumServerWorldTimeSecondsDeltas;
// Smoothly interpolate towards the new delta if we've already got one to avoid significant spikes
if (ServerWorldTimeSecondsDelta == 0.0)
{
ServerWorldTimeSecondsDelta = TargetWorldTimeSecondsDelta;
}
else
{
ServerWorldTimeSecondsDelta += (TargetWorldTimeSecondsDelta - ServerWorldTimeSecondsDelta) * 0.5;
}
}
}
Someone reported that the ServerWorldTimeSeconds at some point were like 3-5 seconds off
This would kinda make sense if the average suffers from some bigger gap, but eh
direct replication can get slow under load
Yeah I guess what happened was that they maybe had a new bunch of values or a reset with the > 250, and then had only one older value and the average calculation then freaks out
e.g. if you have timestamps 20, 50, 51, 52 and divide that by 4 you get 44
#pragma region NetworkClockSync
UFUNCTION(Server, Reliable) void ServerRequestWorldTime(float ClientTimestamp);
UFUNCTION(Client, Reliable) void ClientUpdateWorldTime(float ClientTimestamp, float ServerTimestamp);
float ServerWorldTimeDelta = 0.f;
float ShortestRoundTripTime = BIG_NUMBER;
UFUNCTION(BlueprintPure) float GetServerWorldTimeDelta() const;
UFUNCTION(BlueprintPure) float GetServerWorldTime() const;
#pragma endregion NetworkClockSync```
bouncing through the PC for network sync every 10 or so seconds
So Client asks Server for WorldTime, Server sends it back, and everyone keeps ping in mind
But either way, the OnRep from the Engine could cause bigger gaps I guess
sends it back along with client timestamp at the time request was made
so you can calc ping and everything
So you basically get the full ping from Server - ClientTimestamp?
and you use the delta calculated from shortest round trip
as it will be most accurate
Hi everyone, how do I use conditional replication in actor components? I tried the usual way using a DOREPLIFETIME_CONDITION with the COND_OwnerOnly condition, but it doesn't work. The client only receives the data if I use DOREPLIFETIME. Is there a limitation in conditional replication for actor components?
yes
well, no
void ARTS_PlayerController::ServerRequestWorldTime_Implementation(float ClientTimestamp)
{
const float Timestamp = GetWorld()->GetTimeSeconds();
ClientUpdateWorldTime(ClientTimestamp, Timestamp);
}
void ARTS_PlayerController::ClientUpdateWorldTime_Implementation(float ClientTimestamp, float ServerTimestamp)
{
const float RoundTripTime = GetWorld()->GetTimeSeconds() - ClientTimestamp;
if (RoundTripTime < ShortestRoundTripTime)
{
ShortestRoundTripTime = RoundTripTime;
ServerWorldTimeDelta = ServerTimestamp - ClientTimestamp - ShortestRoundTripTime / 2.f;
}
}
ping is difference between timestamp when request was sent and timestamp when reply was received
Right and ServerTimestamp is somewhere inbetween
serverr doesn't track the per client ping here, it doesn't care
Why do you only care about smaller values?
i care about the delta only
