#multiplayer
1 messages · Page 169 of 1
i wish there was fixed tick 😦
isnt 100 big when set to actors that are not used a lot ?
does lowering the value make it skip replication ? or does it just delay it ?
for eg, for a door i could lower it a bit since not 100 players will try opening it at the same time
does this impact RPCs ?
hi, someone can look in #blueprint I need an expert
Hi,
I 'd like to cleanly separate my client and server code, since I am not supporting listen servers.
In other words, I want my client binary to exclude server code at compile time, and vice versa.
I have therefore split my code into server, client and shared modules.
However, now hitting the UHT issue that you can't use UPROPERTY() etc inside a conditional block.
So for example my player controller class creates various client-only objects on the client, and those are UPROPERTY member variables.
How can I exclude those for the dedi?
Thanks!
(I have a #define hack that may work... but I don't like such hacks)
you can , i just posted a "little" video about this . doesn't go much in depth. but you can use fixed. https://www.youtube.com/watch?v=ltNaPfHwxhE
Quick Overview Of Mover, Explaining Biggest Complaint about the 5.4 mover, The "Jitter". Talking about what you can do to fix it and what possibilities the network prediction plugin allows.
- If you want a good explanation of network prediction and rollback check out this video from Overwatch Developer :
https://www.youtube.com/watch?v=W3aieHj...
sorry for the necro of a few weeks - have you seen any tutorials/guides/blogs that describe a better way that you've hinted at? I understand what you are saying, just looking if anyone has more on this before I delve into this exact topic
Matts approach (sounds pretty much like Lyra) is possibly a better alternative
The superstructs tend to carry to much unnessesary crap for every item 😅
Like why do my Rock item entry have Socket data, Enchantment data and other bonuses? They cant ever exist on the rock
Until you want to create a situation where the Rock is enchanted
One could ofc separate them and replicate them side by side
Extra work, and some linking but avoids the unessesery data when it doesnt exist (beyond some link of type integer or smth)
FItemBaseData
{
...
Int32 EnchantmentIndex = -1;
Int32 SocketIndex = -1;
}
TArray<FItemEnchantData> ..
TArray<FItemSocketData> ..
Not sure if this would be any less tho
If this is all the fragmentation there is, then possibly. But easily becomes massive aswell
And can be painfull to maintain
what are some things that would cause creating a session through steam to fail ? it's connected to steam, but it won't create session
480 is the testing one iirc
i have it set to 480 in DefaultEngine.ini
I have a strange spawning issue where the location im trying to spawn an AI character is ~50,000 units away from my possessed character and it won't spawn. If I move my character closer to the spawn location and trigger the blueprint again to make it spawn the actor then it works. I think it has something to do with net cull distance because the bug goes away with standalone mode. But I checked the values and the AI character is using the default net cull distance of 225000000.0 which is far larger so I don't see how it could be the cause of the issue.
but its all using the massive 225000000 default
so im well within that range at all times
Sure thats not squared?
Root if im not mistaken
if its squarred then its v225000000
15k
Could that be correct ?
ughhh that's much smaller than what I need
its kinda logic that its in square distance
maybe easier to do math with sqare than circle
no wonder LOL
Squared distance is cheaper mathematically
50k^2
2 500 000 000
Not sure ifnit accepts that input nor how much imoact that'll make 😆
How come you need to spawn itnso far away?
Well the AI is spawning on the other side of the level
well
that works, thanks for being so smart you smart people you!
the ator is still spawned right ?
its just that your player isnt replicating him yet
when you will get closer you will load him
I just used some massive net cull distance number for these AI characters who should always be relevant anyways
no I looked on the level outliner and it doesnt get spawned in at all which is a problem
is your player the listen server ?
no its dedicated
weird
well its the same, the player didnt replicated the event of spawing the actor
I use a widget for testing to click a button to spawn the AI characters in the "respawn room" then they run towards a "role selector" which then spawns them elsewhere on the level as a different character and destroys the old one. Problem was that distance was greater than the net cull squared distance (which I didn't know was squared lol) and so they failed to spawn in.
oh yes I see now they do spawn in once I move closer to them I was confused because on the scoreboard they appear as "dead" even though on the server they're alive but by the time I got to their location they died to other actors anyways. Silly ai bots.
I tested again and moved my character within the default net cull distance and saw they were alive on the scoreboard and hadn't died to other actors .... yet.
So that means all I have to do is fix a bug on the scoreboard so they appear to be alive even though my character isn't within the net cull distance which was giving a false report of "dead".
This means they wont start before within range of player tho, right?
and they appear as "dead" on the scoreboard because that's the default behavior
Well they are starting and interacting with the level just only on the server because of the net cull distance is hiding them on the client.
guys how can I not replicate something done on the server, if you wonder why it's done server side it's because it's a listen server so the server is also an instance of the game
If you don't want something to replicate, just not mark it as replicatable, I guess. Usually the problem is how to replicate something rather how not to replicate 😛
@mystic estuary yes but lets say for example you want to hide your pawn for the other but for you in local just change the material like a invisibility spell how do you do xD the pawn has to be replicated
Just make the pawn invisible on remote clients, you don't have to stop replicating the pawn
@mystic estuary yes but if for example a client is using his spell, for the client in local you change the material, but on the server session you hide it right ? but if you hide it, it will hide the pawn for everyone because the action is done server side am I wrong ?
SetActorHiddenInGame is replicated, yes. However, you could ignore that on owning-client: anytime the property is changed, change it back to false on the player that is using invisibility potion locally. Sadly, the bHidden property doesn't have an OnRep function, so there would be a harder way of ignoring the true state, nevertheless, it's not impossible.
yeah but this is fighting with server, and I don't like that ... What about hiding the component and not using actor hide in game
maybe it's not replicated I will test !
Yes !! that's working !
🥳
is there a way to put a delay in a function in blueprint ?
use a macro instead, use a customevent instead, etc
functions are not meant to be latent in blueprints
ok
as they are meant to return asap, in bp
What multiplayer functionality makes GAS worth using, besides client prediction, responsive root motion replication, and easy replication of montages?
I don't have a game where I need to manage a lot of different states with tags, damage types, resistances, etc.
So in terms of pure multiplayer functionality, does GAS do other important things under the hood? I mean stuff like more optimized montage replication (as opposed to RepNotify and Multicasts), or if it handles packet loss for montages/abilities more "gracefully".
Secondly;
Is GAS beneficial, or even viable to use, for its multiplayer capabilities alone? I mean without utilizing every aspect of the plugin, such as Gameplay Effects, or at least to a minimal degree. Can GAS shine without organizing all your gameplay within its structure, and feeding everything through it? Or does it require you to handle all gameplay elements, such as health and damage, within the GAS system?
I am not opposed to this, but I would like to know if it's viable to integrate GAS alongside your own systems, and only use it for certain functionalities. I already have a vertical slice of my game, and I don't see the need to refactor everything into GAS if it is not necessary. Hence I am curious if it's reasonable to only use a few functionalities that I want from it.
Thanks in advance for any advice!
Let me know if I should move the message to #gameplay-ability-system. It's sort of a two-sided question, so I was unsure where to ask. I'm mostly interested in learning about the first part, concerning multiplayer.
Prediction is the primary benefit.
That is not a small benefit, it's pretty important.
True, but I was able to create predictive montages with Blueprints.
Yes, but do you have a system to rollback mispredictions? Do you have a way to confirm whether a client successfully predicted something? Do you have a way to predict a fast-changing value without the server's confirmations stomping on your newly-predicting changes?
It's not as simple as predicting montage playback.
I'm not telling you to use GAS just for prediction, just that prediction is way more than just playing an animation.
You're right. Does GAS offer functionality to help with those things as well?
Yes.
C++ mainly, or Blueprints as well?
The complex parts of prediction must be handled in C++. Some of it is handled for you automatically, which mostly makes blueprint unaware of it.
Anyway, if you're going to use GAS then you generally should be integrating just about everything you can with it. As a framework it likes to take over a project.
Understandable. Really appreciate the insight, thanks.
Had a quick skim of that, but I'll go over it more carefully.
How does GAS handle rollback of abilities? I mean, without the plugin if you predict an event wrongly, the server will correct you anyway.
What's the difference?
I see the part about prediction keys, but doesn't the CMC and RepNotify functions do something similar when locally predicted?
GAS does not handle character movement prediction
If I have a boolean set to repnotify and when an actor is spawned by the server on begin play it sets that variable to true (it's not default true) and a function is set up to do something (change a material, etc) when a client joins after, that should run correct?
Sorry, I should rephrase. Does GAS handle rollback/server corrections smoother than a corrected, locally predicted RepNotify event?
I can't tell the difference, besides the potential for value stomping as you mentioned.
They still rely on similar fundamental parts of replication within the engine, right?
There's no smoothing, GAS prediction is designed for instantaneous actions, it is not suited for something that needs a buffer for rollback/resim like movement.
Gotcha, that makes things clearer. I did see someone link a video about using NPP for smoothing corrections, so I guess that is partly where it comes in.
Yes, NPP is much more suited for that type of prediction as it sets up a more generic framework for rollback/resim.
GAS prediction keys are usable outside of GAS itself, though you then have to implement sending/confirming/rolling back in your own systems.
Thanks!
Assuming the server is setting the RepNotify successfully, all relevant clients (even if they join later) should be updated on the state of the variable, and thus execute the appropriate function.
in this case I'm referring to a client that joins after it's set. Are there any known bugs in PIE with this? I set up a 2 player listen server, started it up, spawned the actor, set a the boolean on begin play (actor replicates) but the function just didn't run. used reconnect on the client to verify but also didn't run. very weird.
BeginPlay of a player character?
Begin play for a spawned actor. Actor spawned by the host/server. pulled off switch has authority. Actor is present, actor is replicated, but the repnotify just didn't fire. Even stuck a print string on it to be sure.
If I remember correctly, event OnPossessed in the character BP only runs on the server, which is who should set the notify in order to replicate it.
Otherwise, just call a server RPC on BeginPlay.
Use a print string for OnPossessed, before setting the notify, to make sure the server is called.
not a character, this is a random actor in the scene.
Hmm, and you know that the server is calling BeginPlay of the actor?
Yes, because when I had it previously as a multicast the multicast was called off the begin play. I've temporarily fixed it with another function for now, but I'll have to do some more testing later
Hello everyone!
Is there anyone who would be up to guide me for like 5 minutes via a call? You don't need to have a mic hehe
Did you try setting the notify with a server RPC?
I'll give it a shot, it's pulled off switch has authority so it should be running as server
Anyone knows?
is TSubclassOf replicatable?
Yes
So if I had it as a member on some component/actor of type TSubClassOf<UUObjectDerivedClass> with defined GetLifetimeReplicatedProps it will be replicated right? I'm asking cause I know UObjects aren't replicatable.
Hello multiplayer experts. I'm using a custom CMC with safe moves to launch my character at another, but when they collide, the client is showing a ton of net corrections I suppose due to the fact that the other character is stationary and the client hits them before the server does. Is there a decent way to fix this? I'm looking to launch at the other character and continue my motion or at least if I get stopped not rubber band everywhere... Also, when the character gets close to the other, it launches them as well so that seems to be adding to the confusion as the client version seems to be off from what the server launched target seems to be.
TSubclassOf is not an Instance of an Object.
UObject Instances are not replicated out of the box.
TSubclassOf is a pointer to a UClass
The Engine can resolve that across the network because every machine will always have the UClass being pointed to.
I see, so it will work then, thank you!
May have just rubber duckied myself. Appears that when I call launch on the other character as an RPC from the client, I still need to call it locally on the locally controlled client as well so it can predict and then the server can catch up to it. Seems to have eliminated a lot of the rubber banding.
Hi i started learning about Character movement component, and it mostly says it's useful for multiplayer games since it transfers the data towards the server side, the thing is if it's without a physical server , like a multiplayer with a pc-hosting & clients configuration is that still useful or i should keep the usual movement system witch is client sided ?
You should always use Server Authoritative movement.
why do you think GMC is not a path forward for the movement stuff?
There are very few usecases where Client Authoritative movement is necessary.
ok so what i'm learning will be useful for my project, tyvm !
you have any examples ? (not needed, just for culture)
Instantaneous high speed movement abilities can sometimes cause problems. You can disable/enable Server Auth Movement during these abilities to ensure they are consistent. But that has its own set of problems to deal with.
As a new user you should never need Client Auth movement.
Hmm I'm curious if my launch abilities would be considered high speed movement. I'm launching forward 1000 to 2000 u/s sometimes and knocking back about the same. Wonder if that's also contributing.
I bought a rock paper scissors multiplayer game on the UE launcher to help me understand how to make multiplayer games.
I can't say it has helped much.
is there a limit to how many replicated variables one can put
just the number alone, not related to how often they are being changed
Isn't there a limit on how much data can be replicated?
I mean, to not choke the buffer
The NetDriver does impose bandwidth limits
So, isn't it a limit?
His question was specifically is there a limit to how many replicated variables you can have. He also specifically stated that he was ignoring any limitations on their replication.
I answered his question as he asked it.
Ik, I must've misunderstood
for some reason i cannot travel a specific level but all other levels seem to travel just fine? whenever i try to travel to this level it just puts me back in the main menu
on build it just gave a black screen
hello what would be the best method for creating a money system for a multiplayer game? would it be in the game instance since they will have different player controllers?
Hmm I seem to be confused about Safe movement variables in the CMC. Right now I'm using them to perform movement abilities which properly predicts on the owning client and sets it properly on both the owning client and then the server. However, the simulated proxies do not see things properly because the Safe variables are not replicated. For instance, I enter into fly mode by setting a safe variable bWantsToFly to true which is then checked in the update movement function to properly call the launch and switch to fly movement mode. When I want to toggle the safe variable to false to exit, it works fine on the owning client because it's changing it and pushing up to the server to match. When I do this same thing on the ListenServer, it immediately exits because bWantsToFly is always false on the simulated proxy due to it not replicating. Just now I added property replication to this variable and marked the CMC as this component replicates and it seems to now only call on the server without exiting like it has been, but this feels wrong. What am I missing?
yes that's correct. idk why I asked really, I figured there would be no limit but was just curious because the keyword DOREPLIFETIME makes me think there's a lot of fancy things going on behind the doors, more than what I understand about how replication works
if variables are being internally copied and moved around or something idk
It just registers that property with the replication system, so that its aware of it.
What exactly do you mean by traveling? Moving from server to server, from host to host, or just disconnecting and playing solo on some level?
If you mean, where should you store player's gold, your answer is PlayerState
That is a class that is independent of things like pawn, so player resources won't be destroyed when player is killed. Also, it can be moved across the servers
Are you travelling in PIE?
moving from level to level
in both pie and on a build of it (build blackscreens, pie just sends back to main menu)
outside of server, so just singleplayer?
in multiplayer when pie in listen server it was doing it
no other levels besides this specific level do this which is the odd part
like i can travel to other levels fine which is odd because i can also load into it from the main menu fine too
Can you send the logs?
Did you forget to enable Seamless Travel?
i beleive so
Have you tried to remove broken asset from the level?
broken asset?
the level assets store level info so i can put it on the loading screen and such if that makes sense
like it stores name, path image, description
and then i get the path and pass it to the level loading function
but yeah it may be the levle asset for some reason which would be weird
will investigate some things
How do people handle respawns that have an animation and move players? I seem to occasionally have the issue where the packet with position does not arrive the same time as the packet that restores a players health / plays the respawn animation. These things are all set on the same frame for the server, but their replication is not atomic, and this results in clients occasionally seeing simulated proxies rez in place before suddenly teleporting. This can be rather misleading during gameplay, does anyone have any elegant designs to tackle this?
How are you handling respawns? Do you destroy character at kill, and then respawns it?
ok weird update i added it to my level pool asset thingy and it just started working for some reason???
strange
Ah no, pawn stays as is, transform is changed and a gameplay ability with a montage plays in response to the event on the server
I guess pawn destruction is a way to force it, but I kind of dont want to go that route, theres a lot of players and they die often, dont want to reinit the pawn that frequently ideally
So to respawn, you just change pawn's state. You update it via variable replication, right?
I am using GAS, so the animation montage is replicated through GAS (FRepAnimMontage struct), there is a death state variable also replicated (this idea was taken from Lyra, replicating an enum) and finally there is the transform replicated via ReplicatedMovement. There is also the health float variable replicated via the pawn (forgot to mention that one)
I don't have much experience with GAS. But as a workaround, can't you don't replicate this one particular animation, and play it on the client, only when state is being changed to respawned/alive/something_like_that?
I could, but there is also the matter of the health value being restored. I could similarly make an exception for that, but there might be something else in the future etc, so I am a bit hesitant to take that route
I dont know if alternatively, forcing the actor channel to close and reopen for all connections (Except the owner) could work
you mean, you don't want a situation where animation plays, but health is not restored yet?
I effectively need the transform to replicate either in sync or before anything else, if I reduce the problem it's core issue
Nah it's more that, your suggestion was "dont replicate the animation, play it on the client when the state changes", but in the mean time the health can still replicate, and we essentially have a player whose health bar just filled up to full while being in the location they were lying dead (very misleading in player vs player)
What's coming to my mind is that you can use OnRep to check for edge cases. Like, e.g. if player's health is updated, but player state and transform are not yet set for respawn, then you store it into some other variable, and update e.g. player's widget after proper state is set
I will probably consider that as a fallback approach. The issue is also that some effects (like invulnerability and some immunities) are also applied on respawn, so those must also be handled... and it's just become a bit of a long list of edge cases 😄
Then, maybe encase it all inside of the struct, and just replicate the struct, and it should all repliace at once
Yea I could make it replicate atomically, but then that means everytime 1 thing changes, I pay the bandwidth price for many things. Some of these things change very frequently, replicating effects or animation state because a health value changed feels a bit overkill and will hurt bandwidth
I ran out of ideas, unfortunately. The last thing that is coming into my mind, is to send a reliable RPC to set everything at once only at spawn, then set variables on the server
@fossil spoke I rewrote my code again to handle inputs only in the player controller, I hope I made progress 😄 The only issue I have now is still the Client not being able to press any input for some reason and can't find how to fix that 😬
Gating it through the transform rep sounds reasonable.. any other cases where you rep transform?
Hey, if I’ve got some simple information, like the class of the character each player selects in a “character selection” screen, how should I communicate that information to the game mode when opening a new level? I know I could make a map with the players and their character class in the game instance, but I’m wondering if there are better methods?
You can store their selection in their PlayerState and use the CopyProperties function to copy the selection over to the new PlayerState on level transition.
There is nothing really wrong with using the GameInstance of the Server for these things
Really depends on the type of data I suppose
You can also use OnSwapPlayerControllers in the GameMode to move it between controllers.
Cool, I'll check that out!
That to. There are many ways to handle it
Both needs the selection screen to be while already connected to the server
If the screen is in the MainMenu then this won't work
If there is a preselection period before connecting to the server you would need to pass the selection in with the connection options.
Did Epic expose that better in 5 to BP?
Doubt. The function is part of the ULocalPlayer
It's easy enough to expose it I guess
Shame. I guess omitting it helps force people into C++ lol

Where they should be for those things
Yus
I have a problem with replication. Looks like replicated actor receives different name when replicated to client. I assume that because of that replicated array of references is empty. Is it normal? Object are spawned on begin on game.
None means it hasn't replicated
are they all actors?
yes, all of them are actors, and they are replicated - I can interact with them on client side
Show your code for the replicated array
sure
that select is likely at fault
It probably makes a copy of the array
instead of a select, use a branch
Also: make sure to only set the data in that array server-side
don't wanna overwrite anything on the client - the server is the authority
will give it a try, but you can see array is filled on server
yes, but i will double check the relevance
yeap, it is a problem with relevance, they are not passed to client if I make them hidden before client joins
thanks for help!
Do you mind expanding on why you think GMC is not a path forward for the movement stuff?
I assume it uses the same or very similar way of handling prediction, which means it's nothing that is shared between other systems and thus suffers from the same problems.
GMC might be better (never used it and probably never will) than the CMC, but as long as it doens't use something like the NPP and maybe even FixedTick stuff, it has the same problem.
Speaking of NPP, the crash we experienced on a client's project is now public: https://issues.unrealengine.com/issue/UE-210720
Their repro steps are a bit strange, cause we can get this with just 1 client and outside PIE, but well. Error is the same.
Hey guys! Does a RPC (Server, reliable) called by SERVER does some network traffic, or is it ignored, as if it were just an ordinary method call?
almost as it it were an ordinary method call
not sure how using network traffic would make sense
yeah, I agree, but I just want to be sure 😅
Hopefully NPP will actually some attention with Mover, but I'm a little disappointed at the lack of commits there
I would also love the fixed tick policy to not suck
It's only like what, 3 people working on Mover? and possibly "none" on NPP?
And I'm not sure they work fulltime on it, given that Epic said NPP (and Mover?) is in maintanance mode.
So I wouldn't expect much at the given point in time. They will also not address any of the Bandwidth issues any time soon.
Mover has a dependency on NPP, I would hope that NPP would actually get more attention as a result
Yeah but both aren't being used by Epic as of now
And NPP is def in maintenance mode
From what I remember, not even the samples in the extras plugin even worked properly with the default settings
They fixed some BasedMovement stuff on Mover fwiw
I'm relatively sure the Examples are from Dave Ratti still and haven't been touched beyond that
Wouldn't even surprise me if he had local settings that he never submitted
I'll have to look into either patching IndependentTick to have combined reconciling of multiple SImulation Instances, or patch in a Service to get the Smoothing done for FixedTick I guess
What about Iris, how does that fit into any of this? Or we still don’t know?
Iris is mostly working in the background. I assume if Iris is enabled it will only really have an effect on the NetSerialize functions of a Sim's Sync, Aux and Input Structs.
haven't gotten that far yet though
It would be nice to have interpolation for fixed tick as I believe this is what Quake and the Source Engine does
@hollow gate Posted a video outlining this a bit. Doesn't seem too tricky, but if I see it correctly he mostly implemented this into Mover itself. I would much rather have it a Service.
I know how to add those, but I haven't thought about what I would need to do yet.
I assume it has to tick every frame and simply pass the data that SirKai passes along in his functions to the Driver/Simulation.
Would be nice if he could simply share the code that lives inside the Smoothing and maybe even Lag Compensation components.
But that's up to him, I would understand if he doesn't want to share it just yet.
i did mention in video if anyone is interested can DM me, but i guess it's best i put it in a public repo. still i can't put there the getter function i added to network prediction manager. i will clean the code and add some comments then post it.
as for services.. i did it but.. it was so much work since every single model defined needs to implement the templated functions for smoothing. every single one in extras plugins 😅 . the longer epic takes to do this the bigger the task. that being said there's a cleaner way. you can specialize the Tick and the finalize services to do it. take a look at MockNetworkSimulation.cpp which has custom tick service that does a parallel for. but you'll need to copy paste this custom tick service in every model definition you want it to have it.
as for services.. i did it but.. it was so much work since every single model defined needs to implement the templated functions for smoothing. every single one in extras plugins 😅
if we ignore the extras plugins, cause they aren't relevant for actual projects, would it still be a lot of work?
I feel like only Mover and any project specific sim would need it
if you delete the extras plugin, you'll have few model definition you'll need to add the templated function for. so it's not that much work. but personally prefer making custom tick and finalize services that i would just reuse. because not all simulations would require smoothing in reality
for an ability system type simulation , i don't think you would need it. but it's good to have the choice.
But Models can just not register for the given smoothing service
Or am I misunderstanding something
Maybe we are talking about two different things but my idea would be a Smoothing service that models can just not register for if not needed
most services are automatically assigned based on network role and the project settings. only physics service has other conditions. i didn't like the "global" service personally because it makes looking for the actual code that does stuff harder 😅 .
you can make custom tick service , and add whatever you want in it. a custom fixed tick services that call templated function update smoothing Data after doing simulation tick
and a custom finailize service that calls finalize smoothing after the actual simulation "finalize"
I mean, that can all be just one Service
Guess there are different implementations possible
yes it can, but you'll need a double loop. to loop through the registered smoothing services after sim tick and after finalize. i thought making custom existing services is a more elegant solution that doesn't require deleting extras plugin or even editing engine plugin. the templated functions will still need to be defined in the driver of the simulation.
Right, so you would simply inject single calls into the existing loop, at the end
But doesn't the FixedTick loop only tick.. fixed?
yes, the services have been designed in a nice extendable way.
sorry that is a mistake , fixed in not needed there. the tick service is the same
the thing it does is same. they just go into differents arrays when registered based on if they are fixed or not.
I guess I need to look once more into how FixedTick is implemented. I was very focused on the Independent one for now
it's same thing , calls same functions, just that fixed tick use time roll over to accumulate time and tick on a fixed delta time, calls the simulation tick in that loop. everything else is the same.
Right but, if it only ticks if the Accumulated Time hits the FixedStepMS, you'd need to use the Components or Actors tick to do the actual interpolation/smoothing
MockNetworkSimulation.cpp has the custom tick service example.
Lemme check
no no there's already a delta time
in the video i said you need the add getter functions to NP manager so you can access the "UnspentTime" so you can do the smoothing.
Yeah I get that, but my comment is about actually having something that calls each frame to update the mesh
that's the finalize service
called each frame, not fixed
for (TUniquePtr<IFinalizeService>& Ptr : Services.FixedFinalize.Array)
{
Ptr->FinalizeFrame(DeltaTimeSeconds, FixedServerFrame, FixedTotalSimTimeMS, FixedTickState.FixedStepMS);
}
So that one
Hm hm hm, makes sense
yes , for independent. sim tick will be called then finalize right after. and for fixed sim tick can be called multiple times
or none i guess
Yeah so in other words:
BeginNewSimulationFrame_Internal will cause 1 IndependentTick call + 1 Independen Finalize call. And it will cause 0 to X FixedTick calls (based on accumulated time) + 1 Fixed Finalize call
And the Fixed Finalize one is what we can use to Smooth
+- the extra getters
yes . that is how it works. , TFinalizeService is same for fixed or not. you run it for both but for independent you need to set smoothing alpha to 1 directly. so you can smooth correction. for fixed smoothing alpha is UnspentTimeMS/FixedTickMS
Makes sense, UnspentTime is just Accumulated DeltaSeconds
Since last "actual" Tick
Is the custom TickService relevant then?
yes whatever fixed tick left over, so we can use it to know where we are supposed to be between the fixed tick updates. linear lerp
Do you use the Interpolate functions on the States to lerp/etc. between 2 states?
Can't recall if you showed that in your video
Also, does that automatically fix correction interpolation?
Is does that need an extra step
custom tick updates the smoothing data. and since it only update when not re-simulating. and it saved "last update smoothing data" when you are about to tick you can check the cached "last update smoothing data" against the input of the simulation. if you did not correct it will be same and there's no delta, if you did correct there will be a final correction offset between these 2. i just blend it out by adding back it by scaled by 0.2.
since smoothing data is usally small part of the full state data i opted for own smoothing struct that has own interp function
and yes this does smooth corrections as well. this article explains the smoothing setup in a nice way. it's pretty much the same thing every game does.
https://www.maintanksoftware.com/article/rollback4.html
Not sure I follow how this is supposed to work. Or rather what you actually mean with CustomTick. MockNetworkSimulation shows a ParallelFor Tick Service. It's own Tick function seems to be mainly used for Debugging.
Maybe it's easier to follow if you would actually be able to release some sort of repo.
the component i made has the actual code doing things, where you write it down and call it from can be changed as long as its after sim tick and after finalize frame
in the video i show the simplest way to add smoothing. i wanted to make it to share with other that are not cpp savvy and want to use fixed tick. since it just required simple editing of existing code.
did not use a custom tick in what i showed in video.
Ah
it's an example. he has debugging to turn it on and off, i guess to see diference in performance
So is that CustomTick another Service?
Also thanks for the link. Wasn't aware of that article yet.
you can see here the service that is used with this model def. (FMockNetworkModelDef).
all functions call parent except the Tick.
if you want to have a VC call with screen share i don't mind
Another time maybe. I'm ill atm and my throat would probably die.
sure, get well.
Does that Mock LocalTickService get picked up automatically?
yes.
Ahhh. Ok
this is the util function that calls the TickSimulation on the sim class.
used like this inside the Tick function of Tick service
Yeah I've seen that before
So, something I wasn't aware of before, but that seems to be the conclusion: A Model can define a custom Service (of existing type) and that will be solely used for that Model when it is being registered?
i used this to test out input decay too. spoiler forward predicted simulated proxies can't look good if predicting with old input kinematic movement. interpolation is the way to go
yes. this is it.
That's pretty cool
I wonder where exactly that magic happens. I think somewhere in ConditionalCallFuncOnService
Right yeah, it passes in ServiceType<ModelDef>
I think I would be fine with Interpolation anyway
yeah, all services can be inherited. ngl dave ratti did an amazing job.
In terms of pure C++, this is as complex and confusing as it is awesome
yes, if overwatch the the likes are fine , we'll be 😅 overwatch has about 50ms interp delay
it had be a template hell to support all these features. and no subclasses etc..
Well the template stuff is to make it cache friendly I guess?
yes. i assume that is the main reason.
I'm honstly still not sure about the CustomTick and post Sim/FinializeFrame stuff you mentioned.
Is that mainly for corrections?
That's at least how it sounds like in your text.
there are few things that he does in extras as well , that makes you think. like how he did root motion sources with a store and Object ID and the params. immediately makes me thing of a gameplay ability that can have its own serialized params state data.
I still have to read through those examples. I spend most of my time the last weeks on just reading through NPP and Mover to get a better overview of how it is all connected.
not sure i understand your question, you need to tick smoothing so it would save the state for each tick, so you can use it in finalize to interpo between it and last state
tomorrow , at least smoothing comp will be in a public repo. i will also make a video on what you need to do to hook it for anyone interested.
I'm not understanding why it's not enough to use FinalizeFrame with the "GetUnspentTimeMS" function to interpolate
the comp will show you why you need to use both tick and finalize
That is very nice
you tick to cache the last sim tick state
since you can tick at multiple times a frame this saves last sim tick state , used for both correction smoothing and used during interpolation in finalize. for corrections you just get the delta between what you cached as last sim state and the input state of sim tick. if you did rewind and get corrected these states will have an offset between them.
Hm
simulation tick gives you input state which is the last simulation state output.
if it's different from what you cached when not rolling back. then you did rollback and get corrected.
Hi im new, how does multiplayer in Unreal Enginge 5 work, in unity you have to write it all, is that also how it works here?
Problem: Severe lag in an empty UE5 project in local standalone any net-mode.
Steps:
- create a new project from FPS template.
- print ping from player state in character BP.
- launch as Standalone with 2 players in Client net mode (with a dedicated server) this happens with a listen server too.
- ping will be 120-200ms with noticable lag.
Other notes: - turning on network lag emulation in editor settings does work and if turned on, it makes it all worse. I tried setting the emulated 'lag' to minimum 0 and maximum 50 to emulate normal conditions, but this did not work either as lag was around 300-400ms.
- my network-related .ini settings are optimal with 60 tick rates and cranked up bandwidth, it does not influence anything, since I only run two clients with two default players.
- this lag happens in literally every UE5 project that I tried, including Lyra example.
- I have some older UE4 projects that I checked for sanity's sake and in those the locally run net modes report ping of 5-8ms which should be normal, but not in a UE5 project.
- I turned Iris on/off, which did nothing, which makes sense I suppose, since it is only a method of getting/sending the data down the pipes.
- I have googled and clicked on pretty much anything related and all have been vague dead-ends, but seems like many have had this problem in UE.
- I am not running any kind of VPN, WiFi, Firewalls, it's literally just a local home PC with a wire.
What gives? Is this normal for everyone?
It' s all on by default.
What?
So you cant just write a shooting script and every player ingame can shoot, you dont have to write some code to syncronize like in unity?
lol no, ofcourse you write networked code for your game, but it's much more streamlined and you don't have to write low level replication logic, like in unity.
I get the idea behind saving the state etc. Just not when you do that.
You said it's a custom tick, but that's very vague for me.
Did you mean "Custom Tick Service"? And how would you make sure it's called AFTER FinalizeFrame?
I know that SimulationTick gives me the In and Out (Out I generate myself) State.
And that I can possibly Cache that State in my Component.
But isn't that the same state I would get in the next few FinalizeFrame calls until the SimTick happens again?
@analog yarrow Please read the pinned Multiplayer Network Compendium
okay thanks
@hollow gate I think I'm either really bad a following today, or I'm missing something obvious :P sorry
I don't think a severe lag in an FPS Template without Network Lag Emulation is normal fwiw
I assume we are talking Network Lag and not Frames.
Yehh, I would think so too. And yes, it's all about Ping values.
you want to look at RPCs, Replicated Properties and Rep notifies in unreal engine. only Actor class and its children can do replication stuff.
https://www.youtube.com/watch?v=4Tnbf44NjXo this series of videos should help. reids is a great teacher
Support the channel through donations. Crypto accepted!
PayPal: https://paypal.me/reidschannel?locale.x=en_US
Patreon: https://www.patreon.com/reidschannel
Bitcoin: 1JFwWHr4X6uAeoZadukzqKjzFBj3Qjy7Sk
Ethereum: 0x2B2Bc108F1Cc0fF899959dEF3226637787d8C3dE
Dogecoin: DNQ33YnhpWoTBokBNVkZP5ub8KTLkpyjpv
Join our community discord!
Discord: https://dis...
thank you, i will look into that.
Also, if you get Content Example project from the UE Launcher, it includes some basic networked blueprint examples.
Lots of great other examples too.
does replication have to be written in blueprint, cant it be written in c++? also isnt that better, i have heard the blueprints are slower than C++.
@analog yarrow #multiplayer message
Can be C++. As a matter of fact, Blueprints have a lot of limits and you are better of getting used to C++ if you want to do Multiplayer anyway.
But I wouldn't worry about performance of C++ vs BP at this point.
To get your head around things, blueprints are definitely sufficient.
thats nice to know, i would also rather learn c++ lol.
nah all good i don't mind the slightest it's a confusing subject in general.
ok let's forget about the custom tick service for a second. let's talk about smoothing in general what you need.
you need 2 states to interpolate between during finalize frame, these 2 states are the simulation state the last simulation ended at (the state that you get in finalize function as input) and the one before it. this one before is not necessarily a state that finalize frame was called for it. remember sim tick can tick multiple times per render frame.
so you need to update the smoothing states in sim tick ( this is where you also catch corrections).
and in finalize which is every render frame you use the states you updated in sim tick to interpolate between them.
c++ is the engine language. BP is just on top of it. so there's nothing BP can do that c++ can't. but the other way around , many things.
Okay so, in FinalizeFrame I do:
{
InterpState = Lerp(/* from */ LastCachedSimTickSyncState, /* to */ FinalizeFrameSyncState, UnspentTimeMS / FixTickTimeMS);
}
That is correct so far?
Just pseudo code
if cachedSimTickSyncState != FinalizeFrameSyncState . meaning it's not the last sim state that one is "FinalizeFrameSyncState " , it's one before it
so FinalizeFrameSyncState - 1
in mover LastCachedSimTickSyncState, will be what you get in finalize.
I mean sure, if they are the same, lerp would be redundant
yes, that is the idea. the article i shared earlier, has the equations in it as well with clearer naming that what i am saying
You mean Sn+1 = f( Sn, Cn+1 )?
LERP( Position_Simn-1 , Position_Simn , Accumulator / Tick_Length )
to smooth out correction you need to add bit more. this howver will smooth the fixed tick
There is also something else I'm wondering with FixedTick.
If we say we have a FixedTimeMS at 20hz. And the game runs at 60hz.
How does that work with ProduceInput?
First thought would be, only every 3rd frame of Input is actually considered.
yeah input is cached in local variable and consumed in produce input. only 1 frame presses are cleared. rest are not like movement input is never reset to 0. just pressed jump is reset to false after adding to input struct
but yes input is sampled at the simulation rate.
Right, so if I press Jump in any of the 3 frames, it will be cached and used?
Alright
if you press it mid render frame, it can be used in next sim tick before that render frame ends also
So, I noticed that Replication Graph is disabled by default. After enabling it, I am getting lower ping values 50-80, but the lag is still very visible in character movement. Makes no sense.
Hm, AMoverExampleCharacter seems to set both Jump flags to False when releasing the Key. Wouldn't that mean that if I press and release the key in a render frame that doesn't line up with a SimTick frame, that the input is lost?
ReplicationGraph should not be needed. In theory its hould even be somewhat redundant with Iris.
You shouldn't really get high pings when playing locally without Network Emulation.
There is some ping of course, but very very low
Yeah, that's how it should be, but isn't. I'm getting high ping in local net mode in any UE5 project I've tested so far.
People at my work have just been working with a project as is and never paid attention to it, but the lag is the same, just that in Lyra animations mask it and it does not look as bad.
Am I going crazy?
Hi,
I have a supposedly basic issue here.
Everything **close **is NetworkRelevant if I use a character.
Nothing is NetworkRelevant if I use a pawn
Do you have any hint for me ? (I already read exi's guide)
PS : the pawn is composed of a blockAllDynamic cube and a camera and its network settings are the default ones
hm this is in the player HUD
is this wrong to set it up like this ?
in my "player hud Widget" im getting the same player character..
Don't see anything wrong with that. In general, you might want to avoid having hard refs of the Player character in widgets, but that's just my oppinion. If you need it, you need it.
hmm then why is it bugging :/
Needs more context. Player HUD only exists for the local player, so you should get the correct pawn.
Where is the HUD set up?
in game mode
And you get this bug when launching in what mode?
try with dedicated + 2 clients.
Pawn may yet not exist
Are you saying that a print message is coming from a HUD on server?
Add print to cast failed
ah true
hm dose not fail
@coral badger might be abit confusing i have the "player_Hud" and also "PlayerHud_wB"
this was from the player_HUd
also getting same resault from playerHud-Wb
So, it works?
I'm lost with the namings and all, but this still looks like a Listen server launch, not a dedicated + client.
yeah
Try that. HUD does not exist on server. So each client should only get his own.
be different then right
I'm not actually sure if Owner gets set correctly for the HUD in Game Mode if it is not set explicitly in BP code.
If I spawn an empty character and possess it : close stuff is NetworkRelevant
If I spawn a basic pawn and possess it : nothing but bIsAlwaysRelevant gets NetworkRelevant
Any idea why ?
hm
I don't have experience with the why, but it makes sense how character network relevancy settings would be different than just a pawn, since a pawn can be an AI and character will always be a player. What are you trying to achieve/what breaks?
Change the relevancy setting/net culling on the Cube Pawn and see if it changes anything.
well this is real simple its just hooking up the player to the widget and im using progressbar to detect health thats it
i could do it in the widget itself but i like having a parent holding the core reffs
Then that setup is not how you should do it. You want to bind the value of your health to your player character in the widget dynamically, so, it will always pick up a change only when it exists.
As to the bug itself, seems like the HUD just has a wrong owner. Not sure why.
You could try just getting player pawn and playing with the indexes, which would at least tell you what exists on BeginPlay for the HUD.
hm
im trying to set the Character from within the controller instead
how is this wrong O.o´+
So, put different indexes into it, to see if that works correctly
it dose
from the HUD
Ah ok
I assume the player characters just spawn from being set in game mode, not explicit Possess or anything like that?
yeah
And your characters are set to replicate?
Try that
So, if you print the owner here, do all controllers return the same?
yeh
oh ok so no
this is from the controller it displays correct controlklers
but same character
Try printing NetPlayerIndex on controllers
And with dedicated?
how do i simulate dedicated only clinets ?
aye
yeah
all 0
this is just garbage
ok tell me how i would do it from scratch
this is just mind numing
how would u set up the player character reff for each player
just gimme the most common easiest way
As I said, I wouldn't. I'd just bind the value in the widget.
You can't use the "Get Player .... #" nodes reliably in multiplayer, especially so on begin play of certain actors as the player may not have the appropriate reference assigned to them yet.
Same with using "Get Controller" on a pawn on Begin Play - it may not be posssessed on Begin Play.
Same with using "Get Controlled Pawn" on a Controller.
In an empty project I`m getting the same result from the HUD, so, I'm not sure if that is right at all.
hm ok
so u mean
in the player hud Widget
u would cast for
u would do it like this ?
forget the is valid
Not really
then what do you mean+
Get owning player pawn
This is within the Pawn class.
ok
That's the first event that is both server and client where the controller and pawn can know about each other (in blueprints anyway...)
hm mkey
this however give only player charcter 0...
for everyone
this is how im creating the widget
in the HUD
If your cast is succeeding, then it should be correct.
Well I'm guessing that's a bind right?
yeah
Then it shouldn't matter, it may fail the first few ticks until such time as your controller possesses a PlayerCharacter_BP
yeah true
but yeah thewy all gives player character 0
so not working
this is so weirddd ???
Are you actually playing as client/listen server and not playing as standalone?
Can you show the actual printout that you're getting? You should be seeing something like:
Client1: PlayerCharacter_BP0
Client2: PlayerCharacter_BP1
yes exactly thats the issue
just tried that too lol. All of my experience, but have no idea whats up with that. Guess I never needed to do it that way.
If you are in the GameMode, owning player on listen server will only return itself I think.
Can you take a screenshot and show what you are getting? Preferably the blue text that you see in the viewport?
Getting controller for each player state could work, but I wouldn't spawn HUD in the GameMode, if it still is.
ok so i just moved the creation of the hd widget to the player controller
wtf ???
Uh
You're running the code on the server aswell
On the servers copy of a clients controller
Well, technically you shouldn't necessarily rely on the display name of an object to know whether it's the right object or not.
The reference is more important than the display name that a client may have as the display name is handled locally.
This is within a pawn class.
Hello, i have an issue syncing a PlayerState variable, what i want is that, when the player open the game, it does a http request to my backend, and then gets an accountId, this accountId is then set in the PlayerState , this happens from the client, then later on, it joins a dedicated server, but in the dedicated server, when i check this PlayerState, the AccountId is empty, so i dont know what to do to make sure this value gets sincronized
i have something like:
// MyPlayerState.h
UPROPERTY(Replicated)
FString AccountId;
UFUNCTION(BlueprintCallable)
void SetAccountId(const FString& NewAccountId);
// MyPlayerState.cpp
void MyPlayerState:SetAccountId(const FString& NewAccountId){
AccountId = NewAccountId;
}
void MyPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(MyPlayerState, AccountId);
}
Tested with 2 Players, running as Listen server, pressing Page Up once on each of them:
If you're joining a server later on, the PlayerState wouldn't carry over as it would be destroyed when the client is moving to the server. The only thing that would normally persist is the GameInstance.
I'd also be cautious of having the client telling the server an account ID after what I'm guessing is authenticating with your backend. This could potentially be an easy way for someone to spoof someone else's account.
I would highly suggest decoupling any authentication/3rd party account stuff from your Player state. Nor should the game server actually know about any kind of authentication. Your infrastructure should be separate.
mm good point, so i dont know how to solve this, since i need to know the backend Id of each user, so i can register the match result in the backend from the dedicated server, any suggestions ?
@daring cosmos
This is a very big architecture question with a LOT of variables, but:
you should have a separate module/subsystem that handles that stuff, independent from the gameplay. Have that module have authentication/sending info to the backend.
Have your stats/whatever you need tracked in the game state (which is server authoritative) and then pass them to that module which will send them to your backend.
Have your game session on the server handle authentication-related data, like ID's. Depending on how your backend is set up, if your server will be hosted on that same infrastructure, you could directly call those methods from the server and let it post stats to the backend.
However, the game server and your authentication/player account infrastructure should be separate modules and ideally should not even know about each other.
got it thanks, i have some of those things already made like i have a subsystem just to interact with the backend, and in the game session dont know anything about backend until the match finishes that then needs to report who won to the backend, then the backend handles the progression to each player, and thats the part i dont know how to handle since i need the ids of each one player to be able to update the stats of each participant, like exp, etc in the backend
@sinful tree https://gyazo.com/4edece4fa1e410924c26fd7cd0722b92
sry was afk for abitÄ
Ok, then you should be able to give those id's to the session, since session joining should happen from each client after they auth. And then get them all on the server from the session when your match is done and send stat update to the backend. I don't exactly recall whats available in the session interface, but the idea is that you should definitely not keep ids as replicating variables or do any of that stuff with in-game events, if that makes sense.
Anyone know how I would get some printed string to appear for clients? I tried running the string through a game mode event with different event server settings but have come up dry.
GameMode only exist on server
if its a global message, passing it through Gamestate would suffice
if its a player specific one you'd want to pass it through an actor that player owns specifically. PlayerController sounds like an ok fit
thank you very much.
How do you make your AIs/Bots looking at a given player's pawn?
The simple answer would be something like SetActorRotation on the server and take it for granted; I feel, however, that's quite costly, since server is dispatching updates every time the pawn of the player moves.
Another option - although unrealistic I bet, - would be replicating AI's target and rotate it locally; can't even imagine the consequences of that - stuttering et al.
Which virtually leaves me without ideas... so, what are your takes on this? Am I missing something? Is SetActorRotation on the server the way to go? 🤔
how are other player pawns aim directions replicated?
keep that same energy
thanks!, i have some directions now, i think i could do something like that
I confess that while writing up my question, this phenomenon just popped up in my mind, hehe. Thank you for confirming/validating it.
In the context of a multiplayer first-person shooter game, which approach would you guys take for handling automatic weapon fire , sending RPC to the server to initiate firing when the fire key is pressed, followed by another RPC to cease firing upon the release of the fire key? / Or send Fire RPC everytime when the fire rate has passed
The first approach cons is there might be a latency delay to stop shooting, which can confuse the player if a ping is a little bit high like 0.2ms but reducing the overhead
The second approach cons is there might be a latency delay to shoot, which can be a disadvantage for the player, and also there is a network overhead
Also not to mention if player times out, or really high ping like 1000 ms for a few seconds
Atleast for the last scenario, no players can expect anything from their experience in the game. Timeout is timeout, not much to do with that
I would think sending start/stop with local prediction would be the way to go
I want to use Manager singletons
Commonly people put Manager-type classes in GameInstance or maybe GameState
I heard a better way is to put them in Subsystems
However, Subsystems don't replicate
So for networking, I should not use Subsystems, is that correct?
This come up in one of Epic's livestreams about subsystem (which was a while ago, but don't think much have changed/progressed since), and I think the workaround was to reroute that particular system logic that needs replication through a helper actor. Sounds abit dirty but I guess that's the only way if you don't wanna pollute your core classes. Would be happy to be wrong about this tho!
Ugh that sounds... dirty
I see, so for multiplayer we'd best just use GameInstance or GameState?
Although I think I read GameInstance does not replicate... so then GameState?
Yepp
Subsystems in Unreal Engine are automatically instanced classes with managed lifetimes. These classes provide easy to use extension points, where the programmers can get Blueprint and Python exposure right away while avoiding the complexity of modifying or overriding engine classes. This week, lead programmer Chris Gagnon will discuss what Subsy...
check with the timestamp
Ty for that^
Depends on the logic youre about to write, but best places would be GameState (for global gameplay related stuff), PlayerController (for player related logic), or your PlayerCharacter (for different player related logic).
Still can't understand why they wouldnt even have it on the roadmap
I guess this is the extent they needed it for their own internal stuff and just left it at that 👀
Yepp.. as many other things
Kinda wanna point out that you can still somewhat avoid bloating your core classes by using actor components, they can be replicated the same way actors can and you're still separating your code and avoiding polluting your core classes.
(And later if you decide you wanna move that logic to another class (from gamestate to playercontroller or whatever), you can just move the actor comp to the other class and only fix a few minor errors. Easier than transferring whole systems via refactoring major classes.)
Gotcha, yeah I've been using a LOT of actor components
I've been wanting to refactor some stuff, specifically utilizing more event dispatchers instead of calling through functions
So I figured I'd create an EventManager to keep all the event dispatchers in one place
Which I guess I'll put the EventManager in GameState
(If you have multiple gamestates (for different game modes or w.e), it's best make a separate gamestate parent class just for global functionalities like this. )
But yeah sounds good to me! 🍻
Thanks for the help!
Sure, PM or ping if stuck c:
Replication graph isnt being initialized , i have reviewed the target files, the build file, and the default engine multiple times, but I still can't figure out the reason why
Yeah it's silly imo. Just...make subsystems replicate if we want them to.
Exactly
"So we know we have a multiplayer focused engine, but we decided not to do this but here is a workaround in case you want to do it"
Just the way he said it wasn't even on the roadmap.. like.. what?
Then the argument is, "but it's an actor!". Cool - make it work
It's your dang engine
Almost like they forgot 😛
Doesnt contribute enough to their income/vision progression so they'll just put up with a few people malding on discord/reddit every now and then.
I agree tho, in certain cases it would be a no-brainer to use a replicated subsystem. 🫠
hello guys, a question, is it advisable to use php to make the backend of an mmorpg?
Right, but i meant if player started shooting and timed out the gun won't stop firing until the ammo runs out
You can do keepalives
which can be at a less frequent interval than "every single shot", but more often than just on and off
like every third shot or smth
I wouldn't think so. PHP is meant as a pre-processor for HTML.
As i thought, Latency cause big problems, even at average like 100,80
Forsure
And the problem happens more when the fire rate is higher
for example 700 RPM
60 / 700 = 0.085 S
So player should have less than 0.085S latency to send the stop response, any time more than that will cause problems
I don't think there is competitive games using this approach
I'm reverting back to sending RPC for each fire command
I think you'll be surprised by the smoke and mirror they put up
If you have a gun with 700RPM,
and > 85 ms ping
your gun will fire at sub 700 speed
is that a good solution?
trickery
yes
if you don't have a gun that fires more than 700 RPM, and you are restricting your players to 85 ms latency
or your game doesn't depend that much on ammo and you just want to optimize the network traffic
local prediction is what you wanna do I believe
So the player experience is as nice as possible, while the server is gonna have to play some 'catch up', depending on the ping
No thats not what i meant
Its not about predicting results, I am already implementing prediction and handling the mis prediction cases
Here:
you are a player shooting with a weapon that shoots 700 RPM, and your ping is 100, if you release the fire button after 0.15ms, then your "ReleaseFire" RPC will arrive to the server late, at that time server consumed two bullets, and on your screen you consumed one, because you shot once, server thought something else because of the delay
So server will send you the correct values "Ammo", but eventually you lost a bullet
You wanted to shot one bullet not two
This may work fine with certain games genre, but not with survival games
It's not optimal either way
while you may have the correct bullet count by sending the RPC's, your gun can fire considerably slower than it's supposed to with high ping
meaning damage output is reduced
I always have trouble knowing what put inside player controller, for example the team the player belongs to, I set it in the controller but also in the player char bp (the pawn the player is controlling) does it make sense to set it two times once in the player controller and one in the player char ?
team belongs to Playerstate typically (as all players can see other players team?)
@hoary spear Yes and so what store the player controller ?
and does that make sens to also store the team in the character bp ?
Seems like i'm incorrect here.
atleast from local testing
gonna try emulating some lag
Seems I'm getting kicked x)
LogNetSerialization: Error: FBitWriter overflowed! (WriteLen: -1, Remaining: 7620, Max: 7620)
700 RPM is one shot every 85 ms,
if your ping is 0 ms that means on server side you are shooting one bullet every 85 ms
So lets say RTT is 200 ms, one way trip is 100 ms
That means you will be shooting one bullet every 0.185 S
No i think you are right
because server will always be 100 ms late
Seems the rpc's might get batched aswell ..
Idunno, feels weird. Glad im not doing any MP shooter tbh 😆wether its survival or god forbid competitive
One way
Could be
sending many RPCs to the server
but it feels dumb
Especially I'm using GAS, that means i would need to get rid of it
I think its normal, combining it with Lag Compensation might be the key
I repost I don't know if you saw it :
@hoary spear Yes and so what store the player controller ?
and does that make sens to also store the team in the character bp ?
Player controler is replicated only on owning client and server
What is your use case, like why you want to store the team in the player BP?
Controls unrelated to the pawn, stuff that only is relevant to that single player etc. Things you need to persist pawn swapping/destruction
Storing team in the Pawn seem a bit unessesary as you can GetController->GetPlayerState->GetTeam()
@dark wing I am doing a little 3v3 game, for example you can inflict damage only to the other team not your team mate
@hoary spear so I was thinking maybe it's easier to also have it in the player bp, b ut like you said i can get it from controller -> gamestate
the damage should be on server side, server checks if these players are team mates, You can have an integer representing team ID, and when spawned server will add the player to TArray of Team Struct that exists on playerstate, Team Struct will contain TeamID, and TArray of actor pointers "Players" For reference
Still haven't truly figured out this issue yet. On the client when I impulse very quickly maybe 1000 - 2000 units into something that I am also impulsing away from me when I get there, I get tons of net corrections. Is there a good way of handling this or do I need to slow down impulses, etc?
When damage occures, server checks if the player TeamID are equal, or you can do a for loop on the Team Array and check
In that case you don't need a variable on the player
Psuedo:
int ReturnTeamID(AActor* ActorPointer)
Loop through Teams
for loop in Teams.Players, PlayerIndex
if ActorPointer = PlayerIndex.ActorPointer
Then Return Team.ID;
but it's in is own bp, and this bp doesn't have the team array
Are you using unreal engine methods? "ApplyDamage" if yes then there is a reference to instigator, and you are already in the "PlayerToDamage" BP
from there you have reference to both
You don't need the player to store TeamID
let say I have a bp called damageffect
he took two actor the instigator and the player to apply the effect
here it's damage
so how my bp check the team id if the players doesn't store it
As i said
Create a struct called Team, add an integer variable and name it TeamID, add a variable called Players, set it to array of actors
Then in game state, you can add a variable called Teams, set it to the Team struct and set it as array
Mark it as replicated, so all players receives the data
You can also set it as RepNotify, if you want to run some kind of logic every time the Teams are replicated
Then in game state add this logic
@dark wing Ty !!
node.js? What do you recommend?
It depends
How many players?
And what exactly do you want to implement in the back end
Will it be the main master server?
There is a lot more than just that
Node.js would be a good start
The idea is to make a dedicated server that is authoritative, that can support 1800/2000 players
So master server
This video is an overview of the Open World Server 2 (OWS2) system.
OWS 2 Installation Instructions: https://www.openworldserver.com/getting-started/
OWS 2 Source Code: https://github.com/Dartanlla/OWS
Open World Server Discord: https://discord.gg/qZ76Cmxcgp
- There is a new series in UE5 and OWS 2 now: https://www.youtube.com/playlist?list=P...
check this
I did see it, I'm in your discord haha
If I'm going to continue with that, thank you.
my pleasure
On a performing aspect is it really bad to make cast to ?
How often are you casting? and what is your use case
I don't know it's more a general question
lets say a skill touch an actor I try to cast to the player bp class
It depends
Its fine
Its better to not use casting on tick, you can cache the result once and use it
But all other cases are just fine
ok ok ty !
In C++, not in the slightest. In BP, the only real concern is creating a hard reference because it can cause the engine to have to load all the assets for w/e you're casting to
requesting some guidance , i want to add voice chat in my game , anyone know a way to add that ?
Fwiw, Google should totally help you cause this is a solved question
UE has voice support but it might need a Subsystem like steam to use it over the net
Been a while since I used it
can i use the EOS voice chat system while using steam sessions ?
That I can't answer. I simply don't know.
But you can ask that in #epic-online-services or #online-subsystems . But again, might take a bit to get an answer if at all
ah absolutely yeah , thank you !
Why my characters are floating from the point of view of the other player ?
make the capsule visible
if the capsule looks right then its on your component or animation setup
The capsule is in the right place. Which component ? I didn't touch any animation blueprint yet since the beginning of this project and I didn't have this issue before today 🤔
the skeletal mesh
show your character in the bp editor
Something is moving it somewhere
I never moved the mesh through code so I don't know why I have this issue
I want to add different walking speeds to my character. Whats the best way to handle this so that it is replicated correctly without corrections?
Override GetMaxSpeed on the CMC?
Its really that easy? I was looking into saved moves.
Its that easy.
You can also override the acceleration etc
There are functions for those types of properties as well
Does anyone have any good ideas on why Lan multiplayer wouldnt work , or would stop working ?
its not specific to my game, ive tested another blank template project i got from the asset store that 100% used to work , but I havent tested Lan play in some months till now, ive tested Steam networked builds and those work fine.
but regardless of game , Lan session are not working. im not sure if i need to contact my provider or manually figure out how to open a port or something
Moving here from #cpp since this is a replication question. Can a replicated UObject also have it's own replicated subobjects? I don't see any ReplciateSubobjects() method defined on UObect, so there's nothing for me to override.
It appears most of my issues with rubber banding come from player to player collisions when impulsing at them. Is there a better way to handle that? Take off blocking collision and impulse on overlap?
No, they would need to be routed through the Actor thats replicating the parent UObject to begin with.
The same way that it was replicated
OK. Then what about my specific situation
Class A includes a TArray of pointers to class B. Both are intended to be replicated UObjects. Would that array get replicated anyway without a ReplicatedSubobjects call?
Err, no sorry. NOT an array. Just a TOBjectPtr<B>
I was thinking of a different class for a moment
Specifically, class A has
UPROPERTY(Replicated)
TObjectPtr<UDcsInventoryItem> InvItem;
If I have to I can make class A be an AActor, though that seems a little silly since it will never exist in a level.
Whats a consistent way to map some data to a client? I just need some kind of ID that consistent
It would be in UNetConnection right?
I see this but it mentions local and server only
UPROPERTY()
FUniqueNetIdRepl PlayerId;
PlayerState seems to have what I am after I think. If whenever someone experienced reads this could just let me know if I am on the right path or not I would appreciate it
You want to use the FUniqueNetId
FUniqueNetIdRepl is a wrapper around a FUniqueNetId that allows it to be passed across the network.
A FUniqueNetId is a platform Id, like your Steam Id for example.
Alright that sounds perfect, Ill look around for it but do you know where its stored? Or is it something I create passing something through in the ctor
For the local player you want to use ULocalPlayer::GetPreferredUniqueNetId()
When on a server you want to use their NetConnection
UNetConnection::PlayerId
Yeah thats awesome, what if I wanted client A to store some data about client B in a subsystem, I was planning to map their ID to the data but what you described sounds like it works locally or server only
You can also use APlayerState::GetUniqueId()
That sounds like it
So I'm working on my lobbies and just I'm curiuious. If I understand the Online Subsystem is used to communicate with the various services like Steam and Epic. So now, why would someone want to avoid the Online Subsystem and just work with say Steamworks SDK directly? Would it just be about optimizing and not having all these unused parts of the Online Subsystem?
It'd be dumb
The online subsystem is there just use it
Use what you need and don't worry about the rest, won't matter
That's what I thought. I was looking at youtube videos and saw "How To Integrate Unreal Engine 4/5 with the Steamworks SDK Directly (No OnlineSubsystem)" and was curious why but in the couple minutes I watched he didn't say aha
@glad robin The only reason you wouldnt use an OSS is if it doesnt expose something you need from the platform specific API.
There arent many reasons not to use the integrated OSS's
anyone wanna quickly test my project?
is it xz utils 5.6.1?
Yeah lemme just run an executable from somebody who joined the server today
lol
@lusty kelp This server is full of your peers, not your personal testers. If you need assistance with development of your game, make a Job Listing.
ok
Are "Structs" replicatable through blueprint ?
Any struct marked as a USTRUCT(BlueprintType) can be used and replicated in Blueprint
I mean in this case the struct is created in the editor (and not c++)
Keep in mind that the properties within the struct must also support replication.
Yes, they automatically support replication.
in my case it's just 2 booleans
Thank you 🙏
Why is "Client 0" printing twice ? 🤔
yes, 1 being the host and the other a client joining him
so thats why
Basically 2 chars on one client
cool somebody who do the same thing as me, good luck getting somebody to test with you
Truth being, most people either have a friend to test with, a co-worker, or simply a second PC or VM if needed.
Alright then I have no clue on why it still doesn't work even if now the client and the server value of the "CurrentCamera" are in sync...
A guess would be camera loc is not updated on server
loc = location ?
Y
how is that not updated on the server when the Character himself is replicated ? so shouldn't children components of it being replicated too ? I also tried to enable replication on both camera and the issue still persists
Also the raycast logic is done on the server 🤔
I can't find where the original post about the issue is
Wich one ? There are 2 cameras on the character, 1 for FPS and 1 for TPS and CurrentCamerais a variable handling which one of the two cameras is currently active
Are any of them using ControlRotation?
yes the FPS one
And which of the two gives you problems? Both? Or just one of them?
the FPS one
You can try simply using GetBaseAimRotation
Instead of the Camera Rotation
But you are also having issues with the location?
I don't know. The issue I have is the raycast going always parallel to the floor in FPS camera instead of where I'm looking at.
Hm hm, try GetBaseAimRotation for the Rotation
so instead of "GetForwardVector" ?
it does work, thanks 😄 But why is that ? 🤔
Eh, something something Pitch
any good resources on how to properly end sessions, so that they don't hang around and cause weird issues when trying to create a session with the same name?
Isnt that simply DestroySession ?
Client call -> Leaves session
Server call -> Makes all clients leave session
yeah i think i should be calling it right now, if the server destroys the session, everyone is kicked out, but there's some stuff hanging around it seems 😄
also the session interface only takes the name of the session as a parameter, is there some way of ending a session for a specific player id?
and is leave session the same as destroy session? 😄
Last I used it there was no leave session 😮
but perhaps its just to avoid confusion ?
Using a plugin ?
nope, just built the subsystem based on a tutorial for steam.
so should the link to Jambax's website be removed from the pins, and replaced with the other link you gave?
cause I was about to follow Jambax's post not realising there is the newer way (which I will now follow instead)
How dare you ditch our legacy
I think it's good to keep it for the meantime for people on older versions
If I'm not wrong he also said the other day that he's going to do something about it
arh ok. Yeah maybe just a red box at the top of the web page itself saying "if you are using 5.1 check this out" or something
@chrome bay sorry, but an ez mode suggestion/fix you might like to hear ^
Hi everyone! I'm making a two player local game but for some reason the second player can move the first player's camera as well and make him jump. Has anyone had this issue before?
This seems super specific to your project, so you'll have to show your work
The rare splitscreen/local MP question
Hi there
I’m having trouble about steam friend list. I wanted like there’s a button called invite and after you clicked on it the Steam Overlay FriendList pops up
Hello, does anyone know whether Epic changed how they handle widgets on seamless travel?
I always knew that they are persistent (https://wizardcell.com/unreal/persistent-data/#should-userwidgets-persist-seamless-travel), however, it doesn't look to be the case anymore. I have made a bare example with seamless travel (screenshot), but upon it the widget gets removed mid-travelling (on transition map). I have checked the SeamlessTravel in GM.
Upon executing the console command, this is triggered
void UEngine::TickWorldTravel(FWorldContext& Context, float DeltaSeconds)
{
if (Context.SeamlessTravelHandler.IsInTransition())
Context.SeamlessTravelHandler.Tick(); // <<< Following the chain, it calls UGameViewportSubsystem::HandleRemoveWorld
// ...
}
and then
void UGameViewportSubsystem::HandleRemoveWorld(UWorld* InWorld)
{
// Gather all widgets...
for (UWidget* Widget : WidgetsToRemove)
{
Widget->RemoveFromParent();
}
}
So Player 2_BP is a Copy of Player 1_ BP (ThirdPerson_BP). This is the logic for spawning player 2 which is in the Player1_BP.
why would each player have a completely different BP
GetPlayerController(0) is dangerous for MP
and in local MP, that will always be the first player
This is the custon event Adjust player logic in the game mode.
I just started using Unreal recently, so I'm trying to figure things out.
Sorry to necro this comment - I'm currently researching (searching) for the right way to do some inventory stuff. What you wrote around this comment is how I'm approaching it at a high level - so I'm feeling good I'm on the right track.
Just wondering if you ended up releasing any of this code so I could browse it? All good if not, just thought I'd ask. Thanks.
I haven't as of yet I'm afraid
Is there a way to no notify a server that variable has been successfully replicated in C++? I've heard that Blueprint's RepNotify can also fire on the server, is there an equivalent in the C++(ReplicatedUsing is firing only on the client, as far as I know)?
Just calling it manually is how one trigger it on the server
OnRep_MyRepFun(const var oldVar)
What you put in 'successfully replicated' might ofc be something else
The BP version is not that, fyi
I need to be sure, that varibale on the client received a replication. I wonder if there is a way without sending an RCP, if maybe unreal is doing it by itself
There is something there i guess, as it picks up if package is lost etc
There was some PostReplicate talk a while back, but got no clue when thats called
Guess one would need to dive into the replication system
Seems there is no PostReplicate
UNetdriver.h and Netdriver.h got quite a few comments about it
Would there be a functional difference between creating a dedicated server build and a regular multiplayer build with an observer mode? I already need to add an observer mode to my game (I'm making a text-based college basketball sim and if a user coach is fired they need to be set to observer mode so as not to be able to control any teams). I think the observer mode route would mean the person hosting would have to render the graphics as opposed to a dedicated server build, but since its just text-based I don't think that would mean much, could be wrong though.
My question is more - why are you using UE for a text-based game?
Seems like massive overkill
best fonts ever
Well, a dedicated server would not be able to render any graphics to begin with. The server can't directly interact with gameplay either.
If you need to use a dedicated server, you could check if the hosting client has the same UniqueNetID as the server, and then put the client in observer mode.
If you use a listen server where the host and the client are running the same instance of the game, it would be easy to create an observer mode for the host.
I don't see any reason for using a dedicated server here, unless you are on some tight ping/delay restrictions. Just keep in mind you can't transfer the 'host' role during gameplay, so it may not always be the same person as the one observing. But yeah a listen server approach seems the best fit here to me.
Yeah. I guess I misunderstood a bit also, because if the user coach can be any player regardless, going in or out of observer mode as a dedicated server wouldn't change anything. You'll just deal with every player interacting with the game as a regular client, if there's a dedicated server.
I do agree a listen server would benefit, as it's more convenient to host for community members, and that there probably isn't any real-time gameplay (correct me if I'm wrong) that would require the sort of performance that dedicated servers are useful for.
Unless you want to be really strict about the security and validity of user data, and only allow trusted parties to host servers (dedicated).
It definitely is overkill, but its just the engine and the programming language I was familiar with, and seemed to be the best as far as easy to set up, built-in multiplayer.
I do have a listen-server setup working right now. I was just planning on adding a dedicated server setup in the future, but had a thought last night that I might not need one if I can easily adapt my listen-server setup to have a pseudo-dedicated build as well.
I understand where the overkill take is coming from, but I think what matters most is what the person is most comfortable/skilled at, and that the tool can accomplish the task without a large amount of wrestling
the component spawns well on server and clients, but when later setting the Material var, the SMC var is null on client
Note : both var are set repnotify, the code is called some time after both player are created
any ideas why?
Are you setting the material about the same time that you're spawning the mesh component?
right after
So then there's no guarantee that the static mesh component has been created by the time the OnRep triggers for the material.
you are right
When the OnRep for the static mesh fires, check if it and the Material is valid and if so, set the material on the static mesh component.
When the OnRep for the material fires, check if it and the static mesh is valid, and if so, set the material on the static mesh component 🙂
i'll do that
now i got another issue, destroying the comp on server doesnt destroy it anywhere
(i checked if i had multiple stacked comp, i only have one)
i tried from events, it get fired on server but the SMC is still there in game
@dark wing Sorry to bother I ask you a question about handling team yesterday, I have another question on it, may I ask you ?
yes
@dark wing I have done like you say, my game mode choose which player goes in which team, he set the player state and told the game state a player join a team, in the game state I store a map, actor -> team
I made a function in the game state, to find if two players belong to the same team
So your game mode grabs the team array, and assign the player to one of the teams?
why are you setting the player state
show me the bp
or the code
ok if you want I can go on a vocal channel to share my screen as you want
Bump
🔊 Careful loud Sound ‼️
Does someone know why screen turns black in splitscreen when debug appears?
No, but nice anims 🙂
thanks
created a brand new project and the same thing happened
debug on splitscreen makes additional local players black
While testing my game, I noticed that a variable (ECombatState) was not being replicated back to the state I programmed. All configuration parts (ComponentReplication, GetLifetimeReplicatedProps, etc.) are working correctly.
The behavior is simple, I press a button to change weapons, perform the swap and change my character’s state to ECS_SwappingWeapons (on the server). At the end of Swap animation an AnimNotify is called, changing back to ECS_Unoccupied.
It works correctly when my main computer is the HOST and I’m testing it on my notebook as a CLIENT, but in the opposite situation it doesn’t work, the SwapFinished function isn’t even called (this function is called through an AnimNotify) at the end of the swap animation.
Could this be an Anim Notify problem, or a replication problem? and if it is replication, would it have to do with the fact that the HOST is a weak computer and is not capable of replicating the variable back?
I'm struggling to get a CheatManager set up for multiplayer. I have the client running EnableCheats and am able to define Exec function in a custom CheatManager BP class that I can call from console, but I'm not sure how to get my calls up to the server to do the actual work since nobody "owns" the CheatManager object. I'm sure there's a simple way to set this up but I'm having trouble finding it.
Actually, I would think the PlayerController owns it since I have the CheatClass pointing at the custom CheatManager. But any attempt to call a "RunOnServer" event is still called on the client.
We added an actor component to the player controller for this exact reason.
This is the path I was just starting on I think. Basically have the CheatManager call into a component on the PlayerController to RPC up?
You don't need an ActorComponent - it can be PlayerController straight up
There's no replication, but marking a native UFUNCTION as BlueprintAuthorityOnly works
Yep. Acror component helps keep it separate. May or may not be of interest to you.
Which just uses ServerExec from the player controller
At work, I did make BP run on server events get the same treatment
Wait, what
So can you have static functions BlueprintAuthorityOnly that will be bridged automatically to APlayerController?
Look at UCheatManager's ProcessConsoleCommand or Exec function (I forget which)
Ahhh you're specifically talking about UCheatManager
And not static
Sorry, I got hyped for a moment here
I mean, not UCheatManager but ServerExec. I misunderstood it.
Whew awesome. Got a proof of concept up and running now.
Setup is a CustomCheatManager with Exec function that grabs local PlayerController, gets a DebugCommandsComponent on it that can then do RunOnServer events. Does that seem reasonable or am I adding unncessary steps? I do want to keep any debug/cheat logic local to a single component.
Funny how splitscreen in ue5 is tossed aside. I don't even have all the extra options to fix my hud stuff.
What HUD stuff are you trying to fix
UMG should support split screen just fine
umg aside, there's an annoying thing that the screen turns black for the extras local players on split screen everytime a debug appears on screen
now the problem with umg: if I get the same widget from the player 1 to get into the other local player 2, the resolution get all messed up. Also the anchor scale with the render and I can't setup stuff on screen for any resolution
If I scale down that, this happens
Adding the UI to the PlayerScreen instead of the Viewport for any per-Player UI should be enough. This doesn't remove the requirement for you to design the UI to match the screen.
I developed UMG UI 4 years ago already and had no issues with this. You will have to design the UI different if you have 4 players vs 2 players vs 1 player.
Yeah that can happen. Not sure that was a thing back when I did splitscreen stuff.
But I vaguely remember stuff like that
I'm already using the player screen, wish it could be more modular, like make all the variations for all the splitcreen cases already inside the UMG
It's a bit similar to how WebDevs have to solve Desktop vs Mobile
The layout will have to change a bit depending on your UI
fwiw you can make different versions and make the inner widgets as dynamic as possible
e.g. your Characters selection can have an exposed NumColumns variable
Or EntryWidth and what not
And then you can try to make 3 different versions (think 3 is enough, you need one for the big screen, one for the horizontal screen that appears for 2 and 3 players, and one for the tiny screen that appears for the other two players of the 3 players and for 4 players).
You can also try to put everything into one widget, and maybe work with a grid
I already found a solution for my case since I dont want to create multiple widgets for all the cases for the splitscreen manipulating the render scale and setting all my UMG anchors to 0,0.
that's so true
The information that you can easily display in the normal 1 Player Screen gets too tiny in the small version.
And doesn't look good in the flattened version of 2 players
We ended up designing 3 layouts iirc
You can try that with a WidgetSwitcher
Or by altering the Row, RowSpawn etc. of a Grid
E.g. put your elements into a grid and alter the values based on the total number of players and the index of the player itself
But that all depends on your UI
if that supporst that idea
In the end I think I'll do what you're saying, but this is ok for now just for testing
Actually, now that I'm saying that, I think for at least the in-game UI, we made sure the HUD works in all 3 ways
in-game being the HUD with like numbers
It was an arena shooter
With weapon, health etc.
The UI for selecting stuff was more custom, but I can't find images/videos of that anymore
The project never shipped. Don't know what my client back then ended up doing with it
that's alright
thanks for your input btw, I'll plan a rework on my hud when I got the time. I'm currently converting all my project to UE5 by hand since I got a nasty problem with corrupted files
Like that somewhat worked.
But already got a bit cramped on the side for the weapon select
true
Steam isn't offering a lot of pixels
https://store.steampowered.com/app/613620/Hoverloop/
Feel free to check it. Somewhere around 40 seconds in the first video.
I somewhat made 90% of the games code iirc. Just the Art and AI isn't mine.
Idk what state that game is in on Steam :D it's long lost