#multiplayer
1 messages · Page 291 of 1
Why are you doing this
what actor is this code in?
player pawn
or wait
its on the controller
but its after "is local player controller" so that returns fine
thats not the issue
why not just get possessed pawn instead of trying to get player 0's pawn
and it could be a race condition, could be that the controller exists before the pawn does
thers always something your missing.. yeah that was it >.>
Also
Spawning actor(projectile) from player pawn
but its cast failing
is instigator being set?
set to what
(on fails on client)
why is this in construction script and not begin play?
construction script might be early
instigator is replicated anyway, why does the client need to do this
Well since im avoiding self in the code it need to be set "in before" and this has always worked fine
on both sides or client only?
wait it was a misstake from me
a node was missing connection...
thanks
one last thing
im getting these annoying errors from my "log" code
Whenever a unit takes damage i create this widget and gives to all player via RPC, all works but getting this annoying error and im guessing its since the npc takes damage it wanna create a widget on the server which cannot be done.. but if i switch to remote only then it only works for clients not the host(listen server), Advice ??
Hello!
I wanted to make sure I had my "pause game" functionality in the best possible spot to make sure connected clients wouldn't have any weird issues or edge cases.
I currently have my "pause game" functionality setup in my player controller, which queries my game mode to see if they are alone (if yes it will pause run time). Then I simply add a widget overlay onto my screen for the pause menu.
is there a better place to put this functionality that's more universal?
You got null references all over hte place
I set up the default character collision and even moved it away from the collision as shown in the image. I also tried moving it from the mesh to the capsule, but the jitter persists. I increased the net update frequency. I also changed the network smoothing from exponential to linear.
You are saying that a new character class has this jitter with default settings?
No, I just made the character's collision preset the same as the new character's, like you said.
I only spawned the character on the map and the character is interacting with different things, I can't easily switch the character I'm using.
look at the CMC settings
not just collision
You can avoid doing something like this by making your UI listen for messages, allowing your "Log Box" widget manage when a message is received. This can be done by having the server multicast on something like the gamestate, and that multicast can call an event dispatcher that passes along the message. Your UI on construct can then bind to that event dispatcher and run whatever code is needed.
This will also fix the problem of worrying about having a dedicated server or listen server creating the widget or not as your game code doesn't have to tell a widget to do something, and your widget is instead listening for messages.
Hey guys, I am using FFastArraySerializer, it works, but in the PostReplicatedChange function, changedIndices is always empty for some reason:
void FInventory::PostReplicatedChange(const TArrayView<int32>& ChangedIndices, int32 FinalSize)
{
UE_LOG(LogTemp, Warning, TEXT("REPLICATION WORKING"));
if (!Owner) return;
TSet<int32> ChangedIndicesSet;
for (int32 Index : ChangedIndices)
{
ChangedIndicesSet.Add(Index);
UE_LOG(LogTemp, Warning, TEXT("Changed Slot Index: %d"), Index);
}
Owner->OnSlotUpdated.Broadcast(ChangedIndicesSet);
}
bool FInventory::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
{
return FFastArraySerializer::FastArrayDeltaSerialize<FInventorySlot, FInventory>(Slots, DeltaParms, *this);
}```
The settings in the image were different from the new character, so I reverted them to their original shapes (as seen in the image).
jitter has not been fixed
Are you getting any messages in the log while these corrections are happening?
only asset saved, save window destroyed logs etc.
always empty or sometimes empty?
Ofc not, A.I is lying to you. The issue isnt with the network setting but from getting correction.
You can check by running the console commans. P.shownetcorrection or something along that line.
Can someone remind me the difference in use case between SetMoveFor and SetInitialPosition?
Cause the first calls the second, but SetInitialPosition is also called after a move got combined.
So i cannot think of an example of something we would want to store in SetMoveFor and not in the other.
I would think about inputs, but those should probably not be include in CombineWith regardless, so it would not have negative effects to have them be stored in SetInitialPosition (as cmc does for bPressedJump)
Eh maybe something like Stamina for sprinting? The problem with move combining is that it will perform the first move, store it as pending and then combine it with the second move during the next frame before performing the combined one. Which means it performs the first one twice. That's why the initial position is used to reset the CMC back to the start of the first move, to avoid that problem.
Stamina in this example would be otherwise drained twice for the first move.
And then whatever stuff you can think of that wouldn't suffer from being performed twice would also not be needed for the move combining reset.
Yes stamina is the first example i could think of to be stored in SetInitialPosition, since it would be affected by CombineWith.
So basically SetMoveFor is mainly for stuff that is not "rolled back" in CombineWith?
But basically there would not be any issue with slapping everything in SetInitialPosition other then variable assignments being called twice for no reason (?)
The ChangedIndices array is always empty, the log inside the for loop never prints
Are you actually changing the items and marking them dirty?
Any idea how can I get rid of this? It is triggering because my OnRep function is called before static mesh component gets mesh applied and static mesh is being applied/checked in my own OnRep function.
Everything works fine but this triggering ensure is annyoning 😄 I don't wanna turn them off globally so I am asking about turning off this specific ensure, or some sort of idea to solve the actual "issue" which I guess is not a real issue at all
Haven't seen that one yet.
Could you share the actual code, so the OnReps you are talking about and where the component comes from?
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
this is child of staticmeshactor
disabling static mesh component replication gives same result
also, this ensure is propably only editor thing
btw, I'm half sure ItemClass.Get() will load already.
it loads
but it should be checked in packaged build I guess
and yeah I know I have redundant ItemDefinition checks
I mean that you don't need IsValid ? Get : Load iirc
Any reason the ItemQuantity uses a different DOREPLIFETIME macro?
em nope, it should be _FAST also
Hm, it's a bit strange though.
SetStaticMesh calls SetStaticMeshInternal, which should be setting the KnownStaticMesh via NotifyIfStaticMeshChanged.
The ensure comes from calling GetStaticMesh, which happens at the start of SetStaticMesh. So before you even set the mesh from the Definition, it's already in a bad state.
What's the callstack when the ensure hits?
I mean that at that point KnownStaticMesh is already != StaticMesh.
But that can't really happen
Like, let's assume there is no mesh assigned by default.
So StaticMesh and KnownStaticMesh are nullptr.
When you call SetStaticMesh(..), it won't ensure, cause they are both nullptr when it calls GetStaticMesh.
ah, yeah thats right
SetStaticMesh is then setting StaticMesh and KnownStaticMesh, so next time you assign, they are equal.
The thing is, however, KnownStaticMesh is an Editor thing for tracking if the Mesh changed.
Which means this isn't a gameplay problem, but rather that you are doing something during Editor time with it.
Is that Actor placed into the level or spawned runtime? Specifically the one that triggers the Ensure.
depends, but it has bNetLoadOnClient = false so it should be fully replicated to the client
And yes in code I have PostEditChangeProperty which applies staticmesh when ItemDefinition changes.
I am attaching ss of callstack
Hm but that should still cause the flow where it applies the Mesh and then KnownMesh.
This can only really fail if one of the two is set outside of the intended flow.
And yes in code I have PostEditChangeProperty which applies staticmesh when ItemDefinition changes.
You didn't include that in your pastebin
It's difficult to help if you paste partial code :D
Or wait it is
Why can't my browser find it.
haha 😄
Hm, but all of that should still go through the same flow, unless one of the two variables is of a different type.
Which doesn't seem like it, despite one being a naked pointer. So it's not like one resolved and the other didn't.
hmm let me check something, I think you pointed me onto good direction
I would suggest you start breakpointing the different functions in that component
The natives ones, such as NotifyIfStaticMeshChanged SetStaticMeshInternal OnRep_StaticMesh SetStaticMesh, and see if anything calls in a weird way.
ok I think I know the reason
I placed the item on fresh level
so I assume some instance on test level had manually applied different mesh when I was coding it
yep
I forced OnConstruction (moved every actor)
Did you maybe forget the Super call to PostEditChangeProperty at some point?
let me restart the engine once again to sanity check
Cause I could imagine if that is missing, you could assign the StaticMesh by hand and it wouldn't trigger the NotifyIfStaticMeshChanged stuff.
E.g. if you ever did:
- Forget Super call there.
- Assign Mesh to Actor in Level
- Save Level
- Notice it's missing and add it.
- Restart Editor.
Result: KnownStaticMesh isn't set.
Just an idea.
Or maybe within the OnConstruction you forget it for a short while.
Any kind of missing Super call in an override that would otherwise lead to the notification and KnownStaticMesh being set could cause this.
But glad you figured it out (: I have to focus on crash fixes now.
nope still triggers, I was wrong
but yeah if you don't have time its not a problem, thank you anyways
Here is what you can do next:
- Check if every override calls Super:: properly.
- Breakpoint the functions I mentioned and check what calls them and what the values for StaticMesh and KnownStaticMesh are each time.
- Check if it's always the same Actor, if so, remove it and place it again, maybe it's corrupted in some way.
- Try manually calling
NotifyIfStaticMeshChanged(only inside WITH_EDITOR I think) when you apply the ItemDefinition.
yeah sure, thank you 😄
Yes, I am
I specifically use only one function for changing anything so that I make sure the marking gets called.
bool UAC_InventorXBase::SetItem(FInventoryItem Item, int32 Index)
{
if (!Inventory.IsValidIndex(Index)) return false;
Inventory.Slots[Index].Item = Item;
Inventory.MarkItemDirty(Inventory.Slots[Index]);
return true;
}```
Quite useful thing that I just found out, and never realized it worked like this.
Since, given the wording, and my understanding of it, it working like this didn't make sense.
But, turns out that when on rep / replicatedusing is used on a replicated reference (actor, component, maybe object?)
When the replicated thing becomes relevant from network distance, and the such.
It will call the on rep function.
Since from my understanding such thing is only called on actual value change.
Not the thing its pointing to changes.
Any idea why anim notify from an animation not working on client side after i upgraded to ue5.7? It should be running on server by default.
@summer tide perhaps theres misunderstanding? Anim notify gets called locally.
It will fire when ever the machine playing the anim hit the trigger.
OnReps will be called if an Object GUID is mapped/unmapped yes, but they won't fire if the properties of that object change. The Onrep is firing because the value of the pointer changed.
Without this race conditions would be almost impossible to workaround too
I didn’t know about the mapping.
I assumed it was legit just “value change”
I'm having a camera jitter issue.
Originally, the camera was attached to the character's head socket on the mesh. To try to fix the jitter, I detached the camera from the mesh and attached it directly to the capsule component instead.
I also made sure that the character's movement speed is not being modified during gameplay, and the Character Movement Component settings are the same as the default Unreal character.
Despite these changes, the jitter on the client still persists. The server view is smooth, but the client camera becomes jittery while the character is moving.
It still boils down to the same problems....
If it only happens to clients, then it's something to do with how things are networked as jittery movement on clients only is usually something to do with how the character movement component is being used.
You'd need to review all code relating to any movement you may be doing, including anything you may be doing on tick for movement, or anything that may even interact with the movement component.
It can also be related to what the players are walking on - if what they are walking on is not part of the level by default, and you're spawning the level on the client (maybe some PCG system?) that can cause issues as well.
Since there was no problem when I stood still and spin around, I didn’t think that was the cause, but could this be the reason?
Standing still and rotating the camera around doesn't use the CMC.
What makes you think that :D
Fiiiiine.. it does... but not in the sense of causing the jittering they're seeing.
Jitter when moving sounds like corrections. And since the capsule isn't smoothed iirc but only the mesh, it would probably get worse parenting it to the capsule
Without a video and corrections being drawn, hard to tell
https://discordapp.com/channels/187217643009212416/221799385611239424/1480630809609371869
Here's the video they posted a few days ago... It doesn't have the corrections being drawn, but in the second half, does look like typical net corrections.
Actually upon closer inspection, even the first half is pretty bad XD
is the jitter from corrections? enable visualizing net corrections
p.NetVisualizeSimulatedCorrections etc
ok so im stil struggeling with this one..
So unit takes damage then casto the the "damagin actor">get controller spawn widget on that player. it works for the listen server client but on Clients i get error that i need local player only... i guess its just node thats needed ...?
player controllers for other players are not present on clients
the server has all player controllers
clients ONLY see their own unless one is locally spawned (you don't do this almost ever though)
and they receive their local playercontroller from the server as a replicated actor that can arrive a bit later in some race conditions
read the multiplayer compendium things in pinned, it is really really important you understand the playercontrollers are not on every client
in this case you probably just want the local player controller here for both cases as they are who will see the widget
thanks for the respons i will read thru the doc for sure,
But in this case how do i get the local player controller=
If Splitscreen doesn't matter, in theory with get GetPlayerController(0)
I'm, as usual, confused how this base level stuff is still not clear to you after all this time :D
ha yeah, i have that affect x)
its not splitscreen*
its weird some things im really good and and knowlagable about but other stuff just dont stick...
since its on a NPC(Server controlled actor) this code is running from then that will call the listen server´s playercontroller
right
or nevermind thats wrong
basically on a dedicated server you would not want to spawn the widget anyways
so getting the first local player controller is fine on the listen server and clients for the purposes of spawning a widget
hm okey,
but even if i get (get playercontroller)0 on my clients it only displays on my listen server client...
is that code running on the clients or not?
absolutely crucial to be able to answer that question every single time
even if it's just using a simple print log
it can be confusing but logging will show the name of the current world's debug string from bp (client 0, listen server etc)
yeah, thats what i did when u asked* that was a silly misstake
yeah it stuff like that i mostly stumble on 90% of the time and my head gets all twisted
now everything works as intended by just doing this small change...
but yeah anyways thanks for the help !
@thin stratus thanks also, and i might never get better but i still love doing game´s so admire the commitment* atleast 😉
Like actually read the network bible 12 times with lots of experiment. Thats how it clicked for me.
Start with empty project and just do very basic simple thing. Dont dive into your system until you understand how to communicate between server and client.
is RMS (Root motion sources) supposed to support prediction on simulated proxies? i read this quote (from this article):
Any movement effect that should be responsive, should be (1) executed predictively on the controlling client, (2) executed authoritatively on the server and (3) executed again when resimulating moves. As a bonus, predefined behaviors may also (4) be executed predictively (extrapolated) on other clients on sim proxies of the character.
Root motion sources are CMC's way of providing (1), (2), (3) and (4) out of the box for some common types of temporary movement.
i might be misunderstanding it but i was hoping it was possible to apply RMS to a sim proxy and if the params match on both the client and server, i wouldnt see the movement i already predicted being rolled back on the client. i am trying to use this for npcs knockback. i am open to other suggestions to predict this
ive print out the codex got some night reading for the next month
Question
What would be resonable values to simulated a "normal P2P" session ?
or what values are recommended +
depends on the game and your tolerance
some game requires more responsiveness than others.
e.g shooting games.
hm 4 player co-op "small-midd size" maps with 100 npc at a time, 3rd person medival (not shooter)
co-op or not makes no different tbh.
only difference when it comes to co-op or competitive is you can chose to trust the client more, so it's easier to design the network code.
I would suggest playing simmiliar games on steam.
and just hop on different server with different ping.
see what feels acceptable or not.
Generally 70 ms is noticeable.
more than 120ms already feel frustating.
yeah agree
but incoming/outgoing what would be the comparing values
same same or sshould it vary ?
normally I just use the console command and enter the ping I desire.
p.NetPktLag X something like that.
it will emulate
aye ill try that
im thinking all 100+ is almost unplayable
even if everything "works" it s still not fun to play
yeah
do u have any failsafe above 125 liek the game stop or displays a networking warning or something ?
i guess that would be nice to indicate that
displaying network warning is soo trivial.
just check the ping, you can get it from player state.
I haven't implement my system yet, but eventually I will give window for the client to send data to the server.
e.g when handling damage, the server will give window to the client to send data to the server.
Like their input or their state (e.g blocking, parrying, etc.).
but if the data didn't come soon enough beyond the treshold, then I will just ignore the late data.
aye
meanwhile me testing my co-op server auth game at 400ms to make sure it is playable 
I'm not sure if trying to make sure 400ms being "playable" for a player isn't as important as the game not blowing up because someone is playing at 400ms. XD
Hello, does anyone know why I get timed out in 2 seconds when connecting?
It wasn't a problem up until I added some stack trace dumping in the initialization code which makes the server stall a little making it take longer to get through that code, which is over this wildly short period of time.
I checked out all the parameters that contain ConnectionTimeout in them, and the only parameter that has 2 in it is this
/**
* Amount of time to wait for a graceful close/bPendingDestroy to complete before considering the connection timed out.
* This is the time used to allow any existing, pending reliable data to be acknowledged.
*/
UPROPERTY(Config)
float GracefulCloseConnectionTimeout = 2.0f;
Changing it to 10 didn't change anything. The comment makes me think that it shouldn't be the right parameter in the first place, looking at other parameters, there's
/** Amount of time to wait for a new net connection to be established before destroying the connection */
UPROPERTY(Config)
float InitialConnectTimeout;
but it's already set to 30
Does anyone know why I suddenly can't play multiplayer in PIE anymore?
LogNet: Error: LoadMap: failed to Listen(/Game/Maps/TerrariaWorldGen/Deliria?listen)
LogOutputDevice: Error: Ensure condition failed: EnableListenServer(true, ListenPort) [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\GameInstance.cpp] [Line: 561]
Starting Listen Server for Play in Editor failed!
Idk use a debugger
Anyone have a good tutorial on how to create "Friendly target frames for the Ui" ? (dispolaying all palyers own frame
wdym by friendly target frames?
what frame? frame per second?
haveing each party meember s healthbar in the Ui *
(not floating widget) but in the umg
k, why do you need tutorial for that? it's pretty trivial.
You get the health component from the players you want to display then just read from it.
having it float or not is irrelevant, the method to get the data is the same.
you know what.. it is, i just made one myself in 2 minutes... so yeah newvermind
i did just overthink it abit..
Hey
Returning dev question: for Chaos Vehicles do we need something special to make it networked? e.g. if I have Vehicle Movement Component, what should be done to make it work over network?
Hey guys, does FFastArraySerializer only replicate to owner? I set a chest actor to be always relevant but clients have no idea about its contents even tho it uses the same class of an inventory component that all clients have on them which works
Does FFastArraySerializer only replicate to owner? No, it's only a tool to minimize the data that is passed on the bandwidth that moves between server/client more easily, to whom it replicates is dictated by the replication variable configs, just like any other variables, if your inventory variable is configured to replicate to owner only, then yes, it would only replicate to the owner, not because its a fast array but because thats how the variable was set.
For your chest, always relevant and how it replicates to players are 2 very different things. Having it set to alwaysrelevant doesn't mean the data will reach your players. Confirm that your chest, the component, and the inventory variables are all set to replicate
The chest is set to replicate, but how do I make the inventory variable replicate to anyone that opens it?
I do all the DOREPLIFETIME and other stuff for it
@lusty palm show your code
The inventory actor component is quite long with a lot of unrelated stuff but basically I have:
// In .h file:
UPROPERTY(Replicated)
FInventory Inventory;
// In .cpp file:
void UAC_InventorXBase::GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ThisClass, Inventory);
}
UAC_InventorXBase::UAC_InventorXBase()
{
PrimaryComponentTick.bCanEverTick = false;
Inventory.Owner = this;
SetIsReplicatedByDefault(true);
}
It works for characters when the inventory component is on them, clients and server can read it
but when it is on a chest nearby clients cannot read it
Post everything related. Show if the chest is replicated.
Then show how you add the data to the fast array.
it may be the way I access the chest, this is just for testing the replication after all
BP Inventory Test is the chest
Begin play runs on everyone, this is a wrong way to add items to your chest.
Well its fine but make sure to only server adds or remove item.
I know, I am just using this for now to test, it had a switch authority node but I probably deleted it by accident
Because replication work from server to client.
Also for fast array you have to mark the array dirty after adding an entry.
Have you done that?
My problem is clients don't get slots from the chest at all
Of course, how else would it work normally without being on a chest
bool UAC_InventorXBase::SetItem(FInventoryItem Item, int32 Index, bool bBroadcastUpdate)
{
if (!Inventory.IsValidIndex(Index)) return false;
Inventory.Slots[Index].Item = Item;
Inventory.MarkItemDirty(Inventory.Slots[Index]);
if (bBroadcastUpdate) OnSlotUpdated.Broadcast({Index});
return true;
}```
Ensure the chest actor is replicated
Also I am marking only the item dirty because I am changing the FInventorySlot struct not adding another element to array
Not just the inventory comp but the actor it self
It is I checked yesterday
Set it to be always relevant just for debugging
Whos calling set item? It should be server only.
In which case your broadcast shouldnt work on client.
You can do the broadcast on PostReplicatedChange on the fast array for client.
For the listen server, the broadcast from the setitem fires, for the client, there is a broadcast in PostReplicatedChange
Because the PostReplicatedChange doesn't fire for listen server
Yup well i am doing the same thing ( chest and dropped loots ) it work for me.
That doesn't matter tho as the initial array replication doesn't work at all
Like I try getting the quantity of Item at index 0 in chest, server says 5, because I used setitem on server, but client still says 0
What do you do when you open the chest, how do you replicate the inventory to clients or do you only use distance?
I read somewhere it is because the inventory component is added in BP, could that be the case?
No. It'll function identically for replication.
Well for some reason it doesn't 😭
My test soo far is that the actor is relevant
Are you sure your widget is bound to listen to changes to the test inventory? The logic you have right now could result in the client creating the widget before the actual contents are present.
@lusty palm I went home and try to look at my project again.
I suffer from the same issue XD.
if the component is in player character, all is well (I'm guessing other actor that the player own should be fine too).
but when placed on the chest or non owned actor, it doesn't replicate.
Clients load a lot later that the server and the server can see the chest's contents and yes I bind a delegate
Yep, weird since I turned on replication, even tried doing ForceNetUpdate, etc.
I must be missing something...
id start with adding an OnRep to your replicated Inventory variable that just prints a string and confirm if its getting replicated or not
I'm curious, anyone here used the multiserver setup epic got ongoing :)
The subobject didnt get replicated if the inventory comp is in non owned actor on me. Its weird.
I just print the value with keyboard and its null on client
Btw this only happend with fast array 0o.
EXACTLY
Although it's structs for me
and the item quantity returns 0 when it should be 5
Earlier i thought i had everything working but reviewing my project my chest didnt store any items. It just generate replicated items for my player to pick up.
The moment i attach inven comp, making sure the actor replicate as well as the component. It still not working.
Server add the item and able to see it. but the item doesnt replicate to clients.
Same for me, but if it is on a character controlled by a client, that client can see it normally
I hope I am missing something since if this is a bug I think we have no alternative
My inven comp is in pkayer state and all work fine and replicated.
Tried attaching it to character and thats finr as well.
I think we should file a bug report just in case?
Waiting for an elder to give their opinion.
yeah
Hello,
is this the way to "open a dialogue window" via Interface? (Set_InputMode basically shows the UI element)
This would mean the Actor I interact with causes the UserInterface-Widget to show...or is there another/better way?
The code shown doesn't appear to be doing anything with showing any UI elements - you are calling a custom function in WB Player UI called "Set Input Mode".
Ideally you wouldn't have game code specifically telling UI to do things. The UI should listen for messages and update itself and display as necessary. An example of how to do that here would be that your "Interact" interface could signal to some component on the player which then calls an event dispatcher (Possibly an inventory component in this case since you appear to be dealing with a "Loot Container" widget?). Your UI would bind and listen for that dispatcher on the player's component to then display what you want rather than having your game code have to get the HUD, and reference to your UI and Loot Container and tell it to display it.
So the flow ends up being more like:
Player presses "Interact" button > Finds interactable target > Calls "Interact" interface on target.
Target is meant to open the loot interface, so it uses your Player reference (assuming Pawn) and "Gets Component of Class" <InventoryComponent> and calls some kind of function like "Display Container" passing along a reference to the appropriate inventory you want to view when you call "OnOpenedLootContainer"
UI on Construct gets owning player pawn > "Gets Component of Class" <InventoryComponent> and binds to the OnOpenedLootContainer event dispatcher and runs whatever code is needed to display the UI and reads the appropriate inventory you want to view and displays it.
Yeah as mentioned in brackets, the "Set_InputMode" function actually shows the UI. Its a general function so I just have to feed in the widget and it shows the UI element with mousePointer and all etc.
Its basically a "ShowUI+MousePointer"-Function (and if the Widget is already shown it actually hides it etc.)
Ahh i think I get what you mean here.
(example code for now) like this,right?
AC_Base I just made up for example purposes
Yea, that makes this actor bound to the component rather than the UI directly.
I'm losing hope, I may try using normal TArrays for chests or something if this is not resolved lol
aight, thanks for now, gotta redo a lot of things. ill tag you later/tomorrow when im done with either more issues or the successful result 😄
Hi, i am trying to make my dash work on multiplayer, i already created the FSavedMove_Character and the FNetworkPredictionData_Client_Character for my sprint and for a basic dash and it works good with network emulation , but i still have some questions, i wanted to change the ground friction while in dash so it can go and break easily, should i also include my ground friction inside FSavedMove_Character ? Also on multiplayer how should i detect the end of the dash ? Should i set the dash direction on server as a reliable rpc ?
why do you need a separate rpc if it's in the saved move?
you might need something for sim proxies to be aware of it I guess though
https://dev.epicgames.com/community/learning/tutorials/ywD1/unreal-engine-best-practices-for-networked-movement-abilities-cmc#rpcarrivaltimingissues I would generally say having it all as part of 1 saved move sent will be nicer at least for timing (it can be as simple as an incrementing index etc to not miss in-between states?)
because i thought that only compressed flags could be send for movement
you can put any information you want in there?
Does anyone know why a chest with an inventory of FFastArraySerializer won't replicate inventory contents to nearby players but if the inventory is on a player character it works normally?
I think you need to show more of what you're actually doing.
I just set up a FFastArraySerializer project for testing and everything is working as expected, with a replicated actor placed in the level with a replicated component, no ownership needs to be set.
Like... Where does your clients get the values from? Are you relying on the PostReplicateChange or something else to get the values on the clients?
you can add whatever you want if you extend saved move
(you could even make the changed flags make the existing values be interpreted differently etc)
PostReplicatedChange yes
And they work for inventories on the characters clients own
how are the chests created and how is the fast array actually on them
What does your PostReplicatedChange function look like?
I'm waiting for the moment something is being ran through the PlayerController.
Chests for now are just placed in the level, the fast array is on a component which I use for characters too.
One sec booting up Rider
is this replicated? what net load on client setting does it have?
Yes, chests set to replicate, net load on client, never go to dormacy
FastArray or not. Any replicated property requires you to fulfill a few basic steps.
Is the property replicated?
Is the property in a component? If yes is that component replicated? And is it's owning actor replicated?
Is the actor related to this property's replication relevant?
Are there any Rep conditions?
Something here is wrong.
void FInventory::PostReplicatedChange(const TArrayView<int32>& ChangedIndices, int32 FinalSize)
{
if (!Owner) return;
TSet<int32> ChangedIndicesSet;
for (auto& Element : ChangedIndices)
{
ChangedIndicesSet.Add(Element);
}
Owner->OnSlotUpdated.Broadcast(ChangedIndicesSet);
}
bool FInventory::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
{
return FFastArraySerializer::FastArrayDeltaSerialize<FInventorySlot, FInventory>(Slots, DeltaParms, *this);
}```
the silent return on Owner is very sus
The Owner variable is of type UAC_Inventory_Base
is owner being null here expected?
it shouldn't be null and I don't think it is
will check
instead of guessing
make it ensure
there is no need to guess here ever
or even just error log if that is too annoying
It's supposed to be annoying. 😂 Shit went wrong that was never supposed to. Fix it.
if (!ensure(Owner))
{
return;
}
ensure can be done inside of an if statement as it just wraps the call
you can even give it a formatted message if needed
oh so i did not fully understand that
you might be able to get away with a separate rpc but generally separate rpc = random timing in relation to the main saved move sending
it's possible though if you disable corrections from that rpc separately I guess (there are situations where this can make sense if it can't be missed)
No errors nor crashes but the clients don't replicate, so I don't think it's the owner
i am reading this now, thank you
FWIW you are already miles ahead of the average here by even knowing about the CMC saved moves lol...
I guess just keep in mind the goal is to do the same thing on both sides and be close
does ANYTHING about the chest besides the fast array replicate dynamically? and by replicate I mean a value not set by the level, but changed by the server afterwards
just as a sanity check
And in the component I do this:
UAC_InventorXBase::UAC_InventorXBase()
{
PrimaryComponentTick.bCanEverTick = false;
Inventory.Owner = this;
SetIsReplicatedByDefault(true);
}
void UAC_InventorXBase::InitializeEmptyInventory()
{
Inventory.Slots.Init(FInventorySlot(), StartingInventorySize);
Inventory.Owner = this;
Inventory.MarkArrayDirty();
}
void UAC_InventorXBase::GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ThisClass, Inventory);
}
Chest is a blueprint actor, would it be the same if I made a variable on it, set it to replicate and changed it? Since Inventory is in C++
I would recommend using push model replication for fast arrays but I don't think that is the problem (generally speaking you save a ton of server perf by not polling everything)
yeah i am still having a hardtime understanding the framework when trying to do a more complex movement , sometimes it works like magic, i will dig deeper so it can be less magic for me
I guess we specifically care about the inventory component here more than the actor's replication properties
Wait, is this the right setup for a variable to replicate in BP?
Because it doesn't, I change it on server and it doesn't change on clients at all
And this is the actor:
So nothing replicates correctly then
What about the actor itself, in the level you've placed it in.
The actor is there on the clients as seen in the image above (the cube), but none of its variables replicate for some reason
But what are the actor's replication settings for that instance? Both the actor and the component on it. Not defaults.
Looks like the only setting that is changeable on the actor from the defaults is the net load on client which is set to true anyways
Component is set to replicate, cannot be changed on the instance anyways
But the component doesn't matter if the actor doesn't replicate any of its variables
And this is where I update the value on server
It was off for me, tried turning on yesterday, nothing changes
I was going to ask if a force net update helped but you already have that
afaik activate is basically an optional side thing that some components care about and most don't
Yeah, just looked through it.
it's a bit confusing but it's kind of mostly a thing for like particle system components iirc
what authority does the object have on the client?
How do I print it from BP?
just print string after getting the local role?
Ahh get local role
that's what I was asking
look at what the local authority macro does (the switch)
that makes sense here, yeah
I must be missing something here, I checked the checkboxes needed and set variable to replicate and it doesn't work
I hope it's not a bug
I am curious if a temp randomly set replicated property on the component replicates
On the component, but a temp does not replicate on the actor even?
I can't tell if this is just not using fast arrays correctly or if the component isn't replicating at all due to the nature of it being placed in the level
I think it's because of the actor, it doesn't replicate any of its properties at all
I don't think the component is to blame
It might be interesting to spawn one of these chest actor bps at runtime on the server
that way it will be a regular dynamic replicated object
Without the switch it works, but I assume it's because clients spawn their own, with the switch however only server sees items
this is in level bp btw
void FExampleArray::PostReplicatedChange(const TArrayView<int32>& ChangedIndices, int32 FinalSize)
{
OwnerComponent->OnRep_ArrayItemChanged(-1, 255); // This gets called always.
if (OwnerComponent)
{
for (int32 Index : ChangedIndices)
{
OwnerComponent->OnRep_ArrayItemChanged(Index, Items[Index].ExampleIntProperty); // This does not.
}
}
}
Yea but PostReplicatedChange() is only for UI updates, clients should still print the item quantity correctly (which they do not) right?
It's not just for UI updates.... Is for anything that you want to happen when a change is received from the FFastArraySerializer.
verify instead of guessing
In my case I mean
In my case, it's triggering the function on clients, but the ChangedIndices appears to be empty.
it is crucual you can actually verify what happens on both client and server... you should NEVER need to guess
So you'd not have any values in there, meaning your functions aren't getting called.
I did, because it doesn't actually change inventory contents of the server actor, they get their own
instead of branching on local authority here branch on the local netmode not being the client
Because you are iterating over it incorrectly
<_< No.
Yes, int32&, just try that, have no idea, but happened to me too
don't let clients locally create this actor (it can actually be useful to do that in some cases but not here)
or just use auto& Element : ChangedIndices
Yeah I know, and when server creates it, it doesn't replicate properties again
Ah good point... trying.
For some reason int32s are references, don't know why
It bothered me so much the other day
Until I figured it out
nvm, they are references because they use TArrayView lol
forgot
I suspect the fast array is being handled differently for this chest than the ones on the players
do the players dirty elements differently?
does a normal replicated property on the actor replicate down if you spawn it only on the server at runtime?
Nope... Length is being reported as 0
No, the items get dirty on any change, when doing SetItem() but I don't think the component is the issue if the actor won't replicate
I'm also not a fan of not using pushmodel replication but I don't know if it matters here or not
For me this works ```cpp
void FInventory::PostReplicatedChange(const TArrayView<int32>& ChangedIndices, int32 FinalSize)
{
//if (!Owner) return;
if (!ensure(Owner))
{
return;
}
TSet<int32> ChangedIndicesSet;
for (auto& Element : ChangedIndices)
{
ChangedIndicesSet.Add(Element);
}
Owner->OnSlotUpdated.Broadcast(ChangedIndicesSet);
}
Oh, everything is working now? 😛
is the chest actor set to replicate?
I think they mean just the player inventories (which is a good sign as it means the fast array is sending sometimes)
Yes
No, player inventories worked from the start
And what I'm getting at, is on the clients, ChangedIndicies is reporting as 0 always, despite changes coming through.
on a component attached to a separate actor of course 😛
Maybe length works differently for ArrayView
curious if swapping to DORM_Awake dormancy helps
I'm not super clear on how dormancy works in the literal code but that is one non-default thing set here
So from bp it would be this one?
yes
But it says it can go dormany but is not currently if set to this
I think it was defualt in bp
yep, the arrow not being there means it is default
the little arrows on the right indicate you can click them to return it to default
(most of the time)
Yep still nothing
so if you add a new replicated propertry on to the actor bp
and change it randomly from the server
the clients don't see the change at all?
Nope
tested with another actor that doesn't have the component at all
still nothing
did you forget a super:: call somewhere?
It's in bp
I mean if it has a native parent
I feel like I am missing something about the setup here... which netmode is this in?
Listen server
I'm not seeing a good reason for this to actually break a normal replicating bp but I also can't see what you are actually doing
I assume beginplay is being issued normally by the gamestate etc
definitely open the output log and check for big errors
No errors at all
aside from "unfocusable widget being focused" which isn't related
this one
yep
so you are saying this doesn't even appear on clients at all? (the dynamically spawned replicating actor bp)
or that it just doesn't replicate properties (and by this I mean adding a new scuffed float or something just to test)
fast arrays REQUIRE you actually dirty them in the intended way every time
It doesnt replicate
I know ```cpp
bool UAC_InventorXBase::SetItem(FInventoryItem Item, int32 Index, bool bBroadcastUpdate)
{
if (!Inventory.IsValidIndex(Index)) return false;
Inventory.Slots[Index].Item = Item;
Inventory.MarkItemDirty(Inventory.Slots[Index]);
if (bBroadcastUpdate) OnSlotUpdated.Broadcast({Index});
return true;
}```
do you mean it doesn't create the object on clients or that the properties do not change?
I added a testrep int and it does not replicate, spawned it on level bp, the actor is there but the var doesn't replicate
I can only perceive information you show me in discord
It creates it yes
okay, so the property is not changing but the actor does arrive
can you show it being different on client and server?
wdym
I am asking to see how you determine the value of it
even just printing it out in the bp onrep +beginplay is fine
begin play may fire before that replicates to clients <_<
server: 32 client 1:25 client 2:25
Make it an OnRep
ya
yes
I was able to get thigns working right on my end, but I had to use
void FExampleArray::PostReplicatedAdd(const TArrayView<int32>& AddedIndices, int32 FinalSize)
Even tho I'm changing the same index o_o
yeah I think in general you want both added and changed... I recall this being confusing at one point
and removed of course
Not fired at all
Wait it does fire, it made a new func tho when I switched it to repnotify again
So I used that one and it does replicate
Since I open inventory on beginplay, I assume it may not have time to replicate?
Yep, that was it, damn, didn't know beginplay fires before replication happens
Thanks guys
That's why I had asked and mentioned this.
https://discordapp.com/channels/187217643009212416/221799385611239424/1483281002888429701
One client can move contents, other client gets UNetDriver::ProcessRemoteFunction: No owning connection for actor BP_InventoryTestActor_C_UAID_30560F1C9911D6C802_1416337361. Function Server_MoveItem_UI will not be processed.
If your UI is being created on begin play and you're not actively listening for changes to the component, then it could have the wrong values :/
How do I fix that
You can't call RPCs on unowned objects.
How does client 1 own the object when it was made by server
If you want to move something from one inventory to your player's inventory, you need to call that from your player's inventory.
Ah that's bad since I use the Drag and Drop operation to tell it the destination and I cannot do it when I have to tell it the source instead of the destination... I have to clear my head after this lol, maybe there is a way
Include the source inventory in your drag and drop operation.
Dropped on your player's inventory:
PlayerInventory->Server_Move_Item(Source = Source Inventory, Destination = Player Inventory)
Dropped on your target inventory:
PlayerInventory->Server_Move_Item(Source = PlayerInventory, Destination = Target Inventory)
I already use this and it works and fired when the component that own the fast array is attached to player state or player character.
Righttt, thanks
Doesnt fire when its on some actor. But im gonna try again today.
Didn't you have the same issue as me
Also for the failed test, i add item on begin play as server. Server have the iten.
But client null.
Ye
Ufffff, your inventory uses objects
Theres a thing for replicating subobjects, look it up, it seems a bit complicated, you have to register them or smth to replicate
Mine used objects too before I transfered to structs
Ye they work when the comp is owned by player though.
Again, seems like issue is related to using PostReplicatedChange only.... It still shows the length of ChangedIndices as 0 even with the component attached to an owned player character.
Using PostReplicatedAdd seems to works correctly regardless of where the component is.
Are you sure that's just not how ArrayView works?
Yep
For me, it sends the changes normally, I get all the changes indices
I have that override too but gomma check again.
didn't check length tho
I am using an older version of unreal to be fair .... 5.2.1 XD
I don't use PostReplicatedAdd at all since the structs are slots themselves, only if adding more slots
I think your meant to override them all?
Probably but I don't implement the others at all
for me they are not overrides just normal functions, probably caught by the Unreal's reflection system?
Overriding one or the other wouldn't change how the others work tho. In my case it always has a length of 0 on the changed indicies so I can't iterate over the changes.
In PostAdd, it's fine
Yea got it, going to work now but i also done postAdd from memory and have OnItemAdded delegate.
Thing is sverything works fine when comp is owned by player.
Fod both server and client.
But moment comp is dumped on a non owned actor, it doesnt replicate. (I just check with key press the fast array value)
Problem is likely to do with subobject replication in your case if you're using objects for your inventory
I am, maybe need to do NewObject instead AddDefaultGetRef, no other idea at this point.
when following this article about new chaos physics sync, is Iris a requirement?
Also, does Iris cause any problems with the fact it's being enabled instead of default replication?
https://dev.epicgames.com/community/learning/tutorials/MoBq/unreal-engine-networked-physics-pawn-tutorial
iris should work with the original replication system without changes iirc. except for maybe sub objects
Hi, after reading all this there is a part that i still dont understand, they say that for a directional move ability i should use the FCharacterNetworkMoveData instead of a separate RPC, but why cant i just put the data i need on FSavedMove_Character ?
I believe you have to do both
Network move data is what's sent over the network while SavedMove is what gets replayed
And stored locally
But the Network move data also use the saved move, no ?
Yeah but there's data only the client might need iirc
To fix the jitter issue on the client, I deleted everything, disabled collisions, and reset the character movement. It still hasn't been fixed.
Hey, so I wanna play a sound for myself immediately and also play the sound for everyone else except myself. I tried this set up and multiple other solutions but audio just does not play or plays for everyone including the player who emits the sound. It's weird since the print shows in console that indeed every actor except the one I'm playing the sound from prints it out. Any ideas on how to approach this?
OMG I was just being dumb haha. unfocused window doesn't play a sound
just tested with a buddy and it works perfectly fine
Hi all,
I'm building a multiplayer UE 5.7 game with dedicated servers (headless Linux, deployed to AccelByte AMS). I'm running into issues where marketplace plugins with visual/UI dependencies prevent maps from cooking for the Server target. Looking for insight on how others handle separating client UI dependencies from server builds?.
The problem:
Several plugins in my project (DungeonArchitect and NarrativeTales) have TargetAllowList set to exclude the Server target (e.g., UI/widget plugins that don't make sense on a headless server). This is fine in isolation, but my game maps reference these plugins transitively through Blueprint dependency chains:
Map → GameMode Blueprint → PlayerController Blueprint → UI Widget Classes → excluded plugin → cook fails
With -IgnoreCookErrors, the build succeeds but silently skips the maps — the server ends up with only Entry.umap.
Similarly, I have a procedural level generation plugin (DungeonArchitect) whose runtime module loads textures/materials in CDO constructors. On a headless server with no renderer, these assets aren't cooked, causing SIGSEGV crashes on startup before any map loads.
What I've tried:
- Excluding problematic plugins from the Server target via TargetAllowList — but then maps referencing those plugin types can't cook
- Patching plugin CDO constructors with !IsRunningDedicatedServer() guards around visual asset loading — works but not scalable, and plugin updates overwrite the changes
- Using the C++ base class instead of a Blueprint for the server GameMode's PlayerController — avoids the Blueprint's hard asset references to UI widgets
- Removing GlobalDefaultGameMode from DefaultEngine.ini so the cook doesn't pull in the client GameMode's dependency chain
Questions:
- What's the standard approach for separating client UI dependencies from server builds? Do most studios maintain separate server-specific Blueprints (GameMode, PlayerController) that avoid referencing UI assets?
- For plugins that load visual assets in CDO constructors (ConstructorHelpers, StaticLoadObject for textures/materials) — is there a way to prevent those CDOs from initializing on a dedicated server without modifying plugin source?
- Is there a recommended build configuration or cook setting that handles this more gracefully than -IgnoreCookErrors silently skipping maps?
Any insight from those running headless dedicated servers with marketplace plugins appreciated.
Thats not gonna play the sound immedieately though.
Unless the caller r the listen server.
If client execute that function it will wait for the mc call from the server.
I call the sound to be played locally for the player who played it first
then I hit up the server and from there all the clients
using the fake network ping thingy in editor confirms that
Right i missed play at sound location.
Just aware that ppl will get different value on that random node.
If you qant everyone to play at the same value, you have to send the result to the rpc.
why are you playing sound and spawning sound, why not do the same thing for both
so the sound is not delayed for the person making it
I want immediate feedback from walking/shooting your gun
but why spawn vs play
I heard you should spawn a sound for it to replicate
its not replicating, the multicast is running on all machines but owning client
there's nothing to replicate
just play it
are there any benefits from doing that?
probably cheaper who knows. I'd just keep it consistent, whatever your sound approach is
probably a good idea
Then you can set up the sound playing bit once and just literally have both paths call it
actually no I want to spawn the sound to attach it to the player so it moves with em
then do that on both
so you don't have the problem of leaving sounds behind you like Vintage Story has
wdym? I need to use spawn sound attached for it to work or just spawn a sound and attach it manually
Hi
I am starting a blueprint game project on 5.7.4
I would like to do an online multiplayer P2P (without having players to connect with their epic account, so anonymous device ID if i remember well)
And probably will use EOS.
I've heard about the EIK plugin that has a free version on Github, HOWEVER it's not up to date and seems outdated.
Is there alternatives ? I've heard also about a Online Subsystem EOS plugin Or should I go to an older version for my project ?
you could just use steam online subsystem unless you're not planning to do it on steam only
but u need a steam account to play online those games, i don't want to force players to have to connect to their accounts
you could also use epic online services
yes that's what I want to do EOS, but I think I need a plugin to do that right ?
yea I never used it though. just starting to dabble with multiplayer stuff
On a coop game should i use ClientAuthoritativePosition ? Or this can turn out to be a bad idea ?
It just means that a nefarious player can freely teleport at will. How detrimental and how much they can grief with that sort of depends
I was just thinking about it, games like letal company does not care about hackers i think and even GTA open servers have a lot of hackers too, so why not just give the player the best experience on a private lobby, but i also dont really know the consequences of giving Client so much control
it can avoid needing to correctly predict movement
it's not a bad idea for co-op games
the consequences could be they can spoof their real position
To fix the jitter issue on the client, I deleted everything, disabled collisions, and reset the character movement. It still hasn't been fixed. can someone help
@sinful tree @lusty palm not sure was the hiccup last time on my side but Fast Array work just fine regardless of ownership.
I think I was watching the wrong inventory on my side, I had two inventory, one for the backpack and general inventory.
I put everything into one array for easier handling, separated by an enum InventoryPart which has hotbar, backpack etc.
I'm having some issues with replicating an Projectile actor...
For one, even if set to Replicates the actor simply won't appear on other Clients when spawned.
Additionally, and this is the weirder one, if the Server client spawns the projectile, it runs a Begin Play test print with both the correct Pawn as Instigator, and the other clients' Pawns.
But if a Client tries to spawn one, then the debug BeginPlay spawn only prints a single Instigator, which is also the Server client's pawn
Eh which part in specific?
anything related to the projectile
The parent class that gets spawned, something on the blueprint?
everything related to the projectile, it's impossible to see what's wrong without seeing anything.
Okay let's see how I can fit so many lines of test
AProjectileBase::AProjectileBase()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
bReplicates = true;
// After creating our Sphere collision, set it as the Root component for the actor.
SphereCollision = CreateDefaultSubobject<USphereComponent>(FName("SphereCollision"));
RootComponent = SphereCollision;
// Sets our Collision to the correct profile.
SphereCollision->SetCollisionProfileName(FName("Projectile"), false);
SphereCollision->OnComponentBeginOverlap.AddDynamic(this, &AProjectileBase::OnOverlapBegin);
SphereCollision->OnComponentEndOverlap.AddDynamic(this, &AProjectileBase::OnOverlapEnd);
SphereCollision->OnComponentHit.AddDynamic(this, &AProjectileBase::OnHit);
// Projectile Movement Component settings
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>("ProjectileMovementComponent");
ProjectileMovementComponent->UpdatedComponent = SphereCollision;
ProjectileMovementComponent->Velocity = FVector(1, 0, 0);
ProjectileMovementComponent->bRotationFollowsVelocity = true;
InitialLifeSpan = 5.0f;
}
Constructor doesn't seem like anything's off...
void AProjectileBase::PostActorCreated()
{
AActor* ProjectileInstigator = GetInstigator();
InstigatorASC = UDulceAbilitySystemGlobals::GetAbilitySystemComponentFromActor(ProjectileInstigator, true);
Super::PostActorCreated();
}
Then there's this one step that might be it, where it tries to fetch the ASC from its instigator.
On the blueprint class side it's all pretty much blank save for debug prints.
but you are saying the bullet doesn't spawn at all?
The bullet visually spawns on the client that calls it, yeah. Not visible from other clients.
Yeah I mean you are spawning it locally.
why would it appear on other people machine?
Any function you call on your computer will only be run on your computer as client.
Because I was sure I made the controller send the event to theserver
Networking tip. The only way for client to communicate with server is through server RPC.
Then make the server run it everywhere
ok, show that.
multicast?
that's the wrong way of spawning replicated actor.
you will end up with extra copies.
Simply marking an actor as replicated and spawning it as server will spawn the actor on clients.
ofc this doesn't address predicting the projectile but that's not the focusnow.
Ah, I thought the method was supposed to stack the different events...
that's not what your code is doing btw, it's running on Owning Client. Means only run on the player that owns the object where the func is called.
Yeah, to spawn a replicated actor to every machine, you simply mark the actor as replicated.
Then spawn by the server.
that's it, all players will eventually get a copy.
However I still have this issue...
Not sure why this happens when Client0 spawns its bullet
unsure what the issue is
Okay new example using Instigator instead
If Client0/Server does the bullet spawn it seems to also spawn another one with the othe client as instigator
But in the actor list, only a single bullet is spawned correctly so, maybe it just runs twice? Doesn't explain the instigator part tho
@dark parcel I wanna take the chance to check on two things though
For one, what's a better scenario for Multicast? Because I get now that running on owning client is better for something like cosmetic client only effects
Second, projectile prediction will be something that I need to deal with later, so is there some rule of thumb I can follow to make prediction less of a headache down the line while I'm setting up systems?
Anything stateful or need to be in sync shouldn't be using Multicast.
multicast is for event based.
You probably can benefit from Stepehn FPS multiplayer tutorial.
goes a lot about prediction, lag compensation, network clock, etc.
for the basic you just need to know how players communicate with each other.
simply try to understand RPC and OnRep first.
Alright, thanks for the tips
I also feel I should probably use a different system for my projectiles though...
No bullet drop or physics, the Projectile move comp might be overkill net wise
Shouldn't multicast be used for spawning a bullet then? or what's the difference I'm missing
depends on how you want to tackle the projectile.
Well I did try to use Multi instead with no result, gonna have to read more on it
yeah read more on RPC.
Mutlicast shoudl only be called by Server as replication work from server to client, not the other way around.
Ahhh that's the bit I missed, thanks
I also noticed that the player's control rotation is not replicating for clients
But only on one axis...
Pitch is unreplicated, huh
Use GetBaseAimRotation
Would that help with the AimOffset animation not playing too?
You use baseAimRotation to drive your aim offset. As for your animation I wouldnt have a clue why its not playing other than you telling me its not playing.
Hmmm
I think it has to do a bit with how it's set up, probably the same thing that makes the camera not rotate with input
Since the bullets on non server clients spawn without pitch rotation, and I know the camera is the issue since bullets spawn with a position relative to camera
Hi, i am lost in a replication issue, where i need to mix atomic and delta replication.
In an ideal world i would have:
A FInventory struct derived from FFastArraySerialize.
The FFastArraySerializerItem would be my FInventorySlot. These slots have: index, FItemStack, and FStackId.
My FItemStack, would contain an ItemType, Count, and another FFastArraySerialize derived structs which items contains Instanced Structs of type FItemFragments (for dynamic item data).
Inventory slots would need to replicate atomically when the FStackId changes cause it means the whole stack was changed and needs to be sent from scratch.
Now, i am pretty sure trying to implement a chain of custom NetDeltaSerializers would be hell. But is there any reference for doing something like this? Is this even possible?
If i have to use iris i will, but i would still need some reference or guide to get started, plus some advice on how to handle the serialization of this chain of structs
@twin vessel Is this even possible? no
NetDeltaSerialize works on base-level UObject members only, not nested structs
Iris wouldn't change this btw, FastArraySerializers can't be nested
iris fast arrays suck anyway tbh, they can only distinguish between 32 individual items for dirtying. If you had say 64 items, you'd always be sending at least two of them even if only one changes.
Worth mentioning that instanced structs are not delta serialized either - they are sent as full blobs all the time
Still, when they are embedded deep in arrays, not sure how well that holds
That sucks... i hoped that by storing the INetDeltaBaseState of the inner fast array in the INetDeltaBaseState of the wrapping struct that delta serializes, then i could let the chain go.
Still would only work if the properties of the FastSerializerItem are serialized like normal properties, which are probably not...
To fix the jitter issue on the client, I deleted everything, disabled collisions, and reset the character movement. It still hasn't been fixed. can someone help
Hey guys, is there a way to call a client RPC from a server RPC only on the client that called the server RPC
That's what a client RPC does. It calls the RPC on the client that has ownership of the actor
Considering you can only call server rpcs on things that you own (PlayerController, PlayerState, Pawn), just get a reference to that and call the client rpc
Client rpc works on OWNING client.
Exactly, it calls the RPC on the client who has ownership of the actor. I don't want that, I need to somehow notify the client that the predicted inventory action was rejected, the client does not necessarily own the actor, how would I go about that?
The client doesn't own their inventory?
If they don't own something - don't try to do prediction
The only way a server RPC happens is through something the client owns. So, how are they doing the server RPC with this action if they don't own it?
it's a chest in a world
I need prediction, with 100 ping, it has noticable latency
server rpc using the player's inventory that queries the chest inventory
You don't need prediction. Many many many games get by just fine without predicting this.
This is why you can play games at certain pings and the items don't load in the chests contents
The visuals for the chest might play, sure.
Then you need to client rpc back this same way and tell them the prediction was wrong.
Just tested it for arc raiders, literally pulled out my ethernet cable, they do client prediction
Dang - didn't know arc raiders was many many many games
Also - that doesn't say they do client prediction
problem is client doesn't own the actor
That's why I said to do a client rpc back through the same way...
You did a server rpc throught the player inventory
Do a client rpc through it as well
Just yesterday i see people attempting to predict knock back and damage
Still unsucesfull because theres always a take away.
I kinda predict managing inventory like swapping items.
wdym
But that was ez because index r not replicated and managed locally.
Server only care if the item exist in their end when it come to usage.
They may just front load the items and then you just tell the server that you looted chest X. No prediction necessary.
I'm not sure I understand what you mean?
wdym by front load
When you get close to a chest, they async load the items in the chest so when you get there, the items are there to be looted. Even if you never open it.
Then you disable your internet - the items are still there
You loot it
You get the items
Reconnect, you tell the server you looted chest X
Server says 👍
Absolutely zero prediction in that entire process
(Not saying this is what they do mind you)
Yeah, but there are slots in the chest, doesn't necessarily mean I looted the whole chest
Also if I were to replicate when I get close to the chest, it would make cheaters be able to see contents before opening
So what if server says you cannot move it here, there is an item there (if you have desync)?
Then the server fixes the state?
Ignoring the prediction debate - here are your choices:
- Do a client rpc to rollback everything that you mispredicted
- Dig through the rpc system to see how you can circumvent its restrictions and send w/e you want to w/e connected client
So it's literally client prediction lol, they still have to rollack
....
That is not what prediction is
Just because something can get out of sync doesn't mean prediction was involved.
It could also literally just be client authoritative over some actions.
Wait, so you want the client to just set the item somewhere for them, and how exactly will the server know it is there? Without messaging the server
no no no no
It could be a bunch of different things... it could be a sort of lockstep series of transactions that is read back or replayed for integrity later or just entirely trusting the client etc... it's pretty arbitrary
You'd be quite shocked at how many pvp games have client authority over things.
What?
When did I say to not message the server
My assertion is that just because you unplugged your ethernet cable, doesn't 100% mean that arc raiders does client prediction when looting a chest
I'm new to networking and replication so I can't quite wrap my head around this idea, wouldn't that mean that the client is authoritative over the slots
As I said before, you shouldn't really predict this and just leave it to the server, but if you still wanted to, then your choices are the ones I outlined before
they might just run some simple sanity checks to say that you were remotely nearby later
they might not
prediction to me implies it's also doing it on the other machine and that's hard to tell here I think
Currently, I make the client relevant to the chest only if they open it, not if they are nearby
wdym the other machine
What's the intended way to replicate the player controller's pitch rotation?
Hi everyone, is there anyone who has implemented a trading system between two players?
That's a very vague term, trading what, inventory or some type of currency, which type of inventory etc
Imagine an MMO game with an economy system and two players.
You have an axe and you want to sell it to another real player. For this, you open a trade. In the trade window, you can either exchange items—for example, you put an axe and the other player puts a sword.
Or you place the axe, and the other player offers gold (currency), and the trade is completed this way.
It shouldn't be too hard to make if you've got an inventory system working
I would just replicate the "trade inventory" to both players so they see what is offered and then on accepting, they just get the items in their inventory or whatever
I purchased the inventory system, but it feels a bit complex, so I wanted to ask.
Should I create a new slot system, or should I use the existing slots in the current inventory system?
No one would be able to answer that question for you. There are dozens of inventory systems out there, and if it's a paid one, it's very unlikely you'll find someone else in this server who has purchased it who could potentially start to answer that question for you.
The "Slots" don't really matter as much as the logic for handling how the trade starts, progresses and is completed.
I mean if you can understand how the current slot system works I see no issue in using it
okey thx
Whould this method for replicating pitch on the character work properly as I hope, or am I missing something?
I thought Pitch is already replicated, through the camera rotation?
@cinder quartz Use the Pawn function GetBaseAimRotation if you want replicated Pitch.
So GetAimBase instead of controller... What's the core difference?
Just wanna understand all here
GetBaseAimRotation exposes the underlying replicated RemoteViewPitch variable to Blueprint.
Ahhh, got it. And it's not replicated by default, and Yaw already is replicated by virtue of the CMC handling it already
Which is odd tbh, why does specifically the camera not get its pitch updated? Some legacy thing under the hood?
Pitch is replicated by default, it is replicated on the Pawn via the RemoteViewPitch variable as I just said.
/** Replicated so we can see where remote clients are looking. */
UPROPERTY(replicated)
uint8 RemoteViewPitch;
GetBaseAimRotation passes this value out.
So remove the pitch variable and sample from GetAimBase
🤦♂️
What did I say wrong now?
Its literally this simple mate.
...That's literally what I just said
Then I misinterpretted what you meant.
You can delete all the other stuff in your blueprint you mentioned above.
And replace it with that
Other ppls controllers don't exist on your machine
GetBaseAim exposes a replicated pitch in Pawn that comes from ControlRotation serverside. Some old relic from the "It's an FPS engine guys" days.
Pretty low precision though so don't rely on it for "where the bullets go", just use it for cosmetics
Hold on now, what?
What am I supposed to use for the actual "where the bullets go" then?
@dark edge What would be better? A replicated variable? Some different function?
Either replicate each players pitch and yaw manually or just suck it up and use the slightly lower precision since a proxy firing on another machine isn't really that important anyway unless you are making some high level shooter, we're talking very minor imprecision here
you're already going to be offset on a proxy client anyway by the time it takes to go from Client -> Server -> Other Clients
So just make the client send their controller rotation to server to update the pitch and that should work ok?
Just use the existing replicated rotations precision, run some tests and debug lines to see their discrepancy and see if you even notice or mind it
There is a higher cost to sending full precision, hence the reason they are using a quantized value in the first place
Hm it's pretty hard to gauge what's best for my use case. The C++ function works so I'm at least in a better spot, but based on how big the imprecision is I gotta do something
The last debug test I ran had some discrepancies mainly in that rotators were applied the other way around. Like instead of 10 degrees if was -350
Other than that no visible meaningful issues so I didn't think too hard on it
I don't know the full math to give you a correct answer but it's "good nuff" for most cases, my suggestion is to just test yourself on high ping locally
Okay, gonna run a test tomorrow at 100 ping increments
Hi, is there a way to replicate FFloat16 s ?
USTRUCT()
struct FDS_NetworkedHealthPair
{
GENERATED_BODY()
UPROPERTY()
FFloat16 Value = 0u;
UPROPERTY()
FFloat16 MaxValue = 0u;
};
It seems like UPROPERTY does not support FFloat16. Because I have an array of floating points I wish to network, I was thinking that I could half the amount of network traffic.
There's not, but you can create a NetSerialize for your struct and do it that way
would make sense for a struct that small anyway, the UPROPERTY header would be as large as the types
I also tried to do TArray<~~TKeyValuePair~~ TPair<>>, but the key value pair also is not supported by UPROPERTY. Haven't really done NetSerialize before, just trying to figure out what's possible. 😅
UPROP only supports what is normally visible to reflection - minus TSet/TMap basically
So more often than not you need to wrap your types in USTRUCT instead of using templates etc.
I guess I could manually pack it inside uint32 and just do reinterpret_cast ? Sounds a little... "ugly".
Well bit packing is certainly an option
I will think about it. Thanks!
But for very small POD types, implementing NetSerialize can shave tiny bits off your packet sizes (we are talking tiny though)
Each UPROP has a uint16 (I think..?) index to address it per-level (and that index gets wider, depending on how deeply nested the UPROP is) - the minimum net size of FDS_NetworkedHealthPair would be 32 bits, so you may as well pack both values to 32 bits and get atomic serialization anyway
does non replicated property in a struct still increase the size of the data when being send over the network?
shouldn't
How can I create a direct connection between 2 players? socket or something?
Basically I wanna bypass server client model
Well, you just have to write your own networking stack entirely or reach for a 3rd party library
Does it only replicate pitch anyway?
Are you trying to just send a basic thing between two players or make a peer to peer game?
I wanna continuously send data from everyone to everyone. Basically yeah real P2P
There will still be a listen server game tho, I just need to bypass server for latency sensitive data
Normally Steam or EOS provides that, right? I'm currently using RedpointEOS.
Can't I just reach for EOS to handle that?
btw I don't care about RPCs or UE replication. I just need raw data via UDP
FYI: I tried going with default listen server model. Too much latency on client -> client data
Can't speak on EOS, but you can use Steam, yeah. However, that will tie you directly to only being able to use steam for multiplayer. So if you want to release literally anywhere else, you'd be boned.
What are you making? Because I've done many 4-player co-op games with UE's default networking and it has been just fine.
- there's no guarantee that P2P will be any faster. Maybe in some scenarios but not all.
TL;DR I have a lot of units just like a RTS and I'm using deterministic lockstep just like a RTS, but I also have a relatively fast gameplay so it's extremely sensitive to latency. Also 6 players
Oh, RTS? Yeah - client-server model sucks for that generally.
I mean in average not going trough host should be always faster than going trough host. Data is exremely small, so I only care about latency
Nope, I just have a lot of units like a RTS. not building a RTS, but yeah potato potayto same problem
Well, yeah, those are your options though. Write it yourself or reach for a 3rd party library.
UE is client-server through and through
@sinful tree Havent forgotten you, just takes more time to rewrite stuff, its 80-90% working now just the last stuff, but ill figure that out too thanks again for the help
(if you forgot who i am: #multiplayer message )
I'd want to somehow ensure that the projectile initial conditions are as synced as possible, if I was doing a long range shooter. If it's close range it's no biggie
So using a quantized pitch variable, replicated between client and server would be good?
Since in the average fps the actor Yaw is already used for the camera and replicated very reliably, and most games use the camera as origin with offset for the most part anyhow
depends on your definition of good
Well, good in this case is that the player sends the bullet as close to where their reticle is aiming as possible (plus third person aim offset behaving loosely correct)
I'd pass a direction vector over with each Fire call
But see what the built in replicated pitch gets you, might be good enough for your usage
The thing with this is that my bullet origin is already directly based on the player camera with an offset... So I felt as if a replicated camera rotation value would be cleaner
i mean your control rotation should be roughly in sync, but your client should send the rotation
and basically, like fortnite does, cleint sends all the data
server just does anti-cheat verifications
(max yaw angle, simple line test to detect if the show would ever hit, fire rate of guns, that kinda stuff)
That's kinda my original method huh
This just done in C++ so I can have a cleaner function
well that replicated rotation isn't 100% the same
how same is same enough totally depends on the angular resolution you need
Have you tested it yet? This whole convo is redundant if you haven't tested.
Well I did, and it worked. I mostly only tried to work it out because the method was pointed out as flawed
However the singular issue I noticed is that the replicated value gets potentually turned the other way around, ie instead of 40.0 pitch I get -320
idk I just replicate directional vectors not angles
Well I guess I can turn the player view into directional vector and make the server camera imitate that
Just seems like a waste since the only thing I really need to replicate is the pitch
Why do you need a camera on the server?
I'd use the already replicated pitch to drive the cosmetic animation stuff
and when projectiles are fired use either a calculated direction vector (your approach right now), or later pass direction vectors around if that's not precise enough
Ohh yeah, that's right!
I was thinking too hard on that one I missed that
I mostly so focused on this since I was using a replicated WeaponActor parented to the camera
Hey all, what would be the best method of multiplayer connections via blueprint? Is PlayFab worth it or is there another more suggested version?
thats pretty broad
if your just starting out, don't even think Dedicated Servers
use steam, and get the advanced sessions plugin
if your bp only.
or use Redpoint EOS free version for epic stuff
Is this still available for the latest 5.7? I can only find UE4 on a quick google.
I think I've got it, cheers.
Anyone able to help with this? I can create a session, but can't join a session. 5.7.4
I get 0 found sessions in the 2nd image. Using the latest Advanced Sessions https://vreue4.com/advanced-sessions-binaries
And been following this tutorial:
https://unreal-chronicle.hanayou.dev/docs/miscellaneous/advanced-sessions-setup
Some more info... it works via invite, just not through finding session
if you dont have a proper appid, i dont think find sessions works
ie if your using the test one
It does work - its just pretty hit or miss in my experience.
IIRC, I had to set my search size to like 2000 for the testing one.
While actual game AppID was instant of course.
I changed it to give me a list instead of instant. I think I was just being impatient, I think it was just searching for a game. Thanks everyone
you can also check the search result array on tick before the find sessions complete delegate is fired
if you want servers to show up 1 by 1 as they are found instead of all at once when its done
If you are using the default app id 480, then you are sharing the sessions with other testers with the same app id.
You will need to create a session with some unique indentifier and filter search with that unique indentifier if you dont want to grab someone else game project session by accident.
hey! I am trying to get access to a variable in the player controller from the widget. so in the widget i used the "getOwningPlayer" node but i noticed only the server returns the correct result while the clients does not. please any idea ?
for a start, widget is not replicated.
second client only knows their own controller and no one else.
what is the variable you are trying to access? because a client will never know any one else controller but their own.
alright, actually they is a character that is spawn from player controller(not possesed) and I keep the ref in a variable. So from my widget i wanted to get access to that Character Ref.
you can have replicated variable of type Array of Character that lives inside a replicated actor.
don't know how your game is structure but one way is to make a manager actor. basically a Replicated actor that is spawned by the server and gets replicated to client.
The manager can contain the replicated array. Everyone can just read from it.
E.g Widget -> Get Manager Actor -> Get Character Array -> Display w.e.
actually scrap that, just do it in Game State.
so what i am trying to achieve is, each time a new player join the lobby his player controller spawn a character which is not yet posses and will be posses later on. So I want to be able to customize the spawned character from a widget .
k, all you need to do to get the character ref is laid above.
widget should only just read though.
and call functions.
Okay, let me try
Hello deva
if anyone has experience with multiplayer server deployment. I had a query
do I need a new instance of dedicated server for every new session ?
or is there a way to have host only one server and manage multiple game session in that.
you have one server instance per game session
depends on what you mean by session and server
1 physical server can run many unreal server instances
ofc by its cpu and ram
by server i mean Dedicated server exe file (not virtual Machines)
and by session Lets say game of 5v5 match
Also depends if you mean concurrently or sequentially.
A single server can run 5 matches if they don't happen at the same time.
yes at same time
UE is designed to really just run 1 server per instance.
let me rephrase it
can i run 1 server.exe and handle 3 5v5 matchs
No.
thats costly
Correct.
Multiplayer FPS game servers are expensive.
If you can't afford them, get your players to host them on their own machines.
Like cod did back in the day.
Basically if you want to host your own servers over a long time, you need a live service game. Constant income from a subscription or selling skins, etc.
one physical server can host many exes though]
just change the port
we run 12 instances per phyiscal server
Probably can't do 12 5v5 servers, though? Depends on server I guess.
and the server ofc
dedi servers run single thread
and memory is quite low
for most games
Since the plugin "Smooth Sync" replaces the default CMC movement handling and set the Character Transform directly, we lost the "Hit Events", because hits only happens if there's a sweep... Have you guys ever had this issue before? Using Smooth Sync plugin and tries to bind OnActorHit/OnComponentHit
Hey, question for troubleshooting
If I have a APawn variable in a spawned weapon actor, and it will remain unchanged for as long as the actor exists, should it be replicated...?
I am having some issues with online tests as the Variable seems to not work correctly. For context, this is how I'm spawning it.
Yes. Client's value will be null. Server needs to replicate the value.
That's what I needed to know- So if the variable is used after spawn by non server always replicate it
Depends on how that variable gets its value but sure
why do you have Owner and Owner Pawn?
Just setting owner to the pawn would be enough, from there you could get to the other classes you care about I'm pretty certain
That's a funny story... I tried to use the depregated Instigator instead of GetInstigator()
So this was a leftover
How big of a packet is "oh shit" territory?
That was me changing 5 floats on 10 entries every frame for 5 seconds just as a bit of a smoke test.
those aren't individual packets as much as multiple that get read in a row... that bunch is a bit over like 2 or so considering the default size in the editor is like 1000
what startup args was this using?
-NetTrace=1 -tracehost=localhost -trace=net
Not really seeing anything different, what are you trying to see here?
Just standard replication, with a fastarray serializer
okay I have no clue if the old fastarray actually traces anything
2500 bits for 50 floats + overhead + bookkeeping seems not insane
also like this is kind of a case where delta'ing can't really even happen when there's like not a baseline afaik
my assumption being that if the ack for the packet isn't even there yet before you send new info there isn't a baseline yet
I'm not 100% clear on this though and it's mostly an educated guess based on looking at profiling and reading a lot of iris
so I am very much guessing
how crazy is custom serialization, is it a pain in the ass?
it depends on what you are doing
honestly yes is it a pain in the ass for iris
less so for the old way
old way is easy pzy
I really oughtta diagram this thing out.
The hot loop device data lives in contiguous arrays addressable by handle. There is no consumer facing API for domain data, it's all through devices.
The state that must be synced is the set of devices and their corresponding handles, and the set of connections, which are tuples of (devicehandle, port index)
The public facing API is only CRUD via handle for devices, and add/remove connections.
Right now my approach is to have each subsystem create a replicator actor which contains a fastarray of (handle, data) and deriving local state from that on clients.
I'm wondering if it'd be worth looking into just netserializing the handle-addressable container and doing away with the hassle of using a flat array as an intermediary.
is there a way to get average network latency for a client?
yes APlayerState::GetPingInMilliseconds etc
for local players they will track a small average ping
see APlayerState::RecalculateAvgPing
can you get that within an RPC? i'm doing some latency compensation
well
the rpc would need some extra context for that
the average ping could be entirely distinct from the time the rpc took to show up
for sure, but it's a component of it
it's not a component of it unless it's part of the same packet
it might be close on average which could be good enough
one thing that might help is using an accurate server timer setup
but just knowing what the average ping is for compensation will help too
i do currently use a delta of GetServerWorldTimeSeconds();
I don't know what the actual plan is here for compensation etc
yeah this is the same thing but basically ran from its own rpc which is honestly useful enough to be worth another extra rpc
you could maybe piggyback the value into other commonly sent rpcs
are you saying this incurs the entire latency again to get the value?
the exact math for the averaging can be tweaked to consider what works best for your project as well... you might want something that changes faster etc
no
it uses an rpc to update it
ClientUpdateWorldTime and ServerRequestWorldTime
by not synced with the call?
the idea is once you have some example deltas you average them and then can get the local delta anywher, much like what you are doing now
it just uses rpcs to get new data
not for every time you ask it to get a time
right
i wouldn't think the clock would drift much though
probably be fine updating it every minute
yeah ideally it stays consistent but if it must be perfect you might be better off putting a timestamp in the actual rpc itself
a timestamp right in the rpc is how the character movement component works for example
this does increase the size of the rpc a fair bit but it's not enough to be an issue generally (a couple dozen extra bits won't hurt much)
i'm committing the sin of client authoritative movement in a space sim, and i'm basically trying to compensate for how far "ahead" the client can get with its reported position value when the server adjusts locally
you are in a safe space lol... I am very much okay with client auth
it's a wise decision for many many games
it works pretty well, just trying to figure out if i can improve it by taking a bit of the randomness out of it
I guess my question here would be if you need to compensate for this or if this second thing could also be client auth (might be complicated)
for example projectiles in unreal tournament are locally predicted partially (sometimes only visually)
if two ships start accelerating in the same direction with the same thrust, the client would fall behind on the server if you take the position verbatim.
instead, i calculate the delta in server time from when the RPC was created by the client, and when it is processed by the server, and extrapolate its position + velocity * delta.
but then this makes the client always be ahead
so i add a compensation constant (for now) that brings some of that back
if the compensation works well here then just tie it to the ping I guess (rtt delta, whatever)
make sure to consider if ping includes frametime as well
it works pretty well right now but starts going a little haywire at ultrahigh velocities
which i plan to solve in a separate way
well, you might want to cap it a bit
I'm not sure what the math looks like here
but if it's really simple you could consider doing fixed ticking and rollback stuff but it will be painful to do that in unreal without going all-in
or just separate resim per ship
to catch up and lerp the visual result a bit
i'm doing some crazy stuff with the physics system so i kind of need to home bake all my networking
how do you replicate their position to sim proxies?
i basically use an impulse to nudge ships towards their correct position