#multiplayer
1 messages ยท Page 268 of 1
Why?
well yeah, it's not supposed to when it's out of relevancy range
animation simply will not be played and AI will come through door without any animation
If the client receives the information in the MIDDLE of the animation, then he should start playing it from the MIDDLE.
Multicast has no such options
So replicate that state and do that on beginplay. Doesn't need an onRep.
beginplay? so the door will only open once?
the animation is short enough if the player comes within relevancy range while it's playing then it shouldn't actually matter
it should just show the correct open/closed state
I want a smooth client experience
Make a struct. Opening or closing and server's played time. Replicate that. Not OnRep. On beginplay, play the montage with the offset based on the data.
ALSO multicast this when it changes so that clients in relevancy get the update as well.
Door's state is already replicated properly
well relevancy should hide that
for what purpose beginplay?
Ai wanders around and when it wants to pass through the door, it will be opened.
Beginplay will fire only once
OnRep() is cheaper than multicast though
Once, every time it comes into relevancy range of the client.
how is it "cheaper"?
They're really not.
Replciation is outright fucking costly.
More stable for data consistency, but it is not cheaper than an RPC.
beginplay doesn't get triggered every time when client comes into it's relevancy range
It is supposed to. If you leave relevancy it is supposed to close the actor channel and this normally destroys the actor on the client. On returning it respawns it and calls PostNetInit which will run Beginplay again.
maybe it's supposed to, but it doesn't.
As can be seen in the video, red sphere is drawn when client connects to the server, but it doesn't fire every time when player comes across relevancy range
that circle seems way too small? Did you lower it?
I've set small NetCullDistanceSquared for demonstration
1000^2
hence the radius is 1000 uu
Wait, you're in viewport. O.o What are your PIE settings?
sometimes for testing I enable network emulation, but in the video it was disabled.
I still think my solution works better with OnRep than multicast. I'm just replicating the structure with data about what should be played and when, and as you can see in the video, it works. When the client crosses the Relevance Range in the middle of the animation, it replays on client correctly and not from the start
btw I've made custom AIMovement component derived from UPawnMovement, which interpolates the server data to the sim proxy, supports root motion, and I think is way cheaper than CMC when it comes to dozens of AI pawns
So rep notify should be used for doors and such. Things that toggle. But what about for picking up items?
Depends.
inventory is just an array of items, so you just call an AddItem() on server and replicate it's state to client.
If you need an event when data changed on client, use repnotify. If event doesn't needed, simple replication is fine
For more perfomance can be used FFastArraySerializer
FFastArraySerializer is needed for delta replication (?)
I remember that someone said on this server that a regular TArray also supports delta replication, but not by elements, but by indexes. And when the element is, for example, deleted, many indexes are changed, and these indexes are replicated
Iโm not doing an inventory system I should have said. In my game you have 1 item at a time and I do it by interacting with an actor that adds a component to the player
than it should happen on multicast, I suppose
if you are adding component every time and not just replacing the mesh or something
Currently I have it set to add the component to the player on a rep notify because I was told that if it isnโt rep notify and I pick up an item (which destroys the actor you interact with) then if someone joins after I destroy the actor then it wonโt be destroyed for the client
yep, that's true
Okay
So I will keep it that way
I will come back later showing my BP code so I can get validation that it is correct
Multicast is just an RPC function, which is called only for connected clients.
Reliable multicast guarantees delivery to connected clients. In case of failure, the engine will simply try again until it succeeds
does Trajectory ever change?
like do you have gravity?
or does everything fly in a constant velocity in a straight line
If that's the case, then what you're dealing with is the fact that everything is moving along the same paths on all machines, but not at the exact same TIME on all machines
The easiest approach is to let the firing client initiate the hit, and just have the server ok it with a sanity check. It's impossible for every screen to agree on every detail if you have prediction.
Aye, straight line projectile with no gravity. I figured it was a position mismatch but I can only reproduce this issue about 1/100 times.
Appreciate the suggestion, will give it a shot.
Just keep in mind that there are 3 views of the world at any moment in time.
The shooting client sees themself in the future and everyone else in the past
The server sees everyone at some time frame
The shot client sees themself in the future and everyone else in the past
Shit gets complicated. The timelines are all tangled up. There's really no one source of truth, you need to make certain adjustments so everyone feels like they're seeing the real thing.
Anyone know how to fix this?
check replication settings in actor. Maybe it set to bReplicates = false.
btw, I would made "Planks" or whatever it is a custom component with it's own heath.
It would be easier than iterate through all every time.
Yes you can create custom replicated StaticMeshComponents or any other components with their own parameters.
What's broken about it
After asking in #gameplay-ai I was told to come here
Context is trying to make an AI that, in case of unstable network from host (due to P2P), the bots would be able to temporarily be client sided while the host network stablises
Which would be the best approach for that?
Make AI logic and behaviour from scratch while building such system with network unstablity in mind
Or somehow change original host to client, and then when original host would be stable again, swap again
Is that a good idea? This will potentially cause severe out-of-sync
-
Unreal doesn't support P2P out of the box. It is always a server-client architecture unless you do custom networking.
-
Doing host migration is fairly difficult to do. There might be some plugins out there that handle it, but your mileage may vary. Most games, even outside of UE, just don't do this. I think it is also difficult to do in UE overall, for fairly little gain for co-op games.
-
If the host has an unstable network - people are generally fine and understanding that it isn't the game's fault.
The core of the problem is making sure all state is 100% sync'd. So you'd need to work out how to get the server only stuff to the client to sync and then switch host connections. It isn't only AI that you need to concern yourself with - you also need to think about stuff like the GameMode.
It certainly falls under the realm of pretty advanced networking knowledge/experience in Unreal.
It is just in the case of extreme network instability
This back up plan shouldn't be active in normal play
But it is just personal preference, picking severe out of sync instead of everything freezing for several tens of seconds
So it would be much easier to do some custom bot behaviour system than some custom networking behaviour
Neither is going to be easy in the slightest.
AI logic only exists on the server. You'd have to set it up some way for the AI's current plan to be sync'd to the client at the time of bad network stability. Which is a problem in of itself, because the client has to wait to get all that state information. But the network stability is already bad, so that's going to suck.
Then you have to get it where the client's AI will resume exactly where they left off.
A quick, probably terrible route, would be to tear off the AI actors from the host and then spawn the AI Controller on the client and then try to resume the stuff like that. And then when networking stuff is fine, try to relink the AI to the original host.
But even that did work, that'd only work for like...one player at a time.
So, already a headache with just 3 people.
Now, let's say you were able to get it to work
The AI controller can be spawned from client?
You still need the client's AI to communicate with the other client's AI
And clients can't talk to other clients directly. Has to be routed through the server. Which, in this case, is the player that has unstable network conditions.
Yes.
But it'll only exist on the client
And it won't be in sync with the controller on the server necessarily.
Might be able to get it to link up though.
But then you need to also make it work with multiple clients
And you also need to mess with net roles and things like that.
That's fine, the idea would be AI controller would only manage behaviour, all of the bot's states, data and variables would be outside of the controller
And once network gets stabilised, variables would be replicated normally again, and the client's controller would be deleted and replaced with host controller
I don't recall anything in the Controller/AIController spawning process that specifically prevents clients from spawning them.
That is the common setup and it can still be quite the headache to do what you want to do.
Oh yeah, I know I'm heading into a headache, I'm just picking the lesser of 2 or 3 different headaches xD
There is no lesser unfortunately. What you are asking for is quite the ask. And the reason it isn't really something people do is because of said headache for such a marginal actual gain. Generally there are better things to be spending your time on.
Not saying to not do it mind you.
Thank you, this is kinda weird and stubborn ask, but I appreciate any recommendations on this
So the """easiest""" method would be to code a removable AI controller that could be swapped out with a client ai controller, then swapped again with the proper host controller
Probably. I'm just spitballin' here while my code at work is compiling ๐
I mean, this is already way better than coding a whole AI behaviour tree from scratch, I'll take notes thank you very much
Well, if you are trying the tear off route - that is the method name on the actor btw, "TearOff". It is a virtual as well.
This is 100% C++ territory as well.
Lol, nice
Hi,
I have the blueprint code (see images) in my game instance to start a new multiplayer Steam session. However, when I click on the button for this in the debug build, the world flashes briefly and I end up back in the main menu with an error message (see images). The logs also reveal that the multiplayer session is created successfully, but there are problems loading the map as a list server. I would appreciate any help. I've been stuck on this problem all day :/
Nevermind found an solution.
Maybe one day someone with the same problem will be searching the discord looking for the same solution; perhaps you should share it instead of simply announcing to the world your geniusness rather than hording it to yourself
yeah sorry, the problem was that I accidentally enabled the Steam sockets Plugin, what caused the issue
Congrats on the resolving the issue, best feeling in the world!
Hi All,
So I've decided to tackle multiplayer which is turning out to be harder than I expected. I'm still trying to wrap my head around the whole replication a bit.
How would I go about replication this to a client?
(This runs in the tick of another actor called Conveyor, Item is just an AActor* )
Item->AddActorWorldOffset(Direction * NonPhysicsItemSpeed * DeltaTime);
It's probably something really simple but I'm learning C++ which I've improved greatly at with this project but MP stumps me.
depends who owns the actor you want to move, also is Item -> bReplicatedMovement set to true
Yea it's set to replicate. So I believe that makes it owned by the server? The other Actor is owned by the Client in this case (as it's a character I'm testing with).
there is bReplicates and there is bReplicatesMovement
Just because something has bReplicates = true doesn't mean that server has authority of it
The actor you say is owned by the client, but who spawns it? The server or the client?
I ended up using the 3rd person template, movement works fine for the character as normal so I would assume the bReplicateMovement = true.
Server spawns it as it's the player. (if I assume correct)
Other actors that land on Converyor that have bSimulatePhsyics=true works fine, it's just the item/character in this case.
and what behavior are you observing on the server vs the client?
Server is smooth, client is jittery, which I believe is a replication issue (from when I mucked around with MP in the past using Blueprints)
jitteryness means that there is a disagreement between where the server says the actor's location is, and the client says it is. So the two "fight" over the location, and because they disagree, you observe that
Tick occurs on both Server and Client, but at different times
I should have stuck to blueprints ๐ I can debug that faster/easier half the time
So I'd imagine you're changing a location and those locations are different between server and client
I didn't know that
No. Blueprints have a place, but actual programming is not it
Especially multiplayer
Yea I decided I had to learn C++ for bettering my skills.
C++ is where it's at.
I'd say it's easier to maintain and debug than bp's
just a steeper learning curve. Plus you're compounding the issue by learning multiplayer simultaneously
Agreed, my first game I made is messy with all the BP's
So, back to that issue, do I have to do a replicated function like UFUNCTION(Server,reliable) void MoveItem(); or could this just be a tick issue? I've tested it with other replicated variables I've done but couldn't figure it out.
Can someone help me
I want to show everyone exept me in red
Just doesn't work on server
Calling a reliable RPC on tick is a bad idea - reliable RPCs get put into a buffer, and when that overflows (because reliable rpcs shouldn't be called on tick) you'll get a very fast disconnect
@frail temple
when is the function called?
Begin play
@frail temple if you need this actor to be consistent for gameplay reasons, there are some ways you can smooth out the logic - but if it's just some window dressing, just do the movement on server or client and separate the two so there is no fighting
Needs to be consistent for gameplay, unless I just make it so the character actually does nothing when stepping on a converyor which is one way around it I guess.
Oh WOW, thanks
I used AcknowledgePossession for client, but that's not BP exposed. If cpp ain't an option you gotta look for other event.
I put 0.2 delay but wasn't enought and i try mor, this work
that's a "bandaid" that isn't even a bandaid
breaks easily if player have more ping or take more time to receive the data.
use appropriate event, don't hardcore some delay.
Well there is a ProjectileMovementComponent that comes with built in physics with replicated net correction. Try that.
I've used it before for some cheap projectiles like grenades
I'm signing off for the day so good luck, if you have additional perhaps someone else here can help, best of luck
Thanks for the help, you've also taught me a few things about MP and C++, appreciate that.
show the path from whatever event to this code
That person did it on begin play, it all make sense why the code doesn't work.
Btw Adriel, if you use GAS do you know why would abilities not replicate to clients when Server run GiveAbility?
^ (Apparently it doesn't replicate to proxies, nvm)
begin play should work barring a race condition with being possessed
That's the exact problem though. BeginPlay isn't guaranteed to be called before/after possession.
What would be the best event for "The thing is totally set up and ready to go now", controller changed?
AcknowledgePoessession == "Hey client, this pawn is possesed by your controller"
It would be safe to call IsLocallyController by then.
I just updated to 5.6.1, and I'm getting multiple "MissingLevelPackage" errors on the server when my client attempts to join in PIE (just Play From Here with 2 players, Listen Server)
I'm using World Partition, has anyone else had issues with this in 5.6.1? I had no issues like this in 5.4.2.
The error is more specifically here in ServerUpdateLevelVisibility:
any reason why i cant click this??
nvm I'm dumb, you cant click it if you're not set to multiplayer mode, order matters for whatever reason
Hello can someone help
Why my unreal engine 5.4 online beacons eos net driver eos subsystem steam listen server + client not work on steam or standalone build
Eos net driver -> not host beacon at all;
Ip net driver -> host but clients canโt join
Beacons work with aws dedicated server + client connection but why not with listen server + client steam
Would love help about this process because the beacon workflow is great and it works locally but not in steam or standalone ๐
I'm not used to using EOS stuff. But usually if you're using a Steam build, you need to override the net drivers to use Steam's. Same with non Steam running Standalone, you usually use Null subsystem and default net drivers unless you always want to be logged into Steam.
it's because we're using the combo of eos subsystem for steam to allow crossplay
so we didn't switch to the steam subsystem and using eosnetdrivers for the beacon
Dropping this here. I published an article on best practices working with CharacterMovementComponent. I hope you'll find it useful:
https://dev.epicgames.com/community/learning/tutorials/ywD1/unreal-engine-best-practices-for-networked-movement-abilities
soo glad I'm on today to see this. Bookmarked.
I am having an issue where I have an array of ACharacter AI that I am pooling. Once dead I set a bunch of default values back on the character, call SetNetDormancy(DORM_ALL) and then FlushNetDormancy()
When I "unpool" the AI I do the inverse where I set the state to SetNetDormancy(DORM_Awake), set some default values and then call FlushNetDormancy (I also tried force net update) but for whatever reason on clients sometimes the actor transform is at 0,0,0 and not where it should be (the listen server and some clients can see the AI moving and following its move to command)
What should I do here?
Before I continue and start doing all the other stuff, can I get confirmation that this is correct? So I'm changing the Player movementmode to flying via entering an overlap. It works but I don't know if I'm doing 1 too many calls or something.
Let's just say I spent so long not realizing I was trying to just change the modementmode on the client and not server.
You don't really need a server RPC for that, they will overlap at the same time already and the server should be the one telling the client what movement mode to use
So I can remove the whole ServerGravityEffect_Implementation() as that isn't required as the server is calling Player->TriggerGravityEffect(bEnteredZone);
You still want it to be "in-sync" but rather than the client telling the server, the server should do it and tell the client unless you have some custom prediction thing going on but you need to handle cases where the prediction is wrong
Thanks for the assistance, I currently have no prediction stuff going on and I'm not sure if I will (I'll find out further down the track). Learning something new everyday with multiplayer stuff, a little more challenging than I expected ๐
Is changing modes part of the client prediction model for CMC?
I'd think it was but I haven't messed with cmc much
isn't that baked into the "move"?
Not sure anymore. Maybe the Client tells the Server the mode, maybe not. But it also doesn't really matter in this case.
CMC is very much about the end-location of a move being the same.
If you, for example, have a sprint mechanic with stamina, even if you potentially sync the stamina on a correction, if you at some point have 100 stamina on the server and 50 on the client, and you sprint, as long as the sprint works (e.g. costs 10 stamina) on both sides, the end-location will be the same and no correction will happen.
Similar, if you are in a different movement mode, it can be that you end up in the same location, but once you don't, you'll get corrected and receive the proper Server movement mode.
For almost everything regarding "walking into something", there is usually no need to predict or send RPCs, because the idea is that after a given move, Server and Client will be at the same location, which in this case is inside the overlap. So simply modifying the CMC on both ends (e.g. refilling Stamina, changing MovementMode, applying an Impulse like a jumppad) is enough.
Hey guys , I wanted to know if anyone has any idea how to implement a multiplayer system, for individual ownership of things like xp, inventory etc, for each individual user for test purposes which would later be implemented in a database
I have like a master data table for xp, inventory and other components I'm using but how should I make it so it can be used individually by a different user
Some things can be saved persistently but some are session only, but it fetches everything from the master table so every user would be getting the same things I'm getting
How should I setup this to be implemented with my current logic
PlayerState and savegames
data tables are for source data, not a live database
you could incorporate a database but probably don't need to for a while
It is. CMC will predictively change modes when walking off a ledge for example.
Server will send a correction if that same move ends up in a different mode. So if client move x puts it from walking -> falling, while server stays walking -> walking, that triggers a correction
Yeah so in homie's example you'd expect the overlap to happen on both sides triggering the mode change on both sides and everyone's happy
got it
Oh yes if you did that on client only, the server is gonna tell you "no" the very first move that arrives on the server ๐
Yup, that's what happened pretty much ๐
You know what I hate, I'm like "Ohh I'm finally starting to understand this a bit better" then the next thing I try to do doesn't work and it's a whole bunch of debugging/understanding of whats going on.
I hope my tutorial (see above) and the links in there help then. Because I've felt that pain with CMC and want to make it easier for others
I'll give it a read through, but I hope I'm done with the CMC for now.
FWIW, take this with a grain of salt. But a birdy mentioned that beacons may be broken for EOS in general.
How can I make replicated inventory but days gone style? Does the backend work for the inventory system remain the same and only UI & few changes?
Pretty loaded question - inventory systems are inherently pretty complex, and I'm not sure what you mean by 'days gone' style. Like... you mean Baldur's Gate or are we talking Zelda? One way I've typically done it is make a UInventoryComponent on the PlayerState and replicate the inventory that resides within there (usually via a TArray of a custom struct, like an FInventoryItem struct and have that data populated via data assets and just grab the CDO data as required for effects, audio, icon etc)
Thanks to Reid for the clip. Watch live at https://www.twitch.tv/mackdoogle
Yeah, no reason why that can't just be a normal inventory system.
Maybe you don't need a whole inventory system, if it is legit just that weapon wheel, but yeah.
Oh my bad I thought you meant "days gone by" like old school lol Yeah well I'm not sure you need the inventory to replicate necessarily, rather you could replicate what the current weapon is for example
It's not only weapon wheels, that include Molotov, bandages and as well as crafting init
Weapon Wheel is obviously going to be UI and is a different topic
like I said, if you use bandages, all other people really need to see is you doing the bandage animation and then locally apply the effects of the bandage along with the animation + some validation server side
There are 2 inventory, one is hidden and used as crafting and other is visible and usable such as weapons, grenades. Hidden one is only shown as text such as amount of scrap and how much scrap will be used to craft this grenade or else
Yeah I think you're overcomplicating the system already
That can just be 1 component, and just the items have a type applied to them, or some flag to be in a specific section.
But, yeah.
A normal inventory system should be able to handle that fine.
I don't understand, it's like if you have a certain amount of scraps then you can make the bandage and use/keep it.
If I was playing against you in your game, for example, why do I need to know how many bandages you have? Or how much scrap you have? Why, as another player, do I need that information? Why does that information need to be replicated?
Because if the player dies, the other player can steal.
Oh okay - yeah then my original answer stands
"UInventoryComponent on the PlayerState and replicate the inventory that resides within there (usually via a TArray of a custom struct, like an FInventoryItem struct and have that data populated via data assets and just grab the CDO data as required for effects, audio, icon etc)"
This one?
That's more along how you might actually bandage, but this is what I was talking about:
UInventoryComponent on the PlayerState and replicate the inventory that resides within there (usually via a TArray of a custom struct, like an FInventoryItem struct and have that data populated via data assets and just grab the CDO data as required for effects, audio, icon etc)
Replicate the items as they are added, removed, mutated, etc
I might not even do that
On death, I might then replicate the inventory and only then
Shouldn't we use Datatable for this?
instead of continously replicating - others only need that information once you're dead and can be looted right?
So make a replicated actor that contains that info when your player dies
Yes, we can make the OnRep function
DataTable contains static data, sure that's one way
Yeah or just have server spawn an actor with the relevant information
may not really need to replicate anything at that point beyond the DroppedInventoryActor
OnDeath send a server RPC with inventory info
Have Server spawn the actor with that info
Okay so the information is held locally until the player dies and once dead, the data is sent over to the server for replication and it spawns to all client
Depends how you wanna do it - I'd say you need some communication on the server to validate inventory, like adding and removing, so that players can't cheat
Like when I go to use a bandage, have a server validate that I, indeed, do, have a bandage
That's my concern on locally controlled inventory
Yeah it can be predicted but I wouldn't say controlled
If(ScrapAmmount >= BandageCraftAmount)
{
// Craft bandage
}
Didn't have a term for it.
LocalPlayer -> RequestBandage
Server -> RequestBandage is called
Validate that data
Server -> Client RPC the next thing or Multicast or whatever
Okay, thanks..I understood the networking context for inventory
Mint. Best of luck! Take your time, Inventories can be difficult
We have inventory issues constantly
I'm thinking of watching this as a reference to understanding the inventory system
My concern was over networking of it
Best of luck!
ugh, it uses a DT
idk about the quality of it but once you watched enough replace his DT system by data assets
Okay, sure.
It works for dedicated servers
But whatโs the alt then; eos lobbies?
I know nothing about those haha
Hey, does anyone know much about Seamless travel and how that effects the persistence of game modes or controllers?
In the documentation I read that they persisted when using seamless travel, but maybe I'm misunderstanding what persisting means in this context? I've set the game mode to use seamless travel, and I'm initiating the level transition through Server Travel, Plus I have a transition level, but when I load into the new level the event begin play event for my game mode fires off and the variables are all set to their default values. Same with my player controllers.
Any help would be massively appreciated, just confused right now on what the intended functionality of game mode persistence is and how to achieve it.
There's a very good guide written by this guy: https://wizardcell.com/unreal/persistent-data/
Short: You never want to persist GameMode! PlayerController is persisted by default
It's also worth noting that non-seamless travel disconnects clients before doing the travel and tries to reconnect them again after the travel, which might not be desired.
You can persist data server-side in a GameInstanceSubsystem, and use the new GameMode to multicast that data after travel is done.
Or if you need player-related data to persist, look into PlayerState::CopyProperties()
I know the Character Movement Component by default predicts everything
But is there a way to switch to a non predicted state for a bit?
Can I (or Should I not)
Create RPC that takes Actor Reference, This actor method reference and some paramters of given method, to be sent to server and runned there?
Maybe I could tag some functions that can be runned this way?
I'm assuming you mean a pointer
you can do that just fine
as to whether or not it's the right thing to do is entirely dependent on what you're doing
actor has to be replicated obviously
is there any way in unreal to check or tag methods? ๐ค , so when method pointer is passed, server can actually check if this can be executed? ๐ค
or should I actually write this funcitonaly myself
wait
are you trying to pass a function pointer or an actor pointer?
if you're asking if you can send a function pointer you definitely shouldn't ever do that
I don't think there's any out of the box functionality for that and it would be an exceedingly bad idea as the client could send anything
if you want there to be different functionality, send an enum or something and switch on it to get the right function
if you REALLY want to do it you could possibly send the function name and look it up on the server then execute it
I can't think of any case where it would be a good idea
Hi everyone, I'm on 5.6 and trying to make a custom movement system with UMoverComponent. I have an issue where it seems like trying to apply two concurrent movement modifiers of the same type causes the second one to never get applied (even though calling QueueMovementModifier does return a unique handle for both invocations). In debugging, I can see that the second instance of the movement modifier never calls OnPreMovement while the first one does.
Basically, I call this twice:
TSharedPtr<FBSContinuousEnergyGenModifier> NewEnergyModifier = MakeShared<FBSContinuousEnergyGenModifier>();
// Set a bunch of parameters within the FBSContinuousEnergyGenModifier
// This returns a valid unique handle both times
return QueueMovementModifier(NewEnergyModifier);
The reason for this is the FBSContinuousEnergyGenModifier affects the character's energy, which in turn affects their movement capabilities. I want this tracked in the mover component so that energy prediction is correctly synced. It is possible for a character to be affected by multiple energy drain or boost effects, hence why I want to potentially stack multiple energy movement modifiers to influence energy levels.
The reason I don't use a layered move is that I don't think layered moves have a convenient way to be terminated externally: they tend to either have a fixed duration or have an IsFinished function to decide if they should end. But using IsFinished requires the layered move to be aware of which effect created them and then query to see if that effect is still present... a good way to cause myself pain when it comes to multiplayer.
Both movement modifiers work, but only if they are the only modifier being applied. The moment I try to add both, the second one is queued but never gets applied
You could have the effect aware of the layered move and set it to terminate whje the effect is removed.
E.g. Set some bIsFinished bool on the LM from the effect.
I did try that, but it seems like you can't externally modify a LM once it's in effect
Why not?
Queuing a layered move doesn't return a handle, and holding on to the pointer and modifying the value doesn't seem to do anything ๐
Well that's shitty.
Yeah. I might be wrong of course, but I can't see any way to externally get at an LM once it's applied
good explanation, Ill re think that ;d
See brian's comment!
Ok got the solution: when you queue movement modifiers it will check to see if a matching modifier is already active and will not apply it if one exists. By default in FMovementModifierBase the Matches function only checks if it's a modifier of the same class, therefore by default the mover system will not let you apply two of the same type of modifier. However, if you override the Matches function (thank god they made it virtual) to also check that the two modifiers are the same pointer as well, then it will work ๐
Nice!
Brian is indeed the messiah, and not a naughty boy
You can be both ๐
i would be glad to know where the CMC traces for its movements
i would like to dynamically modify the shape
(for example, when the player grabs something in front of him, "extend" the shape)
im in a singleplayer situation so idc about replication, i could just hijack the code
(using source build, i can override the engine if really necessary)
In a lot of places. Open the source code and override any function you need
No one will give you such a detailed list that you can get yourself ๐
A single function to start is enough 
Ig ill just ctrl+ f sweep and see what i find
sweep and overlap
Hey guys, I have a setup, where I have a Component that adds a UObject as subobject for replication and on that uboject there is a server function, for the player to interact with.
Now my issue is, that the component lives on a actor, that is owned by the server, so the player can't call the server function. I know I could set the owner of the actor to the client, or I could create a rpc on the player controller.
But I need multiple players to be able to interact with it and there is also a variety of UObjects that have different server functions to interact with, so i would be required for each of them, to add function to the controller which would really clutter the controller.
Any ideas here?
You have to route it through something that is owned by the client so they can send the RPC. There is no other workaround.
Could I use a SubSystem for that?
Doubt there is one that allows this. Usually a component on the PlayerController is the best
Ok I see, I'll do that then. Thanks a lot! ๐
Hi everyone! Iโm running into a problem when testing my Steam build. In multiplayer, the clientโs camera keeps snapping/pulling back when the character is moving. But camera rotation works flawless โ the snapping only happens while the character is moving. In PIE everything works fine (movement + rotation). The issue only shows up on clients in the packaged Steam build. I've tried a lot of stuff due to replication of the thirdpesoncharacter and nothing helped
Also I noticed that the characters appear sideways, on their own screen they look forward, but on another player's screen they are looking in a different direction and it happens only in steam build.
Any ideas?
it sounds like the character is getting corrected.
rotation is not replicated so yeah it doesn't get snap.
but your character keep getting corrected, ofc the camera would have move back too since it follows the player.
The only reason that in PIE everything works "fine" is most likely because you don't have network emulation. You should emulate ping to emulate real world environment.
In real settings, there's no such thing as 0 ms.
@austere sierra
thank you very much for your quick answer, testing in PiE with latensy 200 ms indeed makes the character move a bit incorrectly but not as badly as on steam, but I can see the pattern. I donโt fully understand what I should do to stop the character from getting corrected(?) and snapping the camera. Does this have anything to do with event tick?
or how could I possibly fix this issue with players not right replicated cam and snapping?
You will need to read the character movement component framework, especially the networked part.
Client store predicted data, in FSavedMove. Then apply the Move on their own
it will then get send to server
where it will simulate on server. If the result isn't the same, the client will get corrected.
it's hard to tell what happend in your project without knowing what you actually do.
Are you trying to do sprinting or something?
I would say any movement of camera. Even jumping. Literally anything that moves camera position. (sitting, walking etc.)
I don't think it's the camera, as you say, it happend when the character is moving and only when it's moving.
@dark parcel
yeah, and also as I said the characters appear sideways, on their own screen they look forward, but on another player's screen they are looking in a different direction, Maybe it is somehow connected?
i didn't do anything special with movement whatsoever. just was building a simple multiplayer game.
I would recommend reading through delgoodie cmc article.
if you are just doing Third person template, there shouldnt be any issue.
yeah, that's why i am concerned. as i said i didn't do anything special and just was following bunch of tutorials for the cam. and as it appears it's not a usual problem and idk what to do with that
if you feel like it, I could show you a demonstration of the project or send some screenshots. Maybe you can find some issues. I am really stuck overhere
I dunnoe what ur tutorial do, it might have been sonething special. As i said if you just start with default tps, there wont be a problem
i didn't do much. it's just default "realistic" first person camera in third person character tutorial, that's it
That sounds like something special
I just compared every setting in character movement component with an original third person template and everything looks the same
Can't help you with your tutorial, you can start with default tps, it wont have correction.
i don't think that the problem is in first person camera tutorial to be honest. it's something else
the tutorial is just connecting camera to socket bone of the character(neck) and that's it
I am using third person template and literally don't even know what causes it
W.e you doing really. There shouldnt be any rubber band with default tps, even with 300 or 500 ping
it's helpful. then i suppose the problem is in the camera and this tutorial itself. Will recheck the tutorial. Thanks for your answers. and one more question, based on your knowledge, can the camera be attached to the third person character's skeletal mesh neck and then in ABP blueprint be "replicated" or does this only work for the host? maybe it causes everything. Thanks again
just checked the tutorial again and it has nothing to do with movement it's just about the rotation
Iโm going to check the CharacterMovement settings again, escpesially network
Anim blueprint is not replicated. It can however read a replicated variable from it's owner.
Camera is local, player camera shouldn't even be networked.
normally if you need to know what others are looking at, that can be get from the control rotation.
as long the character is not corrected, there shouldn't be issue where you place the camera.
how could i check this?
open console and type shownetcorrection
if you see red capsules when you move, then you are getting corrected.
p.NetShowCorrections 1
yeah, most of the time the capsule is yellow, chanhing modes from walking to running gives red capsule
yeah that's what I said in the beginning
"are you trying to sprint"
that's the point where people that usses blueprint only finds out the blueprint limit.
if you want to do auth movement, you will have to dive into cpp. Look into del goodie cmc videos for the implementation.
the issue is you don't pack the sprinting info the in the prediction struct FSavedMove
Youtube tutorial is full of scams when it comes to sprinting in networked environemnt. Add lag and the whole thing breaks.
jump(red) makes the same thing and the default walking too(yellow)
i just want that to not be laggy and that others can see animation of sprinting
You wouldn't get it in the default TPS
that's it
Yeah, look into delgoodie CMC video
it's not a 5 minute implementation
understanding the framework takes a while, after that comes the implementation.
https://discord.gg/uQjhcJSsRG
In this video I setup a new project and create a custom character movement component. I also implement movement safe sprinting which works at any ping.
https://github.com/delgoodie/Zippy
0:00 Create New Project
1:02 Setup File System
02:50 Create Custom CMC
04:43 Saved Move Class
08:37 Compressed Flags
13:35 Client...
nope
you have to change the bit flag in the prediction struct, that can only be done in cpp.
and what about jumping and walking? any movement causes lagging, not only the sprinting. any camera location change lags
I can't tell without looking at any code, and even if I did, without the project and attempt to debug it, my opinion would be a guess at most.
jumping shouldn't cause any lag
for the jump i am just using default bluieprint jump. i don't think that it has to do with sprint for now, maybe it will come later on.
If you just call the Jump function
Jump and crouching should already be implemented into the prediction struct. Calling crouch and jump function from the CMC will not cause any de-sync,.
maybe something is messed up in project settings or in event tick
It's probably something that you do, cause de-sync.
e.g setting the actor location as client.
the capsule is always yellow, no matter what the state is(running, walking, jumping etc)
will check that out
probably something in event tick, but as far as i checked nothing should update clients
changing the movement state and have something overriding it outside the cmc framework would cause de-sync too.
oh my god, bro
my capsule component was being replicated
..
lol
but thanks for your answers!
Not sure what the setting should be but it's best to leave it alone at default value.
I read the guide and it was pretty informative a little confusing at parts, but I think I got the idea, and tried to implement a working system, but even though I have my player controller at the same player controller from map to map, it keeps resetting it's values to their defaults, that didn't seem to be the behavior that was being described in the guide, but maybe I was understanding it wrong. So I tried setting up the player state to CopyProperties() that I wanted to persist by using the blueprint events.
Still I can't get any of the properties to persist, I've checked to make sure that I am using seamless travel, and it seems like I have the properties on the game modes all set up to use seamless travel I have a transition map set up and I am calling server travel using c++, but I still can't get any properties on the player controller or the player state to persist between sessions.
Do you have any idea what could be going on here? I have looked up tutorials on how to do this and their seems to be no difference in the methods I'm using. Is my project just corrupted?
I'm kinda at a loss here.
Are you testing this in the Editor?
Following Cedric's comment, seamless travel is disabled in editor - so you should test in packaged build or standalone. Or, try the net.AllowPIESeamlessTravel true command in the console.
that's probably it then
Hello, I have a question regarding multiplayer and possession.
in a project i am making - it is a simple first person shooter, that have about 4 possessables pawns - soldier, drone, map, vehicle.
all have different behavior and UI. i am trying to make a system that is good for handling inputs and UI but my core issue is that possession sometimes fails to clients.
i tried do some delay and timers that check in small intervals but that s obviously a bad approach - is there a guide, documentation, or do you know how can i make a system to swap between those pawns back and forth please?
i searched and couldn't find anything and Layra's project is a good way but i cant do a migration, so maybe use a plugin in Lyra's (if you know that they handle it that way idk) or any help really will be greatly appreciated!
Tbh, this is really straight forward
A player can only posses one pawn at a time and a pawn can only be possessed by one controller (Player/AI) at a time.
Server has to call the possess function.
And stuff like applying input and such is usually done in the setup input functions in c++, or via OnControlleraChanged in Blueprints.
And if you want a client to be able to swap between pawns then you just need to call a server RPC and do the unpossess/possess.
There is no magical trick. If you have issues with it then you are doing one of those things wrong.
Got an issue when the character is attached to vehicle, the pitch/yaw replication breaks.
What can be the root cause?
void UCharacterAnimInstanceBase::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
if (Weapon)
{
FRotator TargetRotation = Character->IsLocallyControlled() ? Character->GetControlRotation() : Character->GetBaseAimRotation();
FRotator DeltaRotator = TargetRotation - Character->GetActorRotation();
DeltaRotator.Normalize();
Pitch = DeltaRotator.Pitch;
Yaw = DeltaRotator.Yaw;
if (Character->HasAuthority())
{
UE_LOG(LogTemp, Warning, TEXT("Server - Pitch: %f, Yaw: %f"), Pitch, Yaw);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Client - Pitch: %f, Yaw: %f"), Pitch, Yaw);
}
}
}
GetBaseAimRotation() returns just 0 when the character is attached to vehicle ๐ซ
thats a passenger, not possessing vehicle, just attached to vehicle with movement mode none.
Hi all, any pointers on how to do tree destruction (like in Valheim/Rust) on trees spawned via world-partitioned PCG.
Each cell in the world-partiition grid gets its own PCGPartitionGridActor, which contains an InstancedStaticMesh component containing the spawned trees and PCG component.
I am pretty sure this PCGPartitionGridActor is not replicated, so every client gets their own PCGPartitionGridActor
Does Event On Logout get called if people are dropped during Seamless travel? Not having an issue, just trying to make sure there won't be one in the future.
Logout should be called for any connection that is closed.
Regardless of type or reason.
Itโs a pretty complex problem for MP and PCG. Do you have the graph running in runtime or on load/demand?
idk if this is the right channel as it's a multiplayer/replication issue, but it also consitutes a UI issue, so im hoping im correct but if not ill remove it and put it in the UI channel.
So my game has UI like this that would be visible for all players on all screens. if 4 players are active there would be 4 instances of this widget along the bottom of the screen. That all works and it links correctly to the players. The issue is that player 2 and i assume 3 and 4 (havent been able to test more than 2 players) show all progress bars are a delayed rate, so for example, the dash bar would be full, you dash and it empties, then fills up across like 1.5-2 seconds. it works fine for player 1/host, but the other player would just see it at what i can best describe as a low frame rate or slideshow.
I don't know if its an issue with me testing the game through 2 instances on my pc (using sandboxie plus with another steam account) or if its due to it not being replicated fast enough for other players
if you skip around half way into this video you can see what i mean with the slideshow/low fps type delay
Hard to tell without seeing the replication code for that stamina value.
Looks like the client just gets the data replicated and you aren't interpolating the current to the new value inside you widget to make up for it
It does seem a bit harsh on the replication interval but yeah
lemme just open the project and ill get some SCs
1st img: Player Controller adds UI to the screen (just a horizontal box that the previous screenshot gets added to as a child)
2nd img: The variables for health and dash are stored in the player state, set to replicated
3rd img: How the player health and dash gets added as a child
4th img: logic for dashing and filling the progress bar back up.
the only screenshot i havent included is how im getting the player state, but im just casting to it on event possessed
Also sorry if the code is awful. The game originally wasn't intended for multiplayer as it was a uni project, and with the attention we drew from it we decided to push for online MP, but replication is reallyyyyy difficult
i think the player state's default constructor sets NetUpdateFrequency to 1.. so unless you changed that in your own player state class, replicated properties in player state will only send as fast as 1hz
ill try changing it to .01 and raise it up if it causes any issues. I looked at some of those but wasnt sure if it would cause any issues with it being something im not too knowledgable of
hahaha im dumb. wont 0.01 mean itll run 100x slower? seems like thats what it did ๐
Yeah i set it to 60 and it works pretty much perfectly ๐ thank you Omnicide
yeah it's a bit confusing cause its different than how you define the tick interval. its actually update rate.. 1 = 1 time a second 2 = 2 times a second ect so higher is faster
i read it and interpreted it as how often itll update in seconds not how many updates per second. so when i tested it with 0.01 it didnt even budge ๐ but yeah 60 works great, and i may lower it to 30 once ive got the custom UI added but for now it works well. Again thanks for the help Omnicide
no problem
after alot of debugging i found that if i disable the vehicle springarm/camera the passenger pitch/yaw works as intended
so here is the question, why the vehicle springarm/camera should effect reset passenger controll rotation on server only? while the passenger is not possessing the vehicle, its just attached to it with movement mode none
is it even possible to make the springarm/camera available for only driver which is possessing the vehicle?
A work around is to replicate my custom base aim rotation while in vehicle which works fine.
void APlayerControllerBase::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
const bool bCanUpdateCustomBaseAimRot = HasAuthority() && ControlledActor;
if (!bCanUpdateCustomBaseAimRot || !ControlledActor->IsAttachedToVehicle()) {
return;
}
if (ControlledActor->GetEquippedWeapon())
{
ControlledActor->SetReplicatedCustomBaseAimRotation(GetControlRotation());
}
}
void ACharacterBase::SetReplicatedCustomBaseAimRotation(FRotator NewReplicatedCustomBaseAimRotation)
{
ReplicatedCustomBaseAimRotation = NewReplicatedCustomBaseAimRotation;
}
void UCharacterAnimInstanceBase::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
if (!IsValid(Character))
{
return;
}
if (bAttachedToVehicle)
{
if (Weapon)
{
FRotator DeltaRotator = Character->GetOffsetRotationWithVehicle();
DeltaRotator.Normalize();
Pitch = DeltaRotator.Pitch;
Yaw = DeltaRotator.Yaw;
}
}
}
FRotator ACharacterBase::GetOffsetRotationWithVehicle() const
{
return IsLocallyControlled() ? GetControlRotation() : ReplicatedCustomBaseAimRotation - GetActorRotation();
}
Yeah I have been plucking my hair over it haha its on load/demand
Youโre in luck. You can use instanced actors then, with 5.6 they work with PCG
It doesnโt work with runtime PCG though
Went down that rabbit hole as well, but encountered a problem: any trees I destroyed would reappear when moved farther than a set distance. Not sure if instancedActors have a way to keep state.
final results with custom replicated base aim rotation.
so gamestate derives from AInfo, but AInfo cannot replicate variables..?
so how does gamestate replicate its variables to clients?
GameState uses the GetLifetimeReplicatedProps, if you need to replicate any var just override it in your custom gamestate class if you don't want to extend the engine by directly replicated in the AGameState
I did that. It still did not work
UPROPERTY is replicated too
bReplicates is true
what else am I missing
I did it all the time and it works
the variable state should be changed by server if you want it to replicate
It is
if client change it, it will not replicate
I understand how to do it, I follow the same order as it were an actor replicated variable
they work as expected
late joiners should get the latest variable no?
so that cant be an issue either
debug it
if (HasAuthority())
{
//server trying to change
}
else
{
//client trying to change
}
only if replicated using onrep
Only onrep?
okay
I will try that
I thought Replicated is also ReplicatedUsing
minus the function call
under GetLifetimeReplicatedProps you can use DOREPLIFETIME(AThisClassName, Variable);
yep I have that
but uproperty should usingonrep = somefunction
and if you are building dedicated server, the onrep method should be called manually right after the variable is changed
bchanged = !bchanged;
OnRep_bChanged();
listen server will call it automatically, manual call is must only for dedicated servers
you could be doing something wrong, there is no reason for it to fail
It is.
Replicated variables will be up to date on clients. ReplicatedUsing just adds the callback.
okay thank you for the sanity check
Where are you printing this?
in a function call directly after FMath::Rand()
Server's generally don't call OnReps in C++. Doesn't matter if Listen or not.
What calls that function?
beginplay
Ah, right I see.
all replicated variables should be ready before beginplay right?
Not 100% sure tbh. BeginPlay isn't really tied to the replication flow of an Actor.
hmm okay
Like, BeginPlay triggers cause the GameMode sets the GameState's MatchState to InProgress.
If you keep that in WaitingToStart, data still replicates. So I wouldn't stick to that being a rule.
If you want to react to the value replicating I would suggest putting that into the OnRep as well. And then guard the Generate call for Seed == 0.
I couldve sworn even putting a delayed timer still showed it as 0 for some reason
Rest looks fine. Try printing it on tick and see if it ever changes.
let me try it again
What is that class you are in? The GameState itself?
No, my custom AInfo child class
Hm ok.
but AInfo derives from AActor anyway
UActorComponent on the GameState might be enough if you don't care about AActor.
But that's besides the replication issue
Okay so it is a timing issue
and my wrong assumption that beginplay was safe
thanks for the help
You can even have OnReps call before BeginPlay in some cases. Which can cause issues if whatever you do there needs the World to have begun play.
Has gotten me back on The Ascent, cause some internal engine code was just silently disregarding my code.
And what about for late joiners, would onrep even call at all?
since it just gets the latest value
It will if the value is different or if you set it to always call.
okay
That's the whole idea about the OnRep
couldve sworn it didnt trigger at all for the late joiner..
So that LateJoiners and peeps coming into relevancy range can react to the value changing
probably my sleep deprivation lol
hmm, Thanks for correcting me...
I think I read this incorrect info in somewhere in an article that listen will call the callback automatically.
since i have never worked with listen servers and I call onrep manually in dedicated servers on C++ side
No, it's Blueprints that call it automatically, because BPs use a hacky PropertyChangedNotifier, which also calls if you actively change the variable. So even clients that locally change a property get the callback in BPs. Including the Server.
But that's just a side-effect of clusterf*ck BPs.
I have a bunch of world subsystems that hold a ton of data and update it continuously.
I want to replicate and sync just some of the data.
What's the approach here, make an actor per subsystem type that the serverside subsystem sends this data through?
is there a "wait until after the next replication" kinda delay/timer?
I have a subobject in server, I try to RPC that subobject to a client and after that remove it as a subobject.
The thing is, if I don't wait the subobject stops being part of the actor (and thus, sendable by the network) and the rpc gets a nullptr instead of the subobject.
any ideas?
rpc what about it?
just rpc a pointer to it?
What are you actually trying to do here
why not just pass the configuration values from the server component to the client component?
so like a gamestate sort of thing?
I'd do something like that at least
Kind of but there's many of them and more can be made by extension
I think If I can reliably tell if I'm the server or client at beginplay for the world subsystems I can just have the server one spawn an actor to replicate through
It's a 1d simulation plugin like power networks.
I can't replicate the entire state, it's way too much data. What I want to replicate is "discrete" stuff that's sensitive to small discrepencies.
Like for example, signals and gearboxes. My gearboxes are implemented as a model that listens to a signal (just a float value) and shifts if the signal is above some threshold. Every machine will mostly agree on the signal value, but what I don't want is for the value to just barely trigger a shift on one machine but not on the other. So the CurrentGear is a discrete value that will be synced from server to client, even though the state it depends on is not synced.
I'm sending a uobject* . Not a comp, a replicable uobject. I would like to send just data, but the system was already in place when I got here.
For the uobject to replicate it needs to be added to an actor.
My problem comes with the timing of the removal to said actor ๐
Why remove it?
I know I no longer need it...
No real reason ๐
Worried that it might build up and clog the net?
No updates should happen on it, so it shouldn't keep replicating... Right?
It'll be there doing nothing
I'd leave it unless profiling indicates otherwise
although instantiating a replicated object just to effectively multicast once certainly is a technique
Ageeed, I don't like it but I can kinda live with it (for now) ๐
Yap. I would say check the GameplayDebugger replicator. But that's a bit more old-school than it has to be. But in short Epic is doing the same.
They just keep that in sync on tick by checking the PlayerControllers on the server side and spawning/destroying those actors as needed
is it possible that you get an actor class that upon creation, communicates to the subsystems whether its the server machine or not, and then initialise the subsystems based on that?
either way you would need this over watching actor class anyway, to pass on structs of the floats being updated every time if you want to do the other method
Okay... what...
So If I use just the C++ class, OnRep doesnt work
but if I turn it into a blueprint
OnRep works
really?
Oh, I just need to tick that its always relevant, never mind
you can call it manually when its needed to, basically when a replicated variable changes you call the callback function to do custom things on all clients and server. you can also return on server if you don't want to do the thing on server for optimization.
like server don't need to play particle, sound etc...
so you can check in onrep function:
if (GetNetMode() == NM_DedicatedServer || HasAuthority())
{
return;
}
playsound(); simulateparticles();
after doing this all clients will play sound and particles but not server
or i guess just checking for HasAuthority() will do the trick and don't need for GetNetMode() == NM_DedicatedServer
Yes you can use AActor::HasAuthority() however GameMode, GameSession, GameState and PlayerController are actors themselves, so you probably don't need another one.
subsystem has a function you can override to determine if it should be initialized or not
you can get net mode even in non replicated contexts
so just check if not dedicated client
Why the first player gets kicked?
void ASurviveGameModeBase::BeginPlay()
{
Super::BeginPlay();
if (HasAuthority())
{
MaxAllowedPlayers = 200;
CurrentJoinedPlayers = 0;
}
}
void ASurviveGameModeBase::PostLogin(APlayerController* NewPlayer)
{
Super::PostLogin(NewPlayer);
(CurrentJoinedPlayers >= MaxAllowedPlayers) ? KickPlayer(NewPlayer) : TakePlayerToLobby(NewPlayer);
}
iirc when PostLogin calls, it should have the current correct state of CurrentJoinedPlayers
since BeginPlay calls first and sets the defaults
this only happens when i run the game as standalone/listen server
Why not just breakpoint and check the values
Also why are you using ternaries like this ;-;
i didnt even know that ternary without use was allowed
Kinda wish it wasn't
I did and it was breakpointing something in alloc.cpp, was going out from the scope of the project.
I found that server was trying to kick itself... giving it a check to exec the kick method only for clients fixed the issue
ternary is just a short form of an if, i feel no danger using it
No danger outside of your code being unreadable
I'm using it alot, for me its very readable.
I have some conditions in code where i have like 15x ? s in a single statement
You do you, I'd get the guillotine for that at some places I've worked at
(and I'd be pulling the cord on myself sometimes)
I use it alot for avoiding nested if's like in this basic condition in my custom CMC
if (bWalkPressed)
{
CurrentPose = (NewMoveFB == 1) ? EMovementPose::Walk_Forward : (NewMoveFB == 2) ? EMovementPose::Walk_Backward : EMovementPose::MovementPose_MAX;
}
else if (bIsSprint_OR)
{
CurrentPose = (NewMoveFB == 1) ? EMovementPose::Run_Forward : (NewMoveFB == 2) ? EMovementPose::Run_Backward : EMovementPose::MovementPose_MAX;
}
else
{
CurrentPose = (NewMoveFB == 1) ? EMovementPose::Jog_Forward : (NewMoveFB == 2) ? EMovementPose::Jog_Backward : EMovementPose::MovementPose_MAX;
}
Missty please disable pings in your replies ^^'
And that is unreadable as fuck, but I think we had that conversation in the past already so
ยฏ_(ใ)_/ยฏ
Have you even considered using directly called lambdas instead? They won't get you around the nested stuff, but are at least a bit more readable.
CurrentPose = [&]
{
if (bWalkPressed)
{
switch (NewMoveFB)
{
case 1: return EMovementPose::Walk_Forward;
case 2: return EMovementPose::Walk_Backward;
default: return EMovementPose::MovementPose_MAX;
}
}
else if (bIsSprint_OR)
{
switch (NewMoveFB)
{
case 1: return EMovementPose::Run_Forward;
case 2: return EMovementPose::Run_Backward;
default: return EMovementPose::MovementPose_MAX;
}
}
else
{
switch (NewMoveFB)
{
case 1: return EMovementPose::Jog_Forward;
case 2: return EMovementPose::Jog_Backward;
default: return EMovementPose::MovementPose_MAX;
}
}
}();
Gives you a bit of nesting still, of course, but might overall be more readable.
Also given NewMoveFB seems to be an int, you can use a switch too.
Hey guys, for real production project, do you guys use multiple Online Subsystems for a single project or just stick to one? Do changing between different OnlineSubsystem requires alot of code refactor or it just interfaces and config?
In theory just interfaces and config, unless whatever you want to do with the subsystem isn't part of the interface.
But you did use multiple OS right? Since publishing on Steam would have to use Steam OS and on other console platform would have to be EOS for example.
"Using multiple" kinda depends. If you release on different platforms/stores and the game doesn't require crossplatform matchmaking, then you would probably end up having a Target.cs with CustomConfig folder per Target, where you have a different OSS set up.
If you need crossplatform matchmaking, you'll need a single OSS that can handle that.
Yes and no. EOS serves as a single point of communication. Your players would all use EOS, but they would authenticate based on their platform/store with it.
What about for steam build? I can still use EOS but I will miss other steam's platform features like friends invite right?
Thanks that explains
Hi, are there any open-source Unreal Engine co-op projects I can check out, whether they're written in C++ or Blueprints? Itโd be even better if they include a lobby system.
Random question but has anyone heard of a concept where a high latency player causes lag for other players/an increase in latency for other players?
It's been brought up on an UE game with (some) proof, unsure how accurate it is and it really wouldn't make sense
And apparently Garry's Mod has a similar problem, so now I'm actually curious if it's just placebo or something that happens for some odd reason
Even though I'm 99% sure it's placebo
I can't think of anything in the engine that could cause such a thing
well, if they are relying on that player's input for recent data they need recent input
less recent input = scuffed data
Except maybe the CMC and queued moves? even then I'm skeptic
for example a really low fps cmc will jitter more because it literally cannot send as much information between frames
I mean I'd get it increasing the latency of one player
But one player lagging increasing the latency of every player?
even just recorded ping
what kind of latency?
displayed ping
yeah I don't see how it would affect their ping unless it was a lockstep sim, which the cmc is not
and apparently server lag? but there's no lockstep yeah
unless it was congesting their network and capping out bandwidth somehow??
and then congesting it for everyone
possibly?
Would have to be low bandwidth settings on the server then
and one hell of a laggy client
I mean the default bandwidth limits are turbo low so
but I would need to see profilers to see what is actually happening
you will definitely see low fps players jitter more on sim proxies as the server just doesn't have as much info
depending on how fast acceleration is on that cmc
Community member reported it, and I'm only a friend of the dev so I'll just bring that info to him
perhaps its queueing up a ton of saved moves somehow? I kinda assumed 99% could combine
I'm not really sure how many saved moves can get queue'd up at once honestly
I'm more familiar with the client side part
and one laggy player causing this just sounds hard to believe
buuuuut it also sounds plausible
so guess it'll need some profiling to make sure it wasn't just a coincidence
btw, if you guys use multiple OSS in development. How can use switch between them without much hassle? For example, in editor I can use NullOnlineSubsystem. When I build I can either build for Steam (use SteamOS) and for Console (use EpicOS). But can I seperate them automatically without having to go into the config and swapping out the settings?
Wow Thanks, that's super cool I will refactor to it
this seems to me more readable and clean
NullOnlineSubsystem can work for nat connections, you will just need to handle connections manually and fight sus connections
this is why using external OSS like steam or Epic is recommended cause they handle those stuff out of the box
Multiple Target.cs files + Source Build + Custom Config Folders
using UnrealBuildTool;
using System.Collections.Generic;
public class YourGameSteamTarget : TargetRules
{
public YourGameSteamTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Game;
DefaultBuildSettings = BuildSettingsVersion.Latest;
IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
ExtraModuleNames.AddRange( new string[] { "YourGame" } );
CustomConfig = "Steam";
}
}
Each of those has a DefaultEngine.ini file with the [OnlineSubsystem] part set to the specific one and then additional settings for that subsystem.
But yeah, that needs a source build iirc.
hello guys ... i have beeing searching how to do slicing using th vr default templet of unreal 5.5.1 .. please help me im new and stack ๐
just a note but your Steam target can just inherit from YourGameTarget so you don't have to keep repeating yourself
Fair. In this case, the files were really small and there was only EOS and Steam, so the gain would be really small.
Does anyone know what the best way to do a multiplayer game where you can chose from multiple different characters? Like do I make one base character and make others a different version/child of the base or is it better to just spawn the player as a unique character or what is the best way to go about this?
In theory, you'd have an overall base class. Depending on how different the characters are, you can either drive all other characters simply through data (different mesh, animBP, abilities, etc.) or in some cases create a child of that.
Okay, sounds awsome! Though I am a bit new to these types of things when it comes to unreal. Any tutorials on this topic or maybe what I should search up to get the desired knowladge?
I don't have any tutorials at hand. In theory, this all comes down to inheritance and composition.
And "data driven" fwiw.
Would use DataAssets and not DataTables for this, but yeah
I'm using a save game to store the character data that is sent later to the server, can't remember where I've seen that
Just remember you can only send 64kb in an rpc. So if your player save game is bigger than that, you need to split it up. Or just let the server store player data in separate saves
I did the latter at my job, works great
and would I trust a large binary blob from the client?
Server ftw. Probably be fine to just do like {unique mp id}/{subject of data}
Easy slot babyyyyyy
Nice friends
I just have a player name and a character class so no big deal
save game object sounds a bit overkill for that
But how do you select between different targets when build or in editor for example
When you build via command line you can specify the target
Editor is kinda self-explanatory
Anyway can I specify a base DefaultEngine.ini for default config and them Steam or EOS and append them using CustomConfig just like the above example?
Yeah pretty sure that's what it's doing anyway
It collected them all
yeah I forgot I've moved it to game user settings
If I use CustomConfig in the Editor.Target.cs it will print something like this
GameEditor modifies the values of properties: [ CustomConfig ]. This is not allowed, as GameEditor has build products in common with UnrealEditor.
How can I resolve this? I see that you can change the BuildEnvironment to Unique, but it would mean that I have to recompile the whole engine again. Does this affect the engine itself (meaning that I have to recompile the engine again to switch project) or any side effects of this?
You don't set the CustomConfig on the Editor.Target.cs
You only need that for the Steam and EOS one.
Editor just uses whatever is the Default one in the Config folder
So basically if you want to test steam or EOS straight in editor. Is it not feasible?
you can emulate the functionality of the target.cs customconfig with the -customconfig=Steam arg
Doesn't seem to work. If I merge the custom steam DefaultEngine.ini to the base one. The steam overlay will show up. But if I seperate them like this and add the argument, the steam overlay wont show up
much easier to use ezargs, but what if you add a breakpoint to FConfigCacheIni::GetCustomConfigString?
not sure how you're verifying it though, null OSS is enforced in editor, you'd have to use standalone with -game
I verify it by running standalone game in my editor. If I dont use CustomConfig and merge 2 configs together. The Steam overlay shows up. However If I try to split the config into 2. I cannot open the SteamOverlay.
let me try this
standalone game is a separate exe
if you want to go straight to standalone, that's what -game is for
Oh the FConfigCacheIni::GetCustomConfigString() do actually return "Steam". However the config still didn't update or merge with the base.
I also tested with the build too. The configs didn't merge either.
This is my custom config in Custom/Steam/DefaultEngine.ini
it only works if I just take these and paste it in the base DefaultEngine.ini
Keep in mind you can't test Steam in the Editor in general.
I am currently suffering trying to figure out how to fix this issue
I want to make a boss bar that appears for my server and client if they damage a boss that they didn't damage before it all worked pretty well except for this error that appears when you kill a boss with a client it says that when the function "unregisterBossChasingMe" (which does what the name says and is the first screenshot) accessed none trying to read "BossBar" even tho on the beginplay in the controller I create the widget and it to the viewport if its locally controllered like in screenshot 2
this issue also doesn't appear when the function "registerBossChaisingMe" even tho it takes the same reference and also is protected by has authority
both "registerBossChaisingMe" and "unregisterBossChasingMe" are called in the boss character when it is damaged (to register the player that damaged it) and on death (to unregister all the players that have the current bossbar) the bar is unregistered for the server only and the bar doesn't disappear from the client's widget
if you need anymore info please let me know
This looks like a whole lot of not understanding networking. First of all the authority switch is only going to execute on the server (or hosting player if a listen server) and it definitely won't have an instance of a UI element of a remote player
but when I removed the authority switch it didn't help in removing the error๐ค
sorry if it feels dumb but I love to learn through trial and error but I seem to be stuck
I like inheritance when it's shallow.
C++Base -> BPBase -> ActualCharacter
Put most of the stuff in the base, ideally ActualCharacter is just different data (meshes, animations, abilities)
And when talking about any character, use the base.
I fixed it!
unbinded the boss on a client owned custom event
But even when I build the game. Using the correct target with the CustomConfig, the Config still not get applied. Do you know why?
No I didn't have that issue. You are using a source build from git?
False alarm. It because I built the game in Shipping build. If I tested it with development, I will see the Steam Overlay.
The custom config works for other fields in the Editor too. For example if I set the startup map in the custom config, it will load it when startup correctly.
However Enabling Subsystem Steam only works if the config is in the base .ini file. I can open the steam overlay in standalone mode. But if I migrate them back to the custom config. I cannot open the steam overlay anymore.
Even outside of shipping?
Shipping only breaks cause you are missing the appid text file that non-shipping creates (cause steam adds that when downloading anyway)
If a packaged dev build doesn't work with steam if the custom config unless you put it into the default config, then it's probably not using the custom config
i am making a combat game and im trying to do reconciliation
1.Player fires input and odes a montage locally
and after that
2.ask server to do a multicast anim montage on all clients excpet the one who fired it
Result:seeing delay in animation montage on all clients which creates a desync issue
how to do it???
what does this have to do with reconciliation?
you are just playing a montage
if you want to reconcile it you need to predict something locally to have something to reconcile from differing results
you could try just predicting playing the montage on the local client and have the server verify it really happened (GAS prediction keys in a sense) but I have 0 context for what is going on here
See how they did with Server Timer. Everytime you multicast the animation, add a ServerTime as the start time of the montage. Then when those clients receive, they will subtract the current server time with the start server time to skip to the correct timeline in your montage.
ServerTime*
If i recall correctly, GAS also have montage replication if you use them. It will automatically replicate the montage with correct time & stuff.
GAS montage replication is based on just an onrep, I don't think it cares about timing between proxies
the timing it sends is for sections and playback rate
if they have actually tight requirements for timing I think it only really makes sense to run things together locally... relying on an rpc with a timestamp on it is basically random especially since they arrive for a set of other actors (even though the offset would help make up the difference partially)
I don't read the code too deep but I see the part they have ConstRepAnimMontageInfo.SkipPositionCorrection
even if you can send the position it's going to arrive at a random time
it would certainly help though, perhaps they don't need perfect timing
You can still guess that random time, that's how they make the countdown timer relatively sync with all of the clients / server.
using RTT
I assume you are using the accurate server averaging method
and with that you can just subtract to fast forward for the late clients.
if you are averaging the RTT as well they also need to make that, when you tell people something it's probably a good idea to not leave out the actual thing you did
just in case, I think it's misleading to say it's just sending 1 timestamp when it's a running average of N RTTs
which is updated constantly
unless you did something else (this accurate network click is a nice way that works well, I think it can help with syncing stuff like this a bit)
Yeah, I should place the appid inside the ./<ProjectName>/<Platform>/ folder. I though to place it at the root (where you usually run the game).
For the custom config in the editor, I figured it out. Turns out, I have to set the parameter in here so the standalone game can open steam overlay. Putting it in engine startup don't affect the OSS choice.
Just a quick question @thin stratus, when you build with different targets. How can you control the game's name? As far as I know, the game name is based on the <Name>.Target.cs. For example MyGameSteam.Target.cs, the game will be built as MyGameSteam.exe.
args don't propagate to the launched standalone process from the editor
the name of the target dictates the output exe name
but we just ship them as it is without changing it?
yeah, why not?
Pretty sure we didn't care about the name.
you tell steam in the backend which exe to run
Just make sure it matches in the backend
Yeah haha, I don't have much publishing experience so I don't know if exposing it will looks weird or not.
Tell that to ShooterGame.exe
I guess steam will be the one who run it anyway.
in the app configuration in steamworks, you tell it, per-platform, which exe is run
and you can specify different launch configurations if you want
A lot of game already shipped with name ShooterGame.exe ๐คฃ
lmao
hey all, i'm confused about the ReplicatedUsing variables declared in c++ and set in bp. what's the pattern for using these variables in bp? is it to set it on the server and call the onrep function? i noticed that these vars don't say "set w/ notify" on their nodes either so it must be something different than creating the same var in bp ๐ฅฒ if you could point me in a direction of a good example to reference, that would be amazing too
yes you have to call the onrep function everytime you set the variable on the server
I don't use blueprints so not sure, but since it's a c++ variable I believe that's what it is
The compendium should explain this fwiw.
In C++, the OnRep only calls on Clients and by default only if the value is actually different.
In BPs, the OnRep calls for every "set" call, because it's basically a "OnPropertyChangedNotifier" of sorts.
If you have C++ Replicated variables and you need the OnRep to call on the Server, your best bet is to keep them private and expose a function instead that sets and calls OnRep.
Hello everyone. I'm building a multiplayer action rpg game that has a few melee attacks. I'm having some issues with network lag, though. For most of my abilities, when it comes to checking of something actually hit, I run collision detection on the server. But for melee attacks, if I do that, it generates a perceivable lag between the animation, that plays predictively in the client, and the actual hit detected by the server. Does anyone have any advice on how to handle that?
predict the hit
How? Running collision detection in the client?
yea
thats how i'd do it
and if theyre wrong just have the server correct them
how do your animations work
I'm not sure I understand the idea. Detecting the hit in the client is easy. But that's not the only thing. I would also have to play a hit reaction to the hit, show visual cues, etc. How would all that work with correction?
u just run all the hit logic the server runs on the client
and then the server looks at what the client did and if theyre right it does nothing
and if theyre wrong it just tells the client they were wrong and they undo the damage
hello friends, how do i make the host kick other players and is there a way to give a kick reason too? i tried using GameSession->KickPlayer, but i dont know how i can get the client to get the kick reason
Send the reason
Have the client send back an acknowledgement RPC
Server calls kick player
When client is kicked, display the reason that was sent
There also might be a delegate that you could bind to for kicking specifically, but couldn't say. Never looked.
Do you even need acknowledgement from the client?
although yeah I guess you could get the packet dropped and then kicked without knowing why
rip
It's more to solve their problem. They said that if they kick the player, they don't get the reason. So send the reason first.
The ack rpc is so you know that you can kick them safely.
AGameSession::KickPlayer sends the kick reason in a client RPC to the player controller
see APlayerController::ClientWasKicked
override it in your player controller
then as soon as you receive it, store it somewhere else (like game instance for example), because the controller will be destroyed soon after
then just check on your "main menu" map when it first loads if there's a kick reason somewhere in your game instance and display it
how to fix the advanced steam sessions plugin 9999ping issue?
steam sockets
im in UE5.5.4 still needs to use steam sockets?
If you want to fix the ping issue then yea
do i also need to adjust the default engine ini ?
yeah, better for you to find some tutorial how to implement steam sockets
ok thanks
Is there a way to use NetDeltaSerialize to replicate a struct atomically the first time it replicates to a connection, and after that go on serializing only what changed?
Also struct replication to a connection is triggered by comparing for each property the current value and last sent value, or by comparing the result of the NetSerialize function?
Hello, yes, thatโs the main purpose of NetDeltaSerialize.
And dirty checking is not done by comparing NetSerialize results, itโs done by comparing against stored shadow state or connection baseline, depending on whether youโre using default replication or delta replication.
You should take a look at these articles
https://www.aclockworkberry.com/custom-struct-serialization-for-networking-in-unreal-engine/
https://ikrima.dev/ue4guide/networking/network-replication/detailed-network-serialization/
https://forums.unrealengine.com/t/question-about-intended-use-of-netdeltaserialize/2618842/2
NetSerialization.h:
Steps to Reproduce Add the following code a C++ project: `class FTestStructDeltaState : public INetDeltaBaseState { public: bool IsStateEqual(INetDeltaBaseState* Other) override { return TestValue == static_cast<FTestStructDeltaState*>(Other)->TestValue; } public: int32 TestValue = 0; }; USTRUCT() struct FTestStruct { GENERATED_B...
thanks for the help! i was banging my head against the wall trying to see how to do this and chatgpt was completely wrong, but this one worked!!!!!!
Hi, thanks for the answer. Reading the first article i found this:
both a 'delta' state (which gets sent to the client) and a 'full' state (which is saved to be used as the base state in future delta serializes).
NetDeltaSerialize essentially does the diffing as well as the serialization. It must do the diffing so it can know what parts of the property it must send```
Does this mean that in the case of delta serialization, i could use NetDeltaSerialize to prevent the replication of the struct?
I'm asking cause i want to only serialize some struct properties to a single connection, and would like to skip replication of the struct to other connections if the only thing changed is the property that they should not receive (like a per struct rep condition)
Yes, you can prevent replication of the struct (or parts of it) to a given connection, essentially implementing per-struct, per-connection replication conditions. You just need to carefully update the baseline so the engine doesnโt think you skipped something by mistake.
Ohh thats cool
Luckily i think i came up with a way to avoid doing this stuff, but good to know that is technically possible
Thanks for the help
Hello everyone. Melee abilities in my game have a noticeable lag when simulating average network condition. That's caused by the delay between the animation that plays predictively, and the actual collision detection and damage calculation that happens in the server. While I could try to predict everything, the issue is that I'm using GAS and a gameplay effect execution calculation for damage in my game, more or less following what Lyra is doing. And it seems like effect executions cannot be predicted - in fact looks like it's not even advisable?. Does anyone know how to handle that?
damage deffinitly should not be predicted
let server deal with it
you can get away with sfx, but damage and hit marker is server side
The problem is that I depend on the damage calculation done on the server (to know, for example, if the damage was zero post mitigation) to show a damage number and to play (or not play) a hit animation. That causes a perceivable delay in clients
welcome to the difficulty of multiplayer
prediction is a nightmare because you fundamentally have the problem of the server and client not agreeing on the state of the world at a given time
Indeed. I absolutely love how much easier GAS makes my life when it comes to multiplayer and prediction. But given that melee abilities are something quite common in games, I wasn't expecting to be so difficult to find good references on how to manage it properly
One does indeed not do damage predicted.
You can't predict death either. Imagine the client mispredits that.
Im trying to use repnotify to update ui when a variable changes, but I cant get the rep notify to fire. what am i doing wrong?
Is the event on the bottom left not connected on purpose?
yeah, I figured it gets triggered whenever the variable changes, but I'm guessing thats not how it works, since it doesnt
this works, but I dont need repnotify for that so I dont get what repnotify does exactly
The OnRep is in the functions list on the left
You gotta implement the code there.
And for arrays you might need to call "set" after the add unique
hmm what do I plug into the set? Add doesnt have an array output
The array. Just set it with itself.
https://forums.unrealengine.com/t/question-about-intended-use-of-netdeltaserialize/2618842/2
from this article i seem to understand that NetDeltaSerialize makes replication not reliable. Does that mean that FFastArraySerializer replication is not reliable too?
Steps to Reproduce Add the following code a C++ project: `class FTestStructDeltaState : public INetDeltaBaseState { public: bool IsStateEqual(INetDeltaBaseState* Other) override { return TestValue == static_cast<FTestStructDeltaState*>(Other)->TestValue; } public: int32 TestValue = 0; }; USTRUCT() struct FTestStruct { GENERATED_B...
I have a client-authoritative character, and AI Move To is not working on a dedicated server. What could be causing this?
I am having an issue with setting the player collision for client and host when entering a vehile. I have tried using repnotifies to disable collision of the capsule, putting it as a a run on server event, but when the player tries to enter the vehicle, the client sees the host fly away when I set the player location in the car, but the host sees themselves in the car
The collision is set on the server, but I guess the client doesn't see the collision disabled client side? I used a print string for the capsule collision and server says no collision but not client
the client runs the capsule sweeps on their end too, they must also be aware of the collision change at the right time
it is likely trying to depenetrate on the client side?
I have no idea what "fly away" means though
like are they just floating along the floor or flying into space from a big depenetration?
i would client predicate it
the client sees the host go high into the air, then gets set near the car car but not in it
On client user input enter vehicule -> disable collision on client + call server RPC to do the same using a variable
should it be multicast?
collisions are simulated locally, so when you update something everyone (server and each client) needs to know it
since its a state you should use a rep notify
I am using a rep notify. I currently have it set to the owning client sets the rep notify collision, then I also set it on server
so if you pause game, go in editor world, and check server and client game world, both should have correct info
BOTH characters needs to have the correct (and same) collision settings on client and server
this means server sets collisions on player 1 & 2, and client sets same collisions on player 1 & 2
so 4 times
does this get recieved on clients or not? this should be possible to just print log on the client when they trigger the onrep event locally
and if so, does it actually affect the collision settings of the capsule? you might also want to set their movement mode to none
it seems that by using rep notifty to set collision on client and server stops the the crazy movement, but now there are other issues I have to figure out. For example, the client sees the host get put in the car but falls down through the car and under the ground, even though I attached the player to a component in the car. And the client still gets placed outside of the car.
yeah, they are still simulating movement
it won't care about attachment unfortunately
you have to manually tell it to stop moving
the cmc does not know about your car
it would be kinda nice if attachment had some automatic handling but it's one line of code to set it to movement mode none
That's actually not true. Final Destination is all about predicting death.
๐ฅ
And how well does that end for them?
that's not a problem, that's how it should be. Hit animation can be predicted and played locally if that's your design choice but the actual damage and damage text shouldn't be predicted. If the players have 50 ms, it shouldn't be that bad but there's soo much you can catter to clients with a very bad internet.
for my game, the only thing that gets predicted for the melee combat is the client side attack animation and hit registry.
Client send server hit data, server validate then if all is well, apply damage server side which plays the hit react and plays floating damage text on client side.
Hello. I'm testing server travel in editor, map loads fine with clients and host, but triggering a logout event on game mode when traveling. Itโs my understanding that if a server travel is working as expected, there should be no logouts triggering in the game mode. Itโs my understanding that the game state and game mode should persist during travel.
I have server travel enabled for my game mode (i have my coop player states, game state, and controllers set as well)
Ue 5.6.1 Blueprint only
Using advanced sessions 5.6
Server travel using console command node ServerTravel LevelNamehere?Listen
Any help would be greatly appreciated. Thank you
im attempting to make a simple quest system for a MP game, and i have a question of how can i have the server give the quest to the client and have specific actors only spawn on their machine? like for example a trigger box that might be in a common area and i'd only want that client to have it (unless another client was also doing it).
i could just have the triggers always there but this would be horrible to scale and it would just be hard to manage, where im trying to dynamically spawn these actors when a client starts a quest , but this starting of the quest is on server, then i'd just do everything from there on the client machines? im just not sure how i'd ensure there's security that the client isn't doing something to finesse the variables at that point.
would the solution be to have the server just do an owning client event for the spawns of triggers and such? still doesn't seem like the right approach but curious if there's a way for this
Anyone have any suggestions on how to get the "random unit vector in cone degrees from stream" node to not desync between client and listen host? I'm trying to this but if I simulate ping the weapon spread is not the same.
On the server during begin play I run the logic seen in the second picture. I know the seeding itself is incredibly basic but Im just trying to get it to work for starters.
If I don't simulate ping it is fine, but if I add say 150 ms then it won't be the same. I also noticed that if the listen server fires a gun the spread pattern is the same on the client (with 150 ms ping), but not the other way around.
i think you can do the random thing but with a seed so that the randomized value would be the same, but latency would always casue things to be slightly different if they are firing the logic at different times
my idea was to set the seed once on the server, and then have it be replicated. So regardless of timing differences it should be the same. But I guess as long as latency is involved it will never work the way I want it to with this current setup.
Do I just call it an anti cheat measure like they do in counter strike? Where players see the spread differently from the server to prevent cheats. ๐
there's infinite approaches to handling what comes w latency, but if not using GAS or something that helps with client side prediction / rollback or anything, i think you just have to deal with the variance. i have a lot of traces / overlaps that will fire locallly on client and then on server and if the client hit then i take it as a hit on the server*, unless it's significantly off from the server, in my case i have it i think set to like 50 or 100 in all directions... which is a lot but if im a client, and i think i shot you / hit you with something, i'd like that to go through , pretty much no matter what , but it's a trade off.
Im not making a super serious competitive shooter so I could be more lenient like you are doing as well in reality.
there's def way better ways, but i went with what i could personally manage and works
But currently my client side prediction bullets are 100% visual
so ideally I would keep them 100% visual but I'll give it a think
yea but im sure you have that hit result, and you could just send that to the server upon the server event, have the server do it's logic, and compare the hit results / do anything you 'd like to figure out if you want the server to confirm the hit
yeah I could in theory do that
yea my client one is visual only but to get the effects/etc to work, im still doing a trace (bascially doubling the logic the server does, minus all damage etc)
im only having server deal damange and handle all logics with damage calculations
I'll see if I can get it to sync up somehow but Ive been trying for quite some time. So in the end I may have to leave it or try a completely different approach like yours.
im not sure exactly what you mean by sync but, but if you're doing anything that is happening at a moments notice and requires percision, i don't really think it's possible to have exact same results on both client and server with latency involved, if you're meaning to have the trace on client and server be the same
I was hoping that using the same seed would yield the same exact spread pattern but latency delays the process between client and server and that is factored in elsewhere
in the random vector in cone node
or rather I guess it isnt factored in, and thus it produces a different output with the same replicated seed
yea exactly, i dont know the entirety of the importance of keeping them exactly synced, but im sure it's not a big issue either way
Im trying to update a variable in all playerstates so it matches but I cant get it to work
Im spawning this gun actor and attaching it to the player pawn. I dont want the client to see it since its the version that everyone else should see. The mesh of the gun actor has "owner no see" set to true but the client is still seeing it.
Does the player pawn own the gun actor?
@latent heart Iirc, "Owner No See" doesn't matter for Actors that aren't the ViewTarget. The name of the property is sh*t. It doesn't check for Ownership, it checks if the ViewTarget is the Owner of the Component.
I ran into that quite a while ago when I made a custom Camera Actor that was the ViewTarget and OwnerNoSee/OwnerOnlySee stopped working on the Pawn.
In other words, you will need to show/hide the component manually.
well in the screenshot you can see the "set owner" node, I think thats how to do it correctly right?
thx got it working manually
Jebus
Does it surprise you?
No it does not.
anyone using websockets ?
Can anyone explain the concept of Use Lobby in Unreal OSS? What's the differences, since I though lobby or not is just how we implement the gamemode to be a lobby or a game session?
the whole things looks very cooked.
The collision happend on every machine since you don't put any filtering. This is very confusing, you need to decide who update what.
Also clients can't call RPC on player state. They don't own it.
Additionally what's up with the multicast that follow. The whole things need to be scrapped, you are doing it wrong.
while I can't tell what you are doing, it would be easier if you just forget about clients setting anything in this context. Let server be the truth and replicate the value to client.
have server do everything (i.e collision check and adding the keys) then client receive the Replicated value.
You own your player state so you can call RPCs on that.
i'm having this error [2025.09.01-15.36.14:023][726]LogNet: Error: Server is incompatible with the local version of the game: RemoteNetworkVersion=894084892 vs LocalNetworkVersion=2859918905, RemoteNetworkFeatures=GenericReplication vs LocalNetworkFeatures=GenericReplication
[2025.09.01-15.36.14:024][726]LogNet: Error: UEngine::BroadcastNetworkFailure: FailureType = OutdatedClient, ErrorString = The match you are trying to join is running an incompatible version of the game. Please try upgrading your game version., Driver = Name:PendingNetDriver Def:GameNetDriver IpNetDriver_2147480934
[2025.09.01-15.36.14:025][726]LogNet: Warning: Network Failure: PendingNetDriver[OutdatedClient]: The match you are trying to join is running an incompatible version of the game. Please try upgrading your game version.
i'm using a basically github version of 5.5.4
do i need to rebuild something cause the version mismatch is crazy
i literally build the server and client 5 minutes apart on the same machine with the same engine and project
Normally GameVersion is a steam thing in Engine.ini?
Question, how do you set your dedicated server game mode to start the correct map on a specific port only when current sessions are filled , and then kill the sessions when they become empty to prevent to many open sessions? Also, is it possible to start a dedicated session specifically only when a player needs that session?
Or do I only need to keep track of port, the game server port for players connect to, and then EOS will keep track of session ports?
And if so, when would I not need to set the port if it is handled by eos? Like would I need to tamper with the port for the game session in that case?
Problem: AI Pawn Movement Replication from Client to Server
I have a PlayerController that controls both a player character and an AI pawn. The player character movement works smoothly with AddMovementInput because it's automatically replicated from client to server. However, the AI pawn movement isn't working properly because:
The AI Controller only exists on the server
When I call AddMovementInput on the AI pawn from the client, it doesn't replicate to the server
This results in the AI pawn not moving.
Current Setup:
PlayerController has both CurrentCharacter (player) and AIPawn (AI)
Move() function works for player character (smooth replication)
Move2() function calls AddMovementInput on AI pawn but doesn't replicate
Question:
How can I achieve smooth AI pawn movement that replicates from client to server, similar to how player character movement works? I need the movement to be responsive on the client while ensuring it's properly replicated to all clients through the server. (Basically the player character and AI Pawn are identical characters)
I'm having trouble understanding some replication behavior in my project. It seems like a client is modifying a server-side object, and I'm not sure why.
Setup:
I have Instanced Static Meshes (ISM) in the world scene, created using PCG, so they are stably named objects.
When a player chops down a tree, here's what happens:
Flow:
-
On the server, a hit trace is done. If a tree is hit, I store:
- The instance index
- The actor's FName (via
GetFName()) - This data is stored in a replicated variable in the GameState called
TrackedTrees.
-
When clients join the game (or when
TrackedTreesis updated), they receive the updated data via OnRep_TrackedTrees. -
In
OnRep_TrackedTrees, clients use:
StaticFindObject(AActor::StaticClass(), nullptr, *StableName)
to find the corresponding actor from the name provided.
- Then, clients attempt to update the transform of the instance (using the index) on that actorโs ISM component.
The transform appears to be updated on the server, even though the update call is happening on the client. Why is the client able to modify what seems to be the server's version of the object? I expected the client to be modifying its local version of the actor/ISM component.
can anyone do 1:1 debugging an issue from my online 2p co-op prototype with me??? the issue looks really obvious but I wanna track down the root code or cause causing it. I think it resides in character movement component.
The issue is most likely because you're using StaticFindObject. In Editor memory between server and clients is shared unless you are using Multi-Process PIE (defaults to off).
In the "real world", this just wouldn't work at all and nothing would happen server side or client side. What you probably need to do is replicate a reference to the actor/component instead of it's name - this will automatically resolve to the correct object if they truly are stably named. It'll also be considerably faster and cheaper than what you're doing right now.
plz...
Describe your issue and you may get an answer.
Iโm working on a project, making a 2p co-op online game prototype using a listen server setup.
Itโs a 3rd-person perspective, and the player should change the rotation and cast a magic spell in the direction camera is looking at (not the characterโs orientation). so sometimes the character adruptly changes its rotation.
Hereโs how I implemented it:
When the player casts a spell โ Call Server RPC CastSpell with the proper yaw value.
On the server โ Call Multicast RPC CastSpellClients.
On the multicast โ Disable movement, Set actor rotation using the yaw value from step 1, Play the cast spell montage,โฆetc.
This works about 88% of the time, but sometimes the player characterโs casting rotation gets out of sync. It looks like a code in the middle of CharacterMovementComponent might be overwriting the rotation after step 3. but wanna know exactly where and how!
should look into gameplay ability system, pretty sure its meant for stuff exactly like that
When playing on Listen Server, if the client ping is laggy. For some reason, that character's animation on the Listen Server also lags / skip frames too despite the host's game running in perfect fps. Anybody know how to fix this?
I'm gonna sound insane, but that was my original approach. The server sends and clients receive a reference to the actor component, and it was getting the same behavior. (Clients received the reference to the actor component, but again any changes to it were happening on the server, not the client.)
When I couldn't figure out why I switched to sharing the name of the object instead.
hi there. im using the advanced steam sessions plugin in ue5.4.4 for my game. I'm trying to add a lobby browser so you dont have to rely on having friends online to host your own lobby. i can create sessions fine and even invite friends through steam and they can join that way, but using the "Find Sessions Advanced" node yields no results at all. The sessions are there because you can join via invites, but you can't just find them. Is there a fix to this, or is this a known issue people have to work around?
for more info. I'm just sandboxie plus on one PC, running 2 instances of steam and the game with separate steam accounts, i also test it with friends when I can and playing the game works fine, its literally just finding a session that doesnt work
I have the same problem. Invites work but finding session return no result. I'm using appid 480.
i have a quest where a player is just trying to get mechanics for the game (like interact etc), for these, i just want them to do simple actions that they could perform at legitmately any time, but i dont want to have that quest being checked everytime they interact or attack etc. im not sure if im overthinking how to do this, but i still want the server to validate the clients doing things but also dont want to that have that extra check for all interacting with the specific thing that is needing to be interacted with (if that makes sense)
You need to suscribe to the quest then your interact will check whatever is subscribed, so you need an array of subscribed callbacks to check.
once the quest is done you remove its callback from the subscribed array
this makes sense, and in some sense, this is how it works, like the quest event wont fire if you aren't on the exact quest, but it checks if you are on the quest first
by subscribe to it, would this be like a delegate of some sort?
it's almsot like i want code to dissapear after the quest, like not even have the code there after it's done
another method i've thought of, is to spawn (at the beginning of the quests) the specific thing that needs intereacted with via like a trigger box that would be destroyed upon completing the task, and, this would be spawned by the server and ideally only show up for the individual client, but then you have the server spawning multiple of the same thing *(if multiple clients are doing the quest) and just seems like the wrong approach. it's kinda like i want it to be a single player experience, which is causing me to run into a lot of issues with doing things solely for a single client
You can make an interactable base class with a virtual interact function, whether it is more efficient or not depends on how many of those you will need in the end.
You will also need a way to set the current interactable class depending on the quest progress
yea i have all of this setup, i've setup a child class to differentiate between the regular interactables and the quest ones, and these are quite few at this point, so maybe not an issue to have that extra check on 1 out of 100 of the possible ones you would be interacting with. also not doing this during the actual interact, rather just doing the quest message upon interacting witht aht quest interactable.... now i'd still love to swap that out with the regular one right after but this again leads me to not know what work around i could do so that it's only on their machine. but i dont think it's a big enough of a deal to matter that much, only if this was scaled to a drastic degree would i see it becoming too much to manage, but im aware of it enough to try to avoid that pitfall
As long as your interactable function is a client function that shouldn't be an issue. When the server gives the quest to the client then issue a client call that will do the setup for you
my only reasoning for this btw is essentially performance
yea i've thought of this , but how would i validate the action ?
server gives quest, but i still would need the server to know when the proper objective is completed
issue a server call then
well that is what im doing, but then the server changes that actor, on the server
actor is no longer quest actor, but now other clients can't do that quest in theory
I'm doing this for example: ``` if (ButtonPressed == EKeys::LeftMouseButton)
{
PlayerController->ServerSquareLeftClick(PlayerId, OwnerBoard.Get(), SquareIndex);
}
with auto PlayerId = PlayerController->PlayerState->GetUniqueId();
Maybe not the most efficient but it works
Can you just spell out what the player with the quest (and the other clients) should see and do?
I'm not picturing what you're talking about
I have a quest. It is fulfulled by me doing X. I see X. Other people see X
ok specific example:
- client interacts w npc
- server gives client quest
- first objective: find location (location in this case is a trigger box in a common area)
my issue already with this is, i dont want to hve that trigger box always theer, but only there for the quest for that client, but im not certain how i can have a server validated trigger box that would only be there during an individual clients play, without having the trigger box always on the server and only fire the necessry event when the client is currently on the quest (which would be checking this each time player is at that location for example)
this same principle would be applied to all things that would be variably*** necessary for each quest, but i could be missing a simple approach to making this work
Why not have the box be on the server?
Is this box valid for various players at various times or does it only exist for this one quest for this one client ever?
there's cases where a location / box would be valid at all times and necessary, but let's say it's just for one quest only once, that's the thing i'd like to solve for
But anyone can get this quest right?
at the moment, this is how it is, but checks if the player is on the quest first, so it doesn't fire anything extra other than the check if they aren't on the quest
Instead formulate it like this
yea, this would be essentially like a tutorial quest
your quest is formulated like:
Goal: Overlap
Target: Box34
Many ways to approach it but I'd probably poll on a timer in the QuestHandler.
Maybe once per second, check status of quests. I'd do a distance check first for overlap goals, then do a get overlapping actors and check if one of them is Box34 if distance passes
Timer:
Are we within extents distance of Box34? -> yes -> are we overlapping Box34? -> yes -> complete
If you're not married to using a box then a point is simpler
Client can check and server can verify
Client: I'm close enough to complete this quest.
Server: OK lemme check. Yup you are, marking it completed.
hmmm i do like that approach, so at start of quest, start the timer / watcher , and upon completion this would be stopped. i think this is good although, if many people are on that quest it ramps up the amount of timers going, or maybe i could have it add the players to check in the same event perhaps
Timer is clientside
client says "hey I'm done" and server checks
quest state should be serverside so gnoll ears or carrots picked is serverside and replicated
In this case the state is your pawn's position
but the checking of state vs requirements can be clientside with server only checking once a client claims they are done
Depends on if you need the quest to pop the frame that it's technically done or if a bit of latency is ok
location based requirements are a bit tricky as they aren't as discrete as gnoll ears.
It's easy to check requirements whenever you loot something, it's less easy to check requirements whenever you move (per frame)
I'd just poll for all of it and call it a day
ahhh that makes sense, i wouldn't have thought to do the timer client side. latency won't be an issue for the environment, but i'll have to give this a try to see how it feels
even if it's not a timer, and is instead bound to overlap, you can still save a lot of server perf by just making clients do all the checking until they think they're done, then server checks
You'll need some sort of protocol to not get stuck claiming you're done then server claims you're not
shits complicated
imagine how much of a PITA WoW is
with the phasing and the sharding
yea i've had cases with other thigns like this, def the worst... i've hit "reliable" on a few lmao
I'd probably do an unreliable call on the timer, and do that as long as the client thinks they are done until the server sets the replicated state to done
maybe even reliable if it's on a timer
You can also make this purely server side by having an actor that tracks all the players on the quest step that is associated with this bounds and then check the distances per tick. Time slice it so you only check say 5 players per tick which prevents overloading when lots of people are on the quest. Disable the tick when there are no players on the quest
QuestManager:
Timer -> for each QuestInProgress -> check reqs -> if reqs met -> ServerClaimDone
ServerClaimDone -> CheckReqs -> if done, move from QuestsInProgress to QuestsComplete
Question about the CMC for simulated proxies, can I use the server world time seconds on a client to somewhat accurately determine their position at that time on the server, if I record a history there?
think rollback/hitreg
server records history of player's position
client sends current time to the server, will the server's position of a player at that time somewhat match what the client saw as a simulated proxy?
or is it a bit more involved
If the server calls SetActorRotation() on client Aโs player character, will that rotation replicate to client A as well? Assume that bReplicateMovement is enabled.
I am expecting that it should replicate the rotation, but it is not working as expected, so I am asking it here.
Can replays be recorded locally?
As in on each client?
I think I can by what the documentation says, but, a weird question; can I play it backwards?
Would I set time dilation negative, to achieve that affect?
Can I play music over them, even if the replays didn't when they were recorded?
Has anyone tested to see how much memory replays take of memory? I imagine very minimal.
Game Recordings are just a hacky little "We act like the game gets replicated to us." thing.
The main DemoNetDriver simply runs the Serialization code on the Actors every frame, saves when that exactly was and later throws the serialized data into the function that usually receives that data.
And then you have different recording types, like to RAM, HardDrive, etc.
Clients should be able to record gameplay just fine. Idk if Lyra has a setup for it. ShooterGame definitely had.
Thanks. https://dev.epicgames.com/documentation/en-us/unreal-engine/using-the-replay-system-in-unreal-engine I did find this, it does leave questions though.
Is there a way to see how long a replay is?
Or time left?
Maybe an event when the end is reached?
i dont think they work in blueprints but in c++ you can use FNetworkReplayDelegates
FNetworkReplayDelegates::OnReplayPlaybackComplete
Hey im fairly new to game dev and im not entirely certain what some terms mean but I saw that when purchasing access to the ALGS movement system on Jakubโs Patreon his latest post says โnot replicatedโ and I wanted to know does that completely hinder multiplayer for any game using that system? I wanted to implement the ALGS movement into a game for me and some friends to play and just wanted to find some answers before I fully commit to a system that may become a roadblock in the future
I don't know who that is - but "not replicated" just means that it isn't supported in multiplayer.
That said - if what they're providing is some advanced Animation Blueprint, that doesn't mean a whole lot
Because those aren't replicated to begin with
But if it is like a BP class, it could be problematic because they didn't build things with MP in mind. So it could be a huge hurdle to retrofit MP on top of it.
following up on this, i switched it to a timer client side, and have it firing the server event after, it is a bit latent given i have it set to 1.5 seconds currenlty, but it does work.
makes me realize the overlap box could also be a similar solution with this same method, have the overlaps spawned at beginning of wuest on the client and have them overlap and fire the server validate event which just checks if player is within 500m of the location point (and thus destroying the client overlap box)*
Does UE have built in methods for replicating console variables? Like character.runspeed that can then be read by the server and all clients?
Or do I have to do something like that myself?
something like that yourself
ty ๐
Hello, I have a bunch of instances of a replicated pawn actor placed in my level, and on some of those instances I have overridden some extra properties, like the material on the mesh component. When playing in standalone those changes get respected, but when playing as client the material etc. get reset to the blueprint's default value.
I got around this by replicating a separate property (initial only), storing the material in there in the construction script, and then overriding the material to that in on rep notify.
But this seems a bit silly. The client should know about this material override right? It should be in the level data, how do I access that?
if you're setting the property at runtime, it's not going to be the same on every client unless what you do is the same on both client and server
assuming the property is set in the BP default it should be the same when run on clients
I'm overriding the properties in the level editor details panel (during edit time) for specific instances of the same BP placed in a level
then it should be the same on clients since that's baked into the bp
I'm guessing there's some initialization order problem going on
if you set the mesh on the component in the construction script it should work fine
or just set the components mesh directly and it should also work
๐ค I'm not making the changes in the bp, but in the level, so I don't understand how it would be baked into the bp.
I'm guessing I have this issue because bNetLoadOnClient is set to false and the characters are being spawned on the client as if it wasn't placed in the level, making it use the default bp values
but can I not somehow get the data from the level, for that specific actor instance, avoiding the additional replication. Since the client has that information already anyways.
net load on client doesn't replicate anything. it just means to spawn it as a client as part of a level
if you don't check something as replicated, it isn't replicated
yeah, but since this data stored on disk, can I not fetch it instead of replicating it?
there is no replication occuring
The fix I mentioned here is the replication I'm talking about, which I would like to avoid
just turn netloadonclient to true
can't do that unfortunately :(
why not
reasons... but thanks for thinking trough this with me
Does anyone know where the engine handles clients acknowledge receiving a property from the server?
Can probably trace what calls PostNetReceive to find it
Aye
Any idea why the engine would keep replicating a push model TArray<FSomeStruct> when it's never being dirtied?
Because programmers are the worst ๐
FSomeStruct does have a custom net serializer but I don't get why it's being replicated when nothing dirties it
I have yet to do anything with push model, never needed it, so couldn't say
idk friend has an array that's never marked dirty but replicates every 0.5s
they do custom delta serialization via a multicast rpc
idk if that would cause something like that to happen
but even without the property keeps being sent so

nvm turns out bWithPushModel was missing in the target
Does anybody know of a way for 1 controller to control two pawns on a client? Right now I am using a player controller and an AI Controller but the AI controller is only on the server so the pawn controlled by the AI controller is significantly less responsive
Get a reference to the current and second pawn on your player controller. Make a system that flip flops input or possession based on needs.
What if I need simultaneous control?
You can always just send commands to them
you don't NEED to possess
depends on what else you have though like movement system etc that might rely on possession
Yup, so it has character movement which relies on possession
And you are right I can send commands to AI controller to move, but the problem is since itโs on the client the movement of the AI pawn is not as smooth as regular pawn controlled by local controller