#multiplayer
1 messages · Page 232 of 1
PlayerNumbers is 0 -> Left Click -> RPC to Server -> PlayerNumbers + 1 -> RPC to Client -> PlayerNumbers is 1
Thats exactly what its doing
No, its updating the value from the client, not the server.
Huh?
Did you want PlayerNumbers to increment each time you Left Clicked?
Yes, the increment should happen on the server only.
Let me show you some more images.
It makes it more clear.
My spawn event, which should increment the number on the server, then after thats done i get the number in the Player number on server variable. (i get them from the retreive players function.)
First image
Just spawned on server.
Increments correct.
Spawned second set from client (right side).
Number increments again from 0 (server prints run on server string so i asume server is updating)
Ok
Right
So because you have all of this functionality in the Pawn
And each Player gets their own Pawn
They each get their own version of this functionality.
So when a second Pawn comes into the picture
The PlayerNumbers variable for the Pawn on Client 1, is a different PlayerNumbers variable to the one on the Pawn on Client 2
Does that make sense?
Because PlayerNumbers is "local" to the Pawn, as you put it earlier
Yes, thats what im seeying
Do you understand why thats a problem?
But i expect when using run on server, that it only does it for host pawn, and send to client pawn.
Well then i dont understand đ
So host and client, each a pawn (in my mind) is actually 2 pawns for host, 2 pawns for client?
Each Player will have 2 Pawns in their World, since they need one for themselves and another for the other Player.
Therefore
The Host (server) has 2 Pawns
And the connected Client has 2 Pawns
So therefore, 2 versions of that code running
Which is why you see that result
Since you can only send RPCs to the Actor
There must be the same version of that Actor on the connection you are sending the RPC
Otherwise the RPC fails
Since its going no where
I understand up until this point.
(Since you can only send RPCs to the Actor
There must be the same version of that Actor on the connection you are sending the RPC)
Yes
If you want to count the number of Players
And you want that count to be singular for everyone
That count must exist only once
So you need to store it somewhere that exists only once
Since there can be multiple Pawns
That is not a smart choice
This type of thing is better handled by the GameState
Since the GameState is a singular Actor that exists once
That is good to know.
I tried this in gamestate earlyer which did not work (probably my error), which made me switch to using the cameractor pwan for this.
Hopefully this doesnt further confuse you, but this image should help you to understand.
Well still there is one thing i dont understand.
At least the picture is not clear.
Let me grab paint and draw a image.
Which one is true?
1 or 2
Technically the second one.
But its better to think of it from the first lol
In multiplayer there a number of things that provide context to why thats the case.
Network Role is one.
ROLE_Authority is given to an Actor that is directly spawned by that context, if it wasnt spawned due to replication.
This is typically true of all Actors on the Server.
With a few exceptions
When a Pawn is created
For the Local Player
This is the picture of what i expect.
That Pawn will have the Network Role of ROLE_AutonomousProxy.
ROLE_AutonomousProxy indicates that Actor is locally controlled by that Player.
So this means that the pawn for player 2 is still locally controlled on client game?
Yes
This is more accurate
This shows that the RPCs are being called on the Actors themselves
The RPC is not being called in a "global" sense for the Server or for the Client
Mindblown
They are called in relation to the Actor that they exist on
Ok i will draw one more picture, then i think you can make me understand what to do next.
Using the some actor as a buffer to do the run on server locic on?
In my mind there needs to be a placeholder for the variable i want to increment.
I will try for a moment.
The PlayerCount variable would be on the GameState
You would also have the RetrievePlayerCount RPC on the GameState
The CheckPlayers RPC would need to be in the Pawn still, or the PlayerState, or PlayerController.
Since Server RPCs need to have whats called a NetOwningConnection.
Which is provided by the PlayerController
And anything owned by the PlayerController on the Client will inherit the NetOwningConnection.
Pawns and PlayerStates are by default owned by the PlayerController.
So the playercontroller acts as the tunneling pipeline
Its your connection to the Server
I have things setup in the player state.
But when i try to get the player state from the player controller, it always fails.
Hence i cant reach the player state to call the event from the client.
This picture is in the CameraActor Pawn
Be careful with that.
PlayerControllers dont exist in the same way Pawns do.
Using GetPlayerController like that can produce unexpected results.
Since you are in the Pawn, you should be using the GetController function
Oh, yeah the Pawn has access to the PlayerState as well
Its a property of the Pawn
No need to use the PlayerController.
Really lol
Still failing when i used that.
It only shows a succes message on the server for all 3 gamestates
Leads me to believe the gamestates only exist on server?
So what are you talking about the GameState for?
Sorry player state i mean
Can you SS the code you have right now?
Part 1: Inside player state
Part 2: Inside pawn
Part 3: in pawn
So use pawn left mouse click to increment number through player state, to have server return number back to client.
Why are you using the PlayerState, I thought I made it clear that the GameState needs to manage this?
The Pawn can have the CheckPlayers RPC that goes to the Server.
Which then increments the GameState::PlayerCount variable
Ok, i will try that, tomorrow with fresh eyes and mind.
Thanks for the help so far Matt, i learned more from you this past hour then many tutorials.
This works like a charm, so i should see the gamestate as the gameinstance of the server i guess.
The pawn is now using the rtc to update it in the gamestate, and the client receives the update.
One question left, in this scenario, is the pawn actually "asking" the server from the client, or from the pawn existing on the server?
Ok time for bed đ
No, the GameInstance is the GameInstance of the Server (there is literally an Object called GameInstance, which is a Singleton on every machine of the running UE process).
The Client Pawn is asking the Servers version of that Pawn
to customize a newly controlled pawn's visual (i.e. it's camera) would i just be able to add a spring arm/camera to it like any other pawn and it will work based on that ? currently just defualts to a fp view, but i also dont have any camera on this pawn currenlty
Hey, I have a problem that my network object (inventory item) getting removed after player character dies (even tho I loot the item, and change its outer).
- On client, local player kills another player, loot his item into his own inventory, but when died character de-spawn item marked as garbage collected.
- Same scenario on Server, everything works just fine.
- On client, If I drop the item, cause to spawn a object, then pickup item back (creates a new item), then it not garbage collected.
here I posted in forum as well, with more explanation + video: https://forums.unrealengine.com/t/network-object-inventory-item-removed-after-player-removed-even-tho-looted/2268750
My first time working Unreal Multiplayer, any idea would be appreciated.
Hey, I have been struggling with a replication and garbage collection issue. BACKGROUND: Iâm designing a inventory system. All items stored in inventory are UObject. (This because planning that some items will be able to store nested inventories. Thatâs why Items are not FStruct). Character->InventoryComponent->Inventories->Cells->Items. Th...
Can you show more specifically where you are removing the item from the old inventory, and adding it to a new one. And anything in between thatâs happening when you give it to whatever actor youâre spawning in the world.
Going to need more specifics, because a lot of stuff is left out
Sure,
From CellWidget's OnDrop:
//TODO: Bundle operation in one rpc
InventoryComponent->ServerRemoveItem(ItemDragOperation->FromCell, ItemDragOperation->Item);
InventoryComponent->ServerAddItem(Cell, ItemDragOperation->Item, DragTopLeftPosition.X,
DragTopLeftPosition.Y);
ServerRemoveItem called in InventoryComponent:
void UInventoryComponent::ServerRemoveItem_Implementation(URepCell* GridWrapper, UItem* Item)
{
GridWrapper->RemoveItem(Item);
UE_LOG(LogInventory, Display, TEXT("[SERVER] Removed item %s"), *GetNameSafe(Item));
}
and ServerAddItem:
void UInventoryComponent::ServerAddItem_Implementation(URepCell* Cell, UItem* Item, const int32 X, const int32 Y)
{
if (Cell->TryAddItem(Item, X, Y))
{
UE_LOG(LogInventory, Display, TEXT("[SERVER] Added item %s to at (%d, %d)"), *GetNameSafe(Item), X, Y);
}
}
So when client opens external inventory (i.e., a death body), it loads the replicated representation of the data, create widgets dynamically. Then when drag-drop Item, it simply apply ServerRemoveItem and ServerAddItem.
Structure of classes:
Character->InventoryComponent->Inventory->Cell->Item
God in discord all code formating looks nightmare
So your replicated object items are kept in replicated object slots?
Yes all chain from InventoryComponent to Item are replicated UOBjects
InventoryComponent is UComponent
Can you show me remove item and try add item in your cell
Or grid wrapper, youâre calling it two different things in the functions but I assume itâs the same thing lol
Sure:
Btw, Cell not directly contain the items, it uses FastArray of FItemPlacement. But I believe there should be no replication issue, because except this issue, I have no replication problem yet
Are you using the replicated subobject list, or the old way of object replication
Ah I'm not sure on that
Where are you constructing a UItem, something isnât making sense
You can replicate the structure, but the objects inside wonât replicate if they arenât net addressable and added to some form of subobject replication
yea I faced this problem first when implemented, but then I enable replication for UItems
Items created from a factory method,
I'm sorry to fill the all page with images, I guess I designed this system with so much classes and it seems hard to describe the high-level overview of it
No itâs fine itâs the only way I can read on mobile
Then i'm sorry twice đ
How are you replicating the UItem?
Or URepCell? What is a rep cell anyhow, the slot?
Yeah, but that doesnât replicate the object
and from inventory component I replicate subobjects
Youâre doing it the old way
Not specifically going to solve your issue, although I suspect it will because it looks like youâre removing the item and itâs becoming unreachable before youâve added it to something else. I bet if you run GC every frame currently youâll find the issue
God, I struggled to understand this old way replication, and cause tons of errors. I guess there is really value to come and ask people
The new way is as simple as adding the object to an actors replicated subobject list, and removing it when itâs destroyed.
Both client and server should maintain their own replicated subobject lists
Actually now I see that, it gives more control over the lifetime, which may also solve the problem
The best way to solve GC problems is to run GC every frame
I also thought something similar, but this garbage collection problem only happens whenever the death player (original author of the item) despawn
is there a console command for this?
Yeah, itâs gc. Something. I forget off the top of my head but if you type âeveryframeâ Iâm sure itâll come up
I mean I felt more like, even though I tried to set the owner of the Item it still keep belonging to the death player, or maybe owner is not replicatied properly which cause, whenever player removed, also bring the item with him
Thanks!, I will find
I saw you were talking about the outer but remember GC doesnât go that way.
All ârenameâ does is change the objects internal name and outer, but it wonât keep it alive
Something else needs to hold a pointer to it to keep it alive (or strong pointers but thatâs not really a good use case here)
I see, but then is there a way to change the ownership of the Item so I can transfer the ownership to another player?
Or do you think, problem is not related the owner but more like some dangling pointer somewhere
I mean changing the outer is fine, but you still need the new thing to keep it alive
Also try to use TObjectPtr for member variables instead of raw pointers. Itâs what UE wants now
Ah, I understand now, I even thought that when player removed it forces to remove the item with him together, but I guess I assumed wrong because GC only works when there are no reference anymore?
GC will run through and flag it as unreachable even if itâs still valid. Then actually free the memory on the next cycle. Thatâs why itâs important to use IsValid(object) in most cases because it checks reachability. Not just if the pointer is pointing to valid memory
Then, let me optimzie the code with TObjectPtr's and new way of replicating subobjects. Maybe it will fix the problem
At least it will open some fresh space in code
Thanks a lot for all suggestions!
Tried both but sadly not worked
Though, got a short video that shows when garbage collection triggered, what are the outters for the objects.
Note that, I have not set outters here, but when I set I seen that they are not replicated (i.e., if server set it to inventorycomponent, it will stay transient for client)
In a scenario where I have a lot of items (can vary from 10 to 100 and even further in rare cases) in a fast array inventory, would it be sane (and faster ?) to put my items in a tmap (ItemGuid / ItemInstance) once replicated locally and make my find methods iterate through the map directly ?
I'm not so sure but I guess it should be depend on the implementation. FastArray limits the representation of the data much, so It may block some replication in your structure
And how you planning to access the items?
Not just if the pointer is pointing to valid memory
I would avoid statements likevalid memory. It's rather "check for nullptr" + flags check.
Pointer can be not null but dangling.
In general, it's impossible to deducevalidityjust from address, actually that's why some smart pointers have so calledcontrol block. đ€
a stale pointer is not valid memory.
yeah though it's UB, e.g. memory can be deleted and then reallocated but in completely different context
You really arenât going to have many issues with stale pointers with UObjects if youâve handled them correctly. I think in this context using âvalid memoryâ is fine when it comes to something as high level as dealing with Unrealâs objects.
Same reason why in Blueprint itâs called âIs Validâ, and not âIs Not Null and Doesnât have GC flagsâ. Because there really isnât a need to be pedantic at this high level 
Sure, I donât see why not. It depends if youâre doing more adding/removing vs searching.
The GameplayTagStack in Lyra does the same thing. Itâs pretty common to have some extra hash bucket for searching inside of things like that
Correct, I just got confused that you separated IsValid into "reachability flag check" and "memory validity". Thus I made conclusion that everything inside IsValid except "flag check stuff" is a a memory validation, but that remaining part is basically null check.
The way you explained it .. made me realize much more simply what lag compensation is
You kinda connected the dots for me
Thx !
@honest bloom I don't think I do, but you can read this article that explains the concept in detail and with example.
I read it before, but had to connect the dots .. which you did for me when explaining it iteratively đ
I'm doing a mix of both yeah, it's just that my inventory combine account inventory (cosmetics etc) and gameplay inventory (world items, weapons, etc) so yeah it can be very large, I'll take a look to the one from Lyra tho, it may match my needs.
Hi, Guys. I need some help. I want to know how can I check the latency between the server and client. and then on the basis of that either pause the game or kill the server.
Can any one provide me with a solution or guidence.
Get ping in ms from the player state
Iirc
You can also ping manually or get round trip time
Simply doing an rpc and calculating the time from sending the letter to getting the answer
any built in function that i can use or is it a third party plugin
I just mention the node to get the ping.
oooh
well now i am trying to find how to improve the latency as the get ping in ms is saying 303ms
Get better internet
Or connect to server that is in your local region
The f? It's just reality
but the internet is 300mbs per second
i know man just joking
What are you pinging
hehehe
the cmd is saying 30ms but unreal is saying 303
and the server i am using is playfab
so i am confused
Make sure your server region is your local region
I know this, i meant it differently đ
Ah ok thanks, that clarifies it then. đđ»
What does game state as the game instance of the server even mean
Game state is game state, game state is replicated to everyone.
Game instance on the other hand is not replicated and every machine have their own GI
I simply meant it as a way of trying to understand the influence of the gamestate, as a functionality of transferable logic between levels.
Like the game instance allowes in a normal non multiplayer scenario.
Thats all đ
I still don't understand
Im very new to unreals way of doing multiplayer, as im used to photon cloud.
So the concepts are very different and important to understand correctly.
it's just 2 completly different objects with different purpose and different life time
GameState is primarily for replicating match-specific information
Thats ok i already have my answer thanks to matt
Exactly, and in a non multiplayer game, people use the game instance sometimes for this as well since it can keep that data in memory across levels.
Hence why i compare these, to understand the gamestate.
That's got nothing to do with multiplayer or not though
I feel like WizardCell's persistent data compendium link is the answer here
But I'm not aware of the inital question so it's just a guess
Those are different concepts really. What you're talking about there is preserving data between "hard" level transitions.
It does for me but there more to this concept then just the small post you saw.
But lets leave it there.
Im not here to confuze anyone.
Your knowledge is already more in line with unreals replication system then mine.
Im catching up đ
in a case of server travel is the game state even presist?"
what is actually preserved other than the actors that is added to a list
If you're looking for a way to carry information across levels you might want to check out this
But as it's stated multiple times, GameState's purpose is not exactly that
It supports seamless travel yeah, assuming you are going to a gamemode using the same GS
My "original" question yesterday was about how to have a client pawn ask the server to update a single variable only existing on the server.
And that variable apparently needed to exist in the game state.
Matt helped me with that and it worked.
So im not looking for information across levels.
I simply made a refference to a concept, eventho incorrect it did help me understand the role of the gamestate.
Thanks guys for jumping on it, really nice support here đ„ł
Is PIE local multiplayer instances only running on PC or on the LAN network ?
Like i test stuff in PIE, can a co worker login by mistake ?
like you are running a multiplayer test in PIE and then your coworker on the same network starts up their own multiplayer PIE and it joins yours instead?
dont think that can happen since it connects to localhost and not an ip or anything
As Omnicide said, it shouldn't happen by accident, PIE clients use UEngine::Browse() with 127.0.0.1:[EditorSettings.Port] as base URL
i didnt try yet, i was just wondering
But if you want to do it to test stuff, I think it was possible but I'm not sure if it can be done on PIE as well or just standalone only
okay thanks for the insights
If you and your co-worker have the exact same copy of the editor version, then I believe your co-worker could connect if they attempted to open a connection to your IP:port, but yea should not happen accidentailly and if you don't have the same version, then things may mismatch and error out.
You probably already know this, but,
it is possible if testing in standalone.
Out of curiosity I launched standalone while running an older instance of my game on another device.
I was able to connect in lobbies between the two. Now my set up wouldn't allow accidentally doing that, other programming potentially could.
But idk how common testing in standalone is in general.
Is it possible to use the CMC on Actors that aren't just a humanoid player running around the map?
For example, can I throw the CMC on a bouncy ball (with no controller attached to it) and take advantage of its replication, reconciliation, smoothing and all of the other useful functionality it comes with, even though my bouncy ball wouldn't be a character?
Or is this nuts and not how the component works at all?
The CMC relies on ACharacter for a lot of stuff.
Thatâs partly that Mover 2.0 was aiming to solve
Ah interesting, the description does sound a lot like what I could use
Still heavily WIP I'm guessing?
Smoothing is trivial and you won't get reconcile/prediction unless you actually control it
Say more about smoothing if you don't mind? Is there content you'd recommend I check out if I wanted to implement this? Never had to before, but happy to.
All CMC does for smoothing is blends the mesh to the capsule over time, that's all you have to do
Capsule location is always hard-set
mesh interpolates to it each tick
Snaps if the distance is too large
very trivial stuff
I keep having issues with Reliable Multicast RPCs not being called on my clients
My latest example is on my gamestate, where when a player's score is changed it fires an event on the server (it's already on the server at that point but it's just for clarity), which calls a multicast, but that multicast is never received by the client game states. Am I doing something wrong with multicast?
And I also know it's not the reliable buffer because I've debugged that and I only have a handful of RPCs firing at this time. I would bet though that if I added a delay before it calls the multicast it would work, for some reason when my player death event is firing it seems like all of my multicasts don't work
Hey does anyone know what could cause the players from not dealing damage to each other? I have added the tag properly, and all the nodes where I can select Run on server are setup that way, but my print strings are still not saying anything is being done to the other player.
dedicated server with 2 clients or listen server?
my guess is that you're trying to call a server rpc on something you have no ownership of
Not replicating properly could cause this. I'd try using repnotify
repnotify?
so, id never use multicasts to change property values. use a replicated property
It's not actually using the multicast to change anything, just to broadcast to update anything that cares about the scores (like the tab menu which shows everyone's score). The multicast fires after the scores have been updated on the server
use a OnRep/rep notify
so for something like this, on rep notify doesn't fire when an internal array value gets changed (afaik), so if I wanted to force a rep notify would I just have a bool that gets flipped or something? That feels a bit janky
Could someone help me with this?
The goal is to make the player place a bomb > ignore the bomb collision while he's on it > re-enable when he leaves the area.
It's working on the listenserver side, but the client acts like they're colliding, and keeps teleporting the player actor around the bomb.
I'm using "IgnoreComponentWhenMove", it's being executed by server authority, I don't know if the collision ignore is being replicated (Note that I checked "replicate" for both bomb and player collisors)
they definitely should, at least they do in c++. no idea if bp differs there for some reason
Hm okay I thought I tested that but maybe there was some other interference, let me check. Thanks for the info though
bp is really limiting for multiplayer
If you're dead set on using BP at the very least you should be willing to expose the functionality you need via C++
There's no award for making a BP only game and no customer will care đ
That sounds like I'm telling you that, just in general I mean đ
Hey, I have a replication problem, related the inventory system.
- on client, local player kills other player
- local player take other player's item
- after other player de-spawn, item marked as garbage in local player's inventory.
I explained it more detailly in here: https://forums.unrealengine.com/t/network-object-inventory-item-removed-after-player-removed-even-tho-looted/2268750
My question is, highlighted with red at the end of the diagram ("why no replication?").
What are the suggestions about this problem? Because I'm not sure if I'm looking to correct place
Hey, I have been struggling with a replication and garbage collection issue. BACKGROUND: Iâm designing a inventory system. All items stored in inventory are UObject. (This because planning that some items will be able to store nested inventories. Thatâs why Items are not FStruct). Character->InventoryComponent->Inventories->Cells->Items. Th...
Sounds like the other player is still the owner of that item and responsible for it's replication as a result
That also sounds like the most logical thing, however I couldn't find a way to change the owner. Even though I set the outer with Rename(nullptr, NewInventoryComponent)
Itâs that same thing I was mentioning yesterday, the outer isnât going to help with replication or GC. If you are using the replicated subobject list. You need to add it to the new ownerâs list, and remove it from the old one. You can change the outer alongside swapping lists
I also tried the new system as you mentioned and I got lots of ideas from it. However I tried but still didn't worked, this may because of I couldn't implemented it well to current system. Because I already have lots of logic and haven't planned the replication it to be this way.
So it's possible that I missed some part, in adding and removing. But simply adding items into replication list, and removing them anytime I remove the item, also didn't solve sadly
truly. and most c++ in unreal avoids the icky garbage in the language. pretty much just using it as a scripting language under most use cases
Btw I started to think that, I can continue pass the item as reference (in RPCs) and create a new copy of the item when adding, can solve the problem. Because I won't need to bother for its owner, it will be fixed every time I move items.
However that sounds like hiding the problem under my bed, you think copy'ing item is fine?
Sounds weird
đ
It sounds more like you just have some architectural flaws more than anything, because it really is as simple as removing and adding it from the list. Just make that happens at the correct time and the correct order.
I think you are right, maybe I need to go full refactoring on code, and convert the system into the new replication system.
Btw copying the item solves the problem, however it feels weird.
you don't need to use iris
are you using uobjects for items?
if so, is it a member of an actor or components replicated subobject list at all times?
He wasnât referring to Iris. heâs referring to the new replicated subobject list. He was still using the old way.
ah
Placed actor on world is not replicating, help.
It only works if you use the Spawn Actor by server during the game, but if the actor is already in the world, nothing happens.
Does anyone know anything I could try? I'm really struggling with this
im trying to fire a line trace based on the camera of a newly controlled pawn, and it seems that the server doesn't have access to the camera location / rotation, or maybe there's another aspect of this newly created pawn that isn't using what my character is (im just attemtpting similar logic to the char, getting camera location and rotation to start a line trace). but i know that the pawn doesn't have a movement component (i dont think this should matter, but perhaps it does?).
on client the trace follows camera but server trace is just in whatever the camera's starting position is. i have a "look" input setup, but again, not sure if this is really doing anything to cahnge camera location as i dont have any movement component or anything like the char does, but curious why this doesn't work the same way (unless it is from not having a movement component)
I'm spawning apples and bananas on trees near each other in a listen server multiplayer. My player has an overlapping component using a collision channel for interactables. If I swap out (scale to zero, or remove component from ID) an instanced static mesh component and place an interactable actor in its place using overlapped sphere component from the player, and I walk away from the blueprint interactable items, I'm having a hard time respawning the PCG Instanced Static mesh in place of the blueprint. How do I relate the ISMComponent with the BP_Interactable to a Client from the Server? Client does not see Servers ISM Component and vice versa as they re not replicable
why would it?
What's this trace for?
really was just testing, but it's going to be used for an attack later but wanted to just get it to work at first
If the camera orientation is driven by control rotation the server will automagically end up with the same rotation eventually, but the best feeling approach would be to tell the server the thing and have it do a sanity check if necessary
makes sense that it doesn't, would i just be able to send the camera location from the client then ?
what's driving camera rotation right now?
just a "look" input i made for it
is it like:
Input -> modify cam rotation?
or:
Input -> modify control rotation
Cam is opted in to use control rotation
ok thats modifying control rotation
do you manually do anything to the camera or do you let the Use Control Rotation thing handle it?
i may too many boxes checked, as i was testing a few things, this is in my camera
i also have this :
turn off the inherits
been a while since I messed with this stuff but you might be saying:
"Use control rotation, then just use the inherited rotation from your attach parent"
which is clobbering it
I suppose first off, print control rotation on tick, make sure the server and client agree on it. I think it's automagically synced through controller but don't really recall
yea this makes sense, will test rn
How do you replicate InstancedStaticMesh components? As they are non replicable.
just printed it, and tried a few different combos, tried turning off inherits, but server is always at 0,0,0 , while client changes
should i be using "use pawn control rotation" ? also, it's on both the spring arm and the camera , i have both checked
you mean like in PCG or another usecase? just have them spawn on both server and client and replicate the indices. I have them on both when an overlap occurs I have this just happen on the server an call a HISMOverp function. First spawn a replacement depending on what the component was. The replacment gets a reference to the ISM component and index. Basically if the replacement is a tree or rock it has a box collider, on end overlap if there's no players in the collider I restore the ISM by the index. (with a short timer) if someone re-enters the timer cancels. Don't actually delete the instances this causes a mess in the arrays and problems when someone logs back in, just offset them off screen, I use an offset of 10K, subtract it out when 'removing' the instance then add it when you want to restore is. The remove and restore is just multicast. Also don't replicate transforms, they 96 bytes each. I even have a lookup for the ISM components on both client and server so it's just a int32, not really as big a deal here but still.
edit: if the breakable that is spawned is destroyed mined, cutdown wtv then I send the ISM component and index to a function in my manager. (its position is already offset because of the overlap) It gets a timestamp here and gets put into a restore array. Every few minutes a function can run on a repeating timer that checks this array and restores the position if they meet the global respawn time (1 hour or wtv).
If you want the control rotation of proxies use getbaseaimrotation
it's more so that the server value* isn't changin based on the clients input, seems to get stay in one location based on how/where it was spawned
Just print get base aim rotation first
I don't know what else to say, that's the straightest way to get the control rotation
Control rotation = where the player is looking at
yea just did that, it doesn't change. the clients value does
Perhaps you are mixing it with something else
yea , have to be
the code ?
Yeah how you print it
And the result
Show
on server*
Well did you move the mouse around on both of the computer?
both ?
Going to try this tomorrow!
Just make sure you move the look view on both server and the client
Test in pie, move your mouse around for server
Go to client window move your mouse around
Their base aim rotation should not be default by then
Do that and show the print string result
im confused a bit, the print will show the client resutl changing as you move and server value is whatever it started at. that is what you will see, but i also don't understand what testing on a server would do for me
im assuming it is something in my control rotation settings
i also added a camera
and that also has settings, which i messed w trying to figure out what to chang e
I scrolled up
Camera transform is not replicated at least by default
And what's the point of wasting bandwidth anyway
If you want line trace from the camera. And the camera never get relative offset.
You can just use the control rotation ( get base aim rotation for proxies ) to get the direction where the player is looking at.
Then just line trace from camera location to the direction of where the player is looking at.
On the other note why do you need to do line trace both on the client and server? They shouldn't have the same values especially if the character is moving. There is delay.
You should just let local controller trace and use that as the truth for easy mode.
these would be what you're suggesting to use ?
this pawn doesn't move in this case
only can look around
it's not a char, more so a turret i suppose
So why do client have to trace?
it doesn't tbh
i was simply just making a simple line trace test
made a clinet and server version , just to see, and found the server was not getting values
but yea i could just send client location / rotation stright into the RPC i guess
Is the turret the player?
but i'd rather just figure out what the issue is, as i dont have this issue w any other logic which is based on a similar concept
no, it's a pawn
Then what is this server client even about then?
Assuming the turret is A.I
What kind of data does the server needs to know from anybody?
Is it possessed by the player?
yes
Then get base aim rotation will work
It's already replicated
And rpc already fired to server if client
Get base aim rotation = the control rotation
testing rn just to see (again im thinking i have at least 1 setting wrong here, but testing rn)
this value never changes (on the server btw this is on tick just to see the value, clients updates as exepcted), i have to have a setting wrong lol
the server line trace alwasy goes to same spot
client's goes as expected
without reading the lore sounds like smth that should be replicating from the server is only happening on the client. Is the actor replicated, are its components set to replicate etc
ForceNetUpdate is pointless on a character right since its update rate is so high? Just confirming
Most likely
Yes itâs replicated and I even have replicated movement just in case despite it not moving just rotating around
The camera component is not replicated tho no. Not even sure I could do that. There are a few other ways to get a result Iâd like but it is a bit confusing why the rotation doesnât seem to be read on the server
Trying to do this while factoring in potential desync. Any ways to do this without building a tool? Something simular to how collision checks are made when you spawn an actor?
if you're getting a rotation from a local camera it won't be on the server.
On the client, the PlayerController manages the camera's location and orientation the server has a representation of the PlayerController for managing server-side logic. There's yt tuts on how to replicate the camera if you really need to. I think I was doing smth like this for my aiming logic but would have to look at it again.
https://www.youtube.com/watch?v=gtgb7zCbXFc
can't say how efficient this would be but it will work
overlap test
Whatâs crazy is I have this working fine on my actual character. I just have this on a newly created pawn which is just simply a mesh and a camera rn. But yea I also was told about âget base aim rotationâ which is replicated but yea itâs just that the rotation of my pawn is simply not changing
base aim rotation is part of the pawn class and replicated by default. If you log it with and without authority (say on tick just as a test) you should be seeing the same rotator
without knowing the goal here base aim is the direction you are aiming. not the direction the capsule or mesh is facing
This is what is wrongly happening. My base aim rotation is not changing on the server. Client does but server doesnât. V confusing
Yea thatâs fine. In this case, itâs just simply a test line trace to get rotation. Did not think it would be this difficult lol but yea something gotta be wrong on my settings or something for this basic task to not act accordingly
Does GameState persist during ServerTravel to a new level? Or is it only GameInstance?
It will not persist.
Though I believe it is possible to have it persist by async loading a level with the same gamestate.
Game instance persists through everything.
Can anyone help explain what I'm doing wrong? I'm working on a multiplayer game. Currently, I have an "interact" mechanic that does a line trace and from there it checks if the hit actor implements an Interface and if it does, it executes that interface on that actor.
- The line trace executes at the server
- The interface execution connects to a custom event on the actor, and the custom event is multicast.
The issue I'm having is that when the line trace executes, it doesn't recognize the player's pitch. So the trace for clients is happening is a horizontal line from the player, instead of the ground or ceiling or wherever the player is actually looking.
Just answered my own question, sorry. Had to include the line trace start and end locations in the event execution so that the server has the start and end locations for execution.
Okay got it, what happens when a player overlaps two different ISMs? I'm getting Bananas spawning in appletrees if i go too close to a Banana tree after walking past an Apple tree.
they should be 2 different ISM components with different indexes so that shouldnt be an issue
Hm I'm doing a trick where the BP_Interactable_Item is a pooled actor base class and just swapping the 'look' at runtime
so it's one ISM component ... uh oh
This doesn't make sense actually one sec
hey, so I'm not looking for any solution, but rather if approach I'm thinking to take is ok or I'm missing something. Here's some context
I'm making a first person coop puzzle game. All the player interaction is processed through the server, so Client calls Server version of Interact function, it gets processed there, and whatever happens in then sent back to the client.
Now, I'm trying to include a minigame, which is a small simple strategy game, with which a player can interact, but in this case, a lot of stuff can be processed on the clients side - like selecting a unit, or determining which action that unit takes, and only if the player decides what to do, then communicate that to the server.
My issue is that since I'm controlling the player character, and everything happens through a player character, is including a local version of interact function a good idea, or should I try to do something else?
so local version of the function chooses a unit, and it's action, and then that's get processed on the server
Lets say i have 1 map, with a lobby widget for hosting and joining.
Can i then keep everyone who joins on this map?
Or as the host do i "Need" to travel to a different map with the "?listen" first.
My prefference is to do it all without needing to travel to a different map.
yeah idk about that. On Overlap I get the static mesh from the component -> get name, then that name I use as a lookup for the row in datable for the replacements. I don't see how pooling would be beneficial here. đ€
after a server travel, player controller is not reset. Is there a function to override to reset some values? Or I need to home made something?
https://wizardcell.com/unreal/persistent-data/
yes you can use relative, partial, or absolute. Or if you want a toatal reset just hard travel?
thanks I'm gonna try
Hard Travel is probably a bad idea.
I thought the idea was once the game started and clients joined. Use server travel.
Hard travel should only occur when hosting the game or when joining for the first time.
ServerTravel doesn't mean non-HardTravel
You are right about the second part, but that's still only a suggestion.
ServerTravel can be HardTravel or SeamlessTravel.
HardTravel: Clients get disconnected and actively reconnect.
SeamlessTravel: Clients get parked on the Transition Map.
Steam, for example, is very unhappy about Hard-ServerTravel
But if one would ignore that case, you can totally do every Travel as a HardTravel.
Epic just advices not to, probably mostly cause it's nicer for the Player.
I have a game where the player needs to click a point indicated on a slider. I was passing the click to the server but latency can cause missed clicks here. If I was checking on the client how can I validated something like this before triggering a success?
Probably as straight forward as you might think.
Like, you'd do it locally, tell the Server what the Client clicked, and the Server will then check if that makes sense given the Client's Ping.
At least if I understand correctly what you are trying to do.
"click on a point indicated on a slider" is not that clear to me.
Like, is this a timed event? Does the Slider move up and down and they have to click at the exact moment the Slider is on top of the point?
yeah, just a timing game. a hammer goes back and forth on a slider, click when its above a certain point
Yeah, Server and Client would basically need to both know about a given "Start" timestamp when the Hammer started moving. And then Client then tells the Server when it clicked, with a timestamp that uses the same "system".
Then the Server can take that timestamp to validate if the Hammer would be on top of the Slider for example.
A synced Timestamp like this can be figured out via a sync clock that should have a pinned post in this channel.
ok fair enough, thanks, I'll take a look.
It might actually not even need the Client to tell the Server a Timestamp tbh
yeah, I mean if the clocks are in sync then just send and account for latency maybe
If you can ensure the Hammer is started with the same Timestamp (relatively), then the Server can just take its own time and subtract the Ping time.
Yeah
+- some threshold
Article is great, I got a working network clock from copy pasting what the article did.
But I was also told there's already one in player state.
Just need to increase the update frequency on the player state for more accurate clock.
Or just make your own, I think the one in article is more involved and accurate.
Does replication typically stop firing once the actor is in the process of being destroyed?
GameState or not? I never liked that it resets the bucket. Always made my timers jump.
I see, I never personally used it to know the cons since the article you link gave me what I need.
If you have multiple UPROPERTY bools in a struct that is replicating, does unreal automatically pack them into a uint8? I heard something in #cpp that they do, or should I be doing something like this myself instead?
UPROPERTY()
uint8 bSomeCoolBool : 1;
UPROPERTY()
uint8 bAnotherCoolBool : 1;
UPROPERTY()
uint8 bYetAnotherCoolBool : 1;
I'm on 4.27 if that matters
at that point why not just do the trace locally and tell the server "I want to interact with actor X"
server can do a sanity check, like if you're close enough, then process
no, replication does not care about types being bitpacked beyond the information they represent in pure bits
replication converts things into a stream of bits
it does not care about alignment etc... it will depend on the type
3 bools only need 3 bits of information as much as 3 uint8 bits
you can try out the network insights window to see how your replication stuff gets packed
@thin stratus @pallid mesa I'm including this branch, for teaching purposes
I've also found it useful for narrowing down issues with complex movement implementations
Its the same as USprintMovement in the main branch but using move containers instead of compressed flags
https://github.com/Vaei/PredictedMovement/tree/sprint_containers
hi vaei that looks useful, thanks :)
I wrote a minimal wiki entry too
https://github.com/Vaei/PredictedMovement/wiki/Move-Containers
very nice
I'm Pooling the BP_Interactables only ( using a lookup for those too like you ), not pooling ISMcomponents that would be silly đ
Can someone tell me if OnComponentHit is automatically replicated please? I ask because Im having a weird issue đ
This works fine as in the health bar goes down on both Server and Client and when the enemy dies it plays the death effect to both Server and Client
but this function which applys a DoT to the enemy and then kills it works "ok"ish as in the server can kill and deplete the enemy hp and it all works across the network but the client does not update the enemy heatlh bar at all but can kill the boxes on their local machine but the server doesnt know the enemys are dead.
Do I have to run a "local" version of this as well as "Server" version of this which both have to be called when a client kills an enemy with a DoT?
Am not quite understanding why OnComponentHit which essentially is doing the same as the DoT function but in "instant" damage works fine but the DoT damage function does not work in the same way.
The only way for client to communicate with server is through server rpc.
Setting variables on client, replicated or not will only set it for it self.
So why does my Client communicate with the Server in the OnComponentHit work?
The same when you destroy a replicated actor as a client. Only the client copy will be destroyed.
The on component hit likely just happend in both of the machine.
Imagine a box collision
Server have the box collision, so does the client.
And the code is just saying if you step on it, print string.
So when a something overlap with the box collision on a machine something will print.
This shows it đ
You have to understand that everyone is running their own instance of the game.
Each machine is running their own code.
I didn't watch the video but looking at the codes it's already incorrect.
Damage and death is server only.
So why does it work if either a client or the server kills a box?
What works? I explained above
If a client set a value it will just change the value for it self.
If a client destroy a replicated actor it will destroy the copy in its instance only.
You should decide on who does what.
Atm it's a mess, a lot of machines doing the same logic.
The first 2 boxes one is destroyed by Server which updates the client, and the 2nd box is destroyed by Client which also updated the servers instance
Read above
You got no filter
On component hit will trigger on server when ever the component is hit on server.
The same thing on component hit will trigger on client when the component is hit on client world.
ok and IF client destroys a box should that update the server?
I explained twice already, no
If client destroy a replicated actor it will only destroy its own copy.
Thats what I would expect to happen but for some reason it,s working.
Which is why i am confused.
Ok.
So the OnComponentHit basically auto replicates to the server , Correct?
which is why everything after OnComponentHit works as Multiplayer Functionality.
No this has nothing to do with replication
Absolutely nothing to do with networking
You write the logic as such if a component is hit , run X
Picture 3 players, everyone running their own instance, running their own world.
Yep
When player 1 hit component trigger then it trigger on his machine.
When player 2 hit component trigger then it trigger on its machine.
And so on
Yes and each would only run on it,s local machine correct?
Yes
without a call to the server to say "Hey, I hit an enemy"
You need to write your logic first on paper. Decide who does what.
Like a goal post.
You don't care if the client overlap it.
You only care if the overlap happend on server
So with this Basically P1 should not be able to half damage an enemy which is located on the servers instance right?
In which you can do by switch has authority.
This code just runs on every machine. Period. It's not the way to do it.
Thats what i thought too!
Ok box takes 10 hits I fired 6 on Client and then 4 on Server at the same box and it destroyed the box with the above code , Which does not seem right to me
Yup totally expected
One way to do this or shooting game in general
You can have the client tell the server, hey I hit something
Then server apply the damage
You just replicate what you need, such as hit points
Yep did you look at the little vid btw?
Thanks for the advice btw đ
Ahh this info I just found might be something "Delegates are not replicated. Executing delegate from server, on clients itâs bit tricky, need some forethought and invovles writing quite a bit of supporting code. All data you will try to send trough delegate, will need to be replicated. DOREPLIFETIME or other macro, depending on how you want âŠ" (The event of Set Timer By Event Nodes are Delegates).
If the event that starts your timer is "Execute On All" then it is a multicast, which means you're starting the timer on all machines that receive the multicast. So each machine is then running a timer and then executing the events of the timer individually based on whatever values they have at the time the timer triggers.
Ye i think I need to have a NonReplicated function which triggers a Multicast to tell all the connected clients inc the server to run the Timer Node and apply the Damage Over Time to the enemy gonna take some tweaking about and I,m sure eventually it,ll click at some point but I think at the moment I,m kind of using the Trial by error method until my brain goes "Aha!"
Or a Non Replicated -> which requests a Connected ServerRPC to start the timer something like this. xD
Actually, you shouldn't be using a multicast for something like this at all... Health should be a replicated property on the target actor, and set as a W/Notify ... This then gives you a function that adjusts when the value changes. The server should be the only one actually applying any damage.
I understand "Switch Has Authority" has 2 lines of logic one will tell the server what to do and the other will tell the connected clients what to do
The timer only needs to exist on the server, the server sets the replicated health property, clients receive the OnRep and can adjust whatever visual things you want with the new value.
Ye thats actually a better method đ I need to learn to use RepNotify more as well
Thank you.
More like, one will be taken if the object has authority, the other will be taken if it doesn't.
that switch does no communication, it's a way to branch the code differently whether the object is authoritative or not. A replicated actor will be authoritative on the server, and not on clients.
how to pass my player camera manager to the server?
but the server doesn't see my camera manager
why
what are you actually trying to do
yeah I get that part but not sure how pooling would help with the spawned actors. Like I said each one has and array of players that it adds on overlap and on end overlap if there's no players starts a 5 second timer then reverts. In theory there should never be a ton of these spawned but curious how that would work.
hello everyone, does anyone know for steam am i able to set the game map in steam lobbies or do i have to use steam sessions for that
Nice, thanks. Also good work on the wiki. I'll read through it when I find some time.
Remind me what the difference is again.
gotta be honest im not 100% sure. i read online lobbies supposed to be for groups to get together beofre game begins and sessions are for finding each other like in a game browser. right now im under the impression that two different clients connecting and existing in one level is different than lobbies and sessions but idk
Pooling has been more stable than spawning/destroying many actors quickly in my experience in this case. There are six to eight apples per tree with lots of trees, and multiple players, not including foliage, berries and other types of interactables littered throughout the world. It's just a lot, so since I was getting crashes earlier from spawning and destroying so often I decided to pool and haven't looked back. No crashes. It's cool because I'm only pooling the BP_interactable base class and changing their look based on a PCG tag 'apples', 'bananas' etc from the looped static mesh spawner PCG node
Right, that makes it confusing for people who are new.
You have to understand that Steam Sessions and Unreal Engine Connection between server and client are two completely separate things.
You can create, find, join and leave a session without ever connecting to a server in theory.
The default join session node just does the connecting part for you, but in terms of code it's an extra step.
You can also connect to a server without sessions.
Sessions hold information about the server, e.g. the address, to make it easier for players to find and join a server.
They are mainly a blob of information in a database
Now lobby vs game (or Steam might call them Party vs Game) sessions are just a way for steam to group them in case you want to search for either of them separately.
On Unreal Engine's end, if you want to have the "light connection" for parties and groups of people without actively traveling to a map, you'd be looking at "Beacons".
C++ required
Most people here will early on create a session with the default nodes and that will create a "Game" session. And then use the Join Session node to join the session and get passively connected to whatever server that session is from.
Anything more advanced needs plugins and/or c++
thanks for the detailed reply!
I have almost completed my modifier implementation, which includes buffs/debuffs, both internally activated (activate on self) and externally activated (applied by another character on server only), as well as partial client authority to prevent de-sync when applied externally. I just have one remaining issue but its really bizarre so haven't been able to get past it yet đ It desyncs if you modify Velocity from the OnStartModifier() function, but only if FPS is >=61, never if <=60 đ
Ah, I remember that. Let me think for a second.
60 FPS is the threshold for a feature in the CMC.
đź
My assumption was that something was overwriting it following replication
But.. yeah, that wouldn't explain the threshold
So
It's been a while, so I might be slightly wrong, but:
ClientNetSendMoveDeltaTime=0.0166
That's a GameNetworkManager variable.
It's used in UCharacterMovementComponent::GetClientNetSendDeltaTime
Which gets called in UCharacterMovementComponent::ReplicateMoveToServer
if (bCanDelayMove && ClientData->PendingMove.IsValid() == false)
{
// Decide whether to hold off on move
const float NetMoveDeltaSeconds = FMath::Clamp(GetClientNetSendDeltaTime(PC, ClientData, NewMovePtr), 1.f/120.f, 1.f/5.f);
const float SecondsSinceLastMoveSent = MyWorld->GetRealTimeSeconds() - ClientData->ClientUpdateRealTime;
if (SecondsSinceLastMoveSent < NetMoveDeltaSeconds)
{
// Delay sending this move.
ClientData->PendingMove = NewMovePtr;
return;
}
}
In other words, if the Client has a framerate that causes the SecondsSinceLastMoveSent to be less than NetMoveDeltaSeconds, it will not send the Move and put it into the PendingMove variable.
NetMoveDeltaSeconds most likely ends up being 0.0166, which is 1/60
Do you have UDN access btw, can I link something for you
With 1/61 you go below that number and the PendingMove stuff kicks in.
Due to that, you'll get into the Combine Move logic next time.
If your Movement starts breaking with >= 61 frames, then you aren't handling move combining properly.
You can test that by disabling Move Combining via Console Variable.
p.NetEnableMoveCombining
Not right now.
Hmm that's true, I'm not doing anything in CanCombineWith for these yet, I was for Snare but.. yeah, didn't add it đ
I'll test
I found something labelled "Listen server don't ack clients movement if clients FPS is too high" and it sounds similar
The thing that is important to note here is that a Combined Move is not actually replacing the initial Move.
What will happen is that it will perform the Move A, and then try to combine it with Move B (the Pending Move)
Which means if it manages to Combine, you need to undo Move A.
Disabling this fixes it
There is a function in the SavedMove called "SetInitialPosition" or so
For the longest time you might have wondered what that is for compared to the outer function to setup the Move
That's where you save the initial value that will change throughout your Move
E.g. the Stamina value.
When you combine 2 moves, you'll want to reset the Stamina back to the Initial Value of Move A
It's super annoying that this isn't really explained properly.
Gosh, this is all it took to fix it
Yeah, but if you later have a move that canb e combined, you'll still need to understand it
Sprinting Forward in a Straight line can be combined.
But the Stamina has to be handled then.
So, if you imagine Boost and SlowFall work similar to sprint in their implementation, and ignore Snare, would this be correct?
Yeah.
Combining a Move is only a thing, again, if you can replace 2 individual moves with 1 and its results in the exact same state.
As soon as the result would be different if one of the two has a property different, then that property is meant to be checked in the CanCombine to block the combining.
E.g. Sprinting in Move A and Move B can be replaced by sprinting in the Combined Move C.
But if you Sprint in Move A and not in Move B, that doesn't work, cause Combined Move C doesn't know that it only sprinted partially.
Now if you do sprint in a straight line through Move A and B, you gotta handle that Move A can be Pending and Move B will be processed before being combined withe Move A. And then Combine Move C will be processed.
Which will result in Move B being processed twice, consuming more Stamina than you expect.
That's what the InitialPosition (state) is for, to save the Stamina and properly reset it back to before Move B.
Idk if I can explain this clearly. It makes a lot of sense once you fought that problem once.
And it#s really annoying since <= 60 FPS you might not notice :D
@thin stratus thanks so much as always, I just learned something pretty immense now đ
Totally just made those functions click
Going to do my best to translate them for PredictedMovement wiki
@thin stratus Does this look correct?
I've added a bit more, but haven't corrected for that yet
// We combine moves for the purpose of reducing the number of moves sent to the server, especially when exceeding // 60 fps (by default, see ClientNetSendMoveDeltaTime). // By combining moves, we can send fewer moves, but still have the same outcome. // We can only combine moves if the values are identical, otherwise we need to undo the first move before applying // the pending move. This is because the first move is applied and then the pending move is combined with it.
// When combining moves, the initial move is applied and then the pending move is combined with it // So we need to undo the initial move first, by resetting the initial move to the value we provide here, // which we simply retrieve from the CMC. // Afterward, the pending move will be applied, and the correct result will be used.
Right so it works like this:
Inside ::ReplicateMoveToServer
- Check if we have a valid
PendingMove- If yes, check if we can combine the
NewMovewith thePendingMove- If yes, combine
NewMovewithPendingMoveand setPendingMoveto null - If not, continue
- If yes, combine
- If not, continue
- If yes, check if we can combine the
- Perform
NewMovelocally - Check if we have a valid
PendingMove- If yes, continue (can't override)
- If not, check if we should delay sending the
NewMode- If yes, set
PendingMove = NewMoveand return - If not, continue
- If yes, set
- Send Move to the Server
- Here we can send up to 3 different Moves:
OldMovePendingMoveNewMove
- Here we can send up to 3 different Moves:
Not too sure about the OldMove right now, but also not interesting for the combining.
The point is though that if there is no PendingMove yet, it will set NewMove as PendingMove and not send it (in the >= 61 FPS case).
It did, however, already process that move locally. Next time it enters the function it will check if it can combine the PendingMove with the next NewMove. If it can combine it will and then process that combined move. But now the PendingMove will be processed again as part of the combined move.
// We can only combine moves if they will result in the same state as if both moves were processed individually.
// When combining moves, the PendingMove is passed into the NewMove.
// Locally, before sending a Move to the Server, the AutonomousProxy Client will already have processed the currently PendingMove (it's only pending for being sent, not processed).
// Since combining will happen before processing a move, PendingMove might end up being processed twice.
// Once last frame, and once as part of the new combined move.
// To counter that, we need to make sure to reset the state of the CMC back to the "InitialPosition" (state) it had before the PendingMove got processed.
@grand kestrel Something like that.
Gonna leave it at that for now. Have to take care of a few thing at home now (: good luck
Thanks so much! I'll dig into it đ
Have updated the wiki
https://github.com/Vaei/PredictedMovement/wiki/Move-Containers
@thin stratus Thanks to you I completed the final stage of my generic modifier implementation
Includes (stacking) buffs, debuffs, self-activated, target-activated on server, and multiple levels of each rather than on/off, and client authority for target-activated up to a specified distance/etc.
Once I complete the wiki and I've tested it more I'll do a proper announce đ
If you wanna preview you can checkout the modifier branch https://github.com/Vaei/PredictedMovement/tree/modifiers
@pallid mesa
Ooh somewhere when refactoring how modifiers work I broke my snares đ
So not done yet đ
Thanks, and nice work. I probably don't have the time to look much through it atm, sorry about that! The little time I have currently goes into my own little projects :P
@thin stratus @grand kestrel in case you didn't already knew about it you might be interested in https://docs.google.com/document/d/1UO6Ww6Lfpti3YElVdo9uioTUtQJQ9CoSLvd9kF8hvJo/edit?usp=sharing
Custom CMC Network Data Discord Permalink This document will cover how to use and send custom network data between the server and client through the Character Movement Component, beyond just custom flags. This could include sending additional compressed flags, additional input vectors, etc. No...
this class is so important to how the cmc and movement replication works and I always forget the name... thanks
Didn't know about the document, but the topic itself is what we basically just talked about above
Also if you think I'm doing this for the wrong reasons do let me know
Hello
I would like to understand something about cheating. The setup is Listen-Server and here is the context:
I have a mouse input linetrace that I execute on client then re-execute on server. for preventing cheating. So, I am using a LineTraceSingleByChannel() and using DeprojectMousePositionToWorld for the FVectors
The thing is, for client (not the one hosting the server), I cannot verify this linetrace on server because, the mouse position is only client-side
My plan is to make the vectors replicated and pass it to the server (With RPC or juste replicate var).
But my question is, by doing that way allow the client cheating with the hitResult from the linetrace, am right?
there is no property replication from client to server, it would need to be an rpc (without some relatively fancy custom c++ stuff to make the replication system send new datastreams afaik)
Guys, even with replication turned of for my chaos vehicle it still creates a copy on the client.
Ideas on what happening?
and yes if you accept client input without validating it, they can cheat
one could easily spoof the packet if they were willing to
Where's your spawn code
Might be running on the client
Already checked, its not printing on the client, so its not spawning the car that way.
Oh, well that's annoying
thank you for confirming my thought!
How could I prevent cheating? Comparing values when validating?
Yeah i have no clue whats left to check
your best bet is to breakpoint the client's care beginning play
to see if it was from replication inside of chaos vehicle stuff etc or just something else
I can test that indeed.
Yeah sadly i cant do that, because im using the EIk eos plugin and it needs standalone to run so breakpoints dont work.
I even removed the whole garage on the client, which takes care of the spawning.
Still the car popped up, so it must be that the car still replicates even with everything turned off.
So weird.
Breakpoints can be hit in standalone builds if you have the debug symbols for that build
I guess this is a good example of why c++ is a bit necessary for mp projects sometimes... I suppose you could try to see if bp exposes the event stack to be printed
Also I would recommend getting in editor multiplayer working if possible as it can be useful to be able to see things working quickly even if it's not a perfect recreation of real two separate clients
Does anyone have an idea on why doesnt the client also travel to the new map?
only the server manages to travel there, but the client doesnt đŠ
Yeah but its hard to read your conversation
if i want to test my multiplayer game which contains a lobby system, is it better to test it via Standalone game?
Depends though.
depends also if you use seamless travel or not
i am using
You don't really need an OSS for 90% of it besides the name systems and double checking connectivity through their systems.
And Steam for example will not allow you to have two clients on the same machine so you're going to be testing a cooked game anyhow.
But before you need to finalize that last little bit, the majority can still be done in PIE through the Null subsystem.
I mean the seamless travel from lobby to gameplay level doesn't need any OSS
Does need standalone though cause of the seamless travel
Or you can try your luck with pie seamless travel
Seamless travel đ€ź
Necessary evil
whats wrong with seamless?
Hello, I was wondering if someone can help me with something inside the CMC. So I have many mechanics that use the jump input. jump, mantle. hang and others. that the character tries to do them when jumping. Now the thing is all these are checked once the character jumps. however, i want that the jump should remain the same, but the other mechanics should start checking conditions after the input has been pressed for 0.2 seconds.
I tried modifying the first if statement of this with get controller and GetInputKeyDownTime (I know this is not the way to do it since it is a multiplayer online game but I was just testing)
// Try Mantle
if (MultiCharacterOwner->bPressedMultiJump)
{
SLOG("Trying Multijump")
if (TryMantle())
{
MultiCharacterOwner->StopJumping();
}
else if (TryHang())
{
MultiCharacterOwner->StopJumping();
}
else
{
SLOG("Failed Mantle, Reverting to jump")
MultiCharacterOwner->bPressedMultiJump = false;
CharacterOwner->bPressedJump = true;
CharacterOwner->CheckJumpInput(DeltaSeconds);
bOrientRotationToMovement = false;
}
}
This is inside the void UMulti_CharacterMovementComponent::UpdateCharacterStateBeforeMovement(float DeltaSeconds) btw.
But it just makes it so I can only jump after I press for 0.2 which is basically the same as original but worse. Any idea where should I implement this functionality I want and properly?
Hello I'm using a basic default root motion system but I'm encountering an issue animations play faster on the client side while they appear normal on the server. This problem only occurs in multiplayer.
on GM logout, why is the PS duplicated in AddInactivePlayer ?
hi guys I'm probably missing something obvious
I would like to have clients have their save files locally
When they join a session they pass the save data to the server so the server knows all the info it needs to load up their character
But when I tried it like this the save data is empty
How do I pass along a client's save data to the server?
Generally speaking, not much. Nothing that good project structure can't fix. But it's one of those things that quickly gets messed up. Loading screens during it hitch during it from world loading, or from people sync loading things, which is a huge problem on consoles where clients are connected and still talking in voice because you have to keep their voice indicators visible and active and that is hard to do with slate frozen. On top of that there are issues with actors sometimes persisting despite that they shouldn't. And for the actors that do persist for the data transfer like playerstates and such, they drag stuff from the previous level into the new one, which can bring a lot of referenced data if you're not careful with linkers.
Just a lot of minor stuff like that which shouldn't be a problem, but tends to be and it's annoying to deal with sometimes because the fixes are rarely small.
You can't just pass an object like this that was created on the client. When you pass a pointer into an RPC, it will try to resolve that object on the other side of the RPC. And for it to resolve that object it has to have been created on the server and replicated to clients.
Do you have any C++ ability by chance? There's a quick and easy way to make this generic.
I can use C++ if it's required for this
In BP if all of your data is in a single struct in that savegame, then you can just pass the struct itself. Or you can manually pass every single data item from the savegame.
If you want something more generic, and can use C++, there is a serialize function that can write an object down into a simple byte array which you could send.
And then either way you'd have to construct a new savegame(not load), on the server and set the data in it either from the loose properties or reserializing the data into the new object.
Oh I didn't realize pointers were a special case thank you I think I can work around this understanding that
for things like asset pointers and replicated objects unreal kind of magically does this for you and hides the complexity
It's just a name list.
Mostly anyhow. At least to replicated objects you pass a pointer to an actor component and it sends like... WorldName.SomeActorName.ComponentName And then it just finds them by that path name.
name export is a bit more than just a list... some things are sent as full paths for a connection and then resolve to a smaller id
hello guys, I work with unreal for some time, but I'm really noob with multiplayer and replication, and I'm trying to fix a small problem on a project here.
Basically, the game is a shooter, where you can buy weapons when you die.
all the respawn logic is already made on game mode, so what I did is:
I created an array var on PlayerState (BoughtWeapons)
When the player buy one weapon on the Widget, I just cast to the PlayerState and add the BoughtWeapon to the array.
On the respawn logic, I just get the BoughtWeapons and add the needed weapons to the spawned character.
The problem that I'm facing is:
It's working pretty well on server, but not on the clients.
I know that GameMode only runs on server, but I don't know exactly the correct way to solve this.
The client can send a server rpc that adds the item to the array in the player state
Seems to me your issue is you are adding it on client.
The only way to communicate to server from client is through server rpc.
Setting anything on your own machine as client will only sets it locally.
Replication works from server to client
Is it me or the CMC doesn't replay jumps in case of desync? Like in FSavedMove::SetMoveFor we save the value of bPressedJump but in FSavedMove::PrepMoveFor we ignore it
Didn't tested in game yet, but it looks like the input will be ignore during replay?
Got it all working with a lot of learning and reading your answer above. Thanks for your help. You are a Legend.
hi i got problem with this code Run On Server not working on client it's an actor i have another actors with similar code but only its not working (componentReplicates Replicate movement etc. is open) and I use this https://www.youtube.com/watch?v=4vUCXwOMXsY&t=1354s https://blueprintue.com/blueprint/jwgps0ki/
Support me here: https://www.patreon.com/halbotstudios
Get my assets here: https://www.fab.com/sellers/HALbot Studios
Join the Discord and showoff your work here: https://discord.gg/Syccf4gTwE
Learn how to create a Resident Evil-inspired power switch puzzle in Unreal Engine 5! In this step-by-step tutorial, we'll replicate the iconic power sw...
is server event set to server, and multicast to multicast?
yes bro
but if I set server event client cant interact with switch but multi cast can interact dont sync with server
@tacit furnace Is the Actor/Component you call the RPC on owned by the given Client?
Also.. is that a Singleplayer tutorial?
That will be really tricky to convert to multiplayer on the fly.
You can't just call RPCs in the Switch Actor. You would need to set up your whole interaction system to be multiplayer ready.
Yes bro but i dont have replicated switch puzzle tutorial
Did you now Any fix for this
There is no "fix". You gotta convert whatever they are doing to Multiplayer
That requires knowledge of how Multiplayer works.
Your interaction system that toggles the switch already has to have the multiplayer part built in, so that your RPCs are sent in a client-owned actor
Which means you can't flip the switch like this in the Actor. You have to RPC wherever you do the interaction code that traces for the switch (or however that works in this tutorial). And then tell the Actor to flip the Switch via RepNotify booleans etc.
Doesn't make sense to me that you follow that tutorial if you don't know the basics of multiplayer yet. Better learn from a multiplayer tutorial and then make that little switch thing yourself later.
Okey bro thanks
Most multiplayer tutorial be like multicasting everything 
At least the one I sees on youtube
actors marked as replicated, if their movement is not replicated, and I move them on each client, does that mean they might get out of sync?
Potentially, yes.
What does it mean and why? Is it getting out of the net cull distance and not being relevant by server anymore, although client seeing like they are in range? Or is there more depth to it?
Awesome, glad it works đ
Hello, everyone, I am working on an RTS game that should have many characters. Currently, the issue is with CMC and the character itself. I tried to write an efficient movement component for a pawn, and it was successful but does not have network prediction. I am looking for a lightweight solution plugin that is very lightweight and enables me to use it for a large number of characters in a multiplayer RTS game while having the network prediction on client sides.
If it's an RTS I'm not sure why you'd need prediction
I'm also fairly certain said plugin doesn't exist.
In fact, for an RTS, you almost definitely don't want prediction
Yeah, the only other partially non-sane thing that people do is have actual P2P for RTS, but that's not a thing for UE anyway.
Well, without prediction the characters seem very choppy on the clients.
Its not p2p, its client server model
How many characters are you moving here? You should literally just be able to move them on the Server and they will "smoothly" blend on clients.
When I used another movement ocmponent, all simulated proxies movemetn become very choppy
around 1k is the goal
No chance lol, not with CMC
yes its not possible with CMC I am asure of it đ
1K will be choppy because you won't be getting nearly enough updates to do smooth movement, so they'll be snapping
You will need a more bespoke solution
no the 1k example was not cmc
it was a custom movement comp and fps was fine
it was choppy only on clinets
Well 1K of any actor, CMC or not, will be biblically too expensive to replicate movement
So you'll need something more bespoke
Replicating the movement of 100 sim proxies (which don't even run CMC anyway) is a hard task on it's own
At those kinds of counts, even using AActor can be brought into question
it was probably fine in editor, but IRL probably won't be great
it was not editor it was on two different pcs
and bottle neck was skeletal mehses. which I am switching them to Vertex Animations
So the thing is it might be 1000 actors, ,but not all of them are going to move at the same time mostly most of them just stand still and play some animations (working animations),
The trouble is, with 1,000 actors, the engine is going to be spending an awful lot of time deciding what to actually replicate to whom - so server performance will tank linearly
all of the mare replicated since the start of the game
So at the very minimum, I'd probably be replicating that info via some kind of proxy actor
And potentially divvy the information up into your own clusters or buckets.
I meant all of them are always relative
Even if they aren't moving, the engine will still be processing them for relevancy, dormancy etc.
And it's not threaded, it'll just be a long as linear loop, for every actor, for every connection. Quickly becomes an N^2 problem
So some kind of replication proxy which replicates info for many of those actors at once is probably a good start
And I also wouldn't run any movement simulation client side.
Just smoothing
I like this idea, I have not thought about it.
well is it possible to make movements smooth without cmc?
and is smoothing really different than predictions?
Manor lords used a vertex animation plugin that only works on actors. but of course manor lords is single player so its way easier for it, it can simply use pawns with a very leight weight movement component.
But I am wondering is the unreal engine this bad for too many NPCs in the game,
Sure, all CMC does (for sim proxies) is when it gets a transform update, it snaps the capsule instantly, but offsets the mesh. Over time the mesh just blends back to its default relative location/rotation. Very trivial to do
Well certainly out of the box, it's not equipped to deal with these numbers.
Vertex Animation is interesting but bounds would have to be large enough to accommodate it. Presumably they did they to save on scene component transform updates, but again there are ways to mitigate that.
So games like age of mythology, the retold one, or strongholds serires, how those handle that many NPCs in a multiplayer game
custom engines usually
Whether Epic admit it or not, Unreal is a shooter-based engine
And the tooling/out-of-the-box stuff is geared towards that
Well, if my project wents well, I find a way to get access to private engine desgiend for RTS đ for next projects
Thank you for the information btw you have opened some new doors for me to explore them
one quick question, what did you mean by bounds here?
As in the bounds of the component. If you offset the vertices on the GPU, the CPU-side bounds still need to encompass that mesh otherwise it won't draw
But increasing the bounds is obvs going to make it more likely to be submitted for draw, so is a performance trade off
If Manor Lords did something to "smooth" characters with vertex offsets instead, my bet is they increased the bounds dramatically in a bid to avoid lots of scene component updates on the CPU, which are also a bottleneck at high actor counts.
Many Thanks, Also I have just done a research. Although still believe UE is not the best engine for RTS, but there were games like Tempest Rising
that are multiplayer and has about 400 on case of 1v1 in its multiplayer
and also there are other games too, so there should be a way to get around 1k soldiers/ workers in a multiplayer environment.
Also Ancestors Legacy seems to have quit large number of npcs in its game
Are there any alternatives to listen servers and dedicated servers these days for more server authority driven multiplayer games?
I really only need a server for rng and simple number-based stat tracking. The mechanics are simple enough that almost everything else can be handled locally.
Is there a solution I don't know of that doesn't require me to pay for long term server hosting for the lifetime of the game?
why not using listen server?
Because the host could cheat.
They could modify the rng locally.
aren't there anyway to prevent host from doing so. I am not an expert about cheating but I think there should be a way that you can use something like an anit cheat to stopp host from cheating
Not really and it would be a waste effort.
Also, you can use seeds and somehow find a way to generate the same series of seeds at the start of the game on all clients and the server, and then you can create a system that check if all players end up using the same seed for the rng then it means no one cheated
Possibly, but from what I've read, server authority is the best way to handle it.
I'm looking into peer to peer authoratative models right now where each player would basically agree on a seed based on a time stamp or something and roll a number based on that.
Yeah. This is exactly what I was starting to consider.
Could it be as simple as using the time stamp and maybe the current game state (stats or something) to generate a seed from?
Using network clock is probably the closest thing you can use
or a combination of all
also you can use game session ID, which I think is the same for all paleyrs and the host
Yeah. I'd have to use some sort of clock to get a different seed each time.
This sounds promising though. All I've ever toyed with is dedicated servers and listen servers. Does Unreal have a way to do peer 2 peer like this out of the box? Via Steam?
Unreal is not p2p out of the box.
Also keep in mind, there's absolutely nothing stopping players modifying the local state of the game even if they do receive the RNG seed from a Server
I mean even if you receive the RNG seed, you can just modify it in local memory
And that is extremely trivial to do
If you care about cheating, that's not going to solve it
The rng from the seed would be the same for both players, so if they didn't match, then we'd know somebody was cheating and just end the match.
Right?
Or am I misunderstanding how this works.
Ah. Okay. So server authority is the only real method to prevent everyone and their grandmothers from being able to cheat.
But how do you know the client has modified the value locally? You can't possibly know that (on the server)
@chrome bay One quick question: For having the smoothness effect on characters or pawns on clients, is there a ready-to-use solution on Unreal Engine, or should I write something for myself if I don't like to use CMC and characters?
Nothing I know of, but should be very trivial to do one yourself
Projectile Movement Component has a simpler version IIRC
What I mean is, how are you going to validate that clients are using that RNG seed? I don't really have enough context here.
A client can cheat if you ever give client the authority to modify gamestate. If the Client for example, pulls a weapon out of a create and "tells" the server what they just pulled out, that's immediately an avenue for cheating.
@round mist reading above maybe you are doing some kind of damage system? The client shouldn't even have any say when it comes to damage.
If you want to predict, then fine do it locally but at the end of the day those number are just illusion because the server would be the one that implements the damage and sets the hp
So a player can cheat and change the value locally but it will have no implication on others.
In general you shouldn't predict anything related to damage though. Damage indicator should be just something that server do
I never predict damage personally. Far more confusing if you predict incorrectly
Generally big events like, especially if hard numbers are shown to players, are better when they're accurate
The game revolves entirely around dice rolling, but I would be using GAS to take advantage of status effects and I guess all of that would also need to be on the server.
The idea was kind of like how blockchain (as far as I'm aware with my very limited knowledge) uses peer to peer confirmation. But with only 2 peers it's a lot less secure, clearly.
The idea was that if both clients locally generated a seed based on values that should be identical for them both, then they'd generate the same number. and if those seeds didn't match up, then somebody is cheating.
But without a built in p2p system this is all pretty moot anyway cuz I wouldn't even know where to start with that.
Many thanks
So I guess if I want PvP then I'll be looking into just simply server hosting solutions.
I'm just a noob but to me that's like the only sane solution.
At the end of the day the auth figure can do w.e
So if you let your player hos the game, there is probably no way to stop them from cheating.
Listen server is good for co op and when you don't care about cheating
Yeah. I use a listen server for my current game (and dedicated servers). And I've never been interested in making a less casual PvP oriented game, but I have an idea that I think could be pretty neat so I'm exploring the options.
Ye I wouldnt bother preventing cheaters in listen server model
The host can just do anything to its instance.
E.g memory manipulation
listen server aside, you still want to maintain good practices generally. Kind of have to anyway if you want to support dedicated as well.
Does anyone have any resources on how to create a traffic system for multiplayer games. particularly on how to spread out the traffic between all the players. Ive looked at some differnet approaches on the systems itself and will probably use splines as the road network is very varied in lane sizes and such. Would just calculating distances between all players work well for removing and adding ai traffic?
Hey ! My Map has a Game Mode that has Dedicated Server logic.
If I want to also implement a "training" mode where a player can run a local instance of the map, what is the best practice ?
Should I duplicate the map and create a new game mode ? Is that the best to do ? As the duplicated map contains same assets, it wont affect the size of the game much, right ?
You shouldn't duplicate the Map if it's the exact same map in the end.
You can tell UE what GameMode to use when loading the map by passing over ?game=GAMEMODE_SHORTCODE
Which GAMEMODE_SHORTCODE points to which GameMode class can be set up in the ProjectSettings under Maps&Modes.
It's probably best if your GameMode can simply handle both, DedicatedServer and Standalone.
Then you don't need any new GameMode/Map/etc.
Thanks, I'll dig into that ! But I dont know how to make the GM "know" that it's currently running on a dedicated or not ?
IsRunningDedicatedServer()
Or in Blueprints probably IsDedicatedServer or so.
Sorry if that's a noob question, but, how does it know ? Is that variable hardcoded when packaging for gameserver from UE Sourcebuild ?
yep, there is macro definition UE_SERVER
Easiest way to answer that in the future is to check the source code of said function
Hi, I'm having an issue with my pre lobby widget, I've got 2 race conditions happening atm.. the first one is that I have the pre lobby widget being created on begin play of the player controller however the OnPostLogin event is called quicker which calls an event to update the UI on all connected players but because the pre lobby widget hasn't been created yet it doesn't do anything until its called again, but always when the player first joins it wont update their widget until someone else joins or they press the 'ready up' button to trigger the update all player lists event again..
The second issue is that OnLogout is called quicker than the Player Array on the game state actually removes the player from it so again it calls to update the UI on all connected players but it still includes the player who just left. Whats the best way to go about fixing these?
Does the option "replicate movement" affect performance even if the actor doesn't move?
What are some tools available to me on Windows if I'm trying to diagnose why a very small subset of players struggles with ever hearing back from the server after sending it the first n packets at the very beginning of joinin a session.
I'm guessing they have some issues with their NAT settings or a firewall that prevents the server's response to them (UDP packets sent from port 7777 to some other port on their machine), but I don't have a super obvious way of testing that hypothesis without running some tests. Any tools that might be useful for this sort of debugging?
Update: ah, looks like 7777 isn't actually the real port here, it's Steam P2P Network's "channel". Looks like Wireshark is the way to go here.
There isnt any C++ function that is called on Actors after the Server sends replicated data?
Like a PostNetSend lol?
PostNetReceive is obviously for Clients.
PreReplication
void APGObjective::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
{
Super::PreReplication(ChangedPropertyTracker);
if (bActive && bWasInactiveForPreReplication && bImmediatelyCompleteWhenActivated)
{
// If we were Active and we are about to Replicate that change, then also call Complete since we want to make that transition straight away.
// We have to manage this here because Complete also calls Deactivate, which will effectively cancel out the call to Activate for Clients.
// This should cause bActive = true to replicate to Clients, from the call to Activate, while also sending the call to Complete in the next update.
// While also allowing Complete to then call Deactivate without stomping on bActive = true for Clients.
Complete();
bWasInactiveForPreReplication = false;
}
}
Welp lets hope that works.
đ€
It works, just have to defer the call to Complete until the next frame.
I thought that PreReplication would have already gathered the replist, but seems thats not sufficient, you still have to wait for the frame to complete.
A PostReplication function would have been better lol
Though, that wouldnt account for if a property wasnt sent in that bunch and was instead deferred because of saturation or something
Mmm waiting for next frame would also have that same problem
PreReplication is before it decides to replicate or compare that actor. The idea is you can do last-minute property updates (e.g, replicated movement)
When writing NetSerialize for a USTRUCT, is the size limit 64KB (size limit of an RPC)? I can't find any doc on this at all online.
That question gives me NPP PTSD.
Isn't that the exact shitty reason they wrote that Bypass for the ServerRPC in NPP?
Maybe not, maybe that was just bandwidth limit in general.
when you remember that Epic doubled up on all the RPC's in NPP too
I do think 64Kb is the max packet size though yeah
Although RIP if you are actually anywhere near that
It's 1024 bytes to fit in MTU though
Rpcs can split into large data
At least in the regular net driver
As for how that works exactly I don't know
I'm wondering if I should try an http stream or something for certain large things
Where does that limit actually come from? MTU can be chosen after all.
Within limits that is.
Which step in the whole transport applies the 1024bytes? I know Ethernet sits at 1500. IPv4 at 64KiB.
Lower values would mean less delay of course.
Oh sorry I meant UE's enforced packet/bunch size
Once code leaves UE I am a simpleton 
Right, I think I see now. So we got like 1500bytes due to Ethernet. IPv4 routers would fragment packets that are bigger than that.
There are risks of Routers dropping packets that are too big, instead of cutting them apart, sending back an ICMP that the packet was too big.
Some Routers (I guess IPv4 by default) do both, they send it but also annoy the sender about it.
Given that IPv4 encapsulates the data, so adding additional bytes on top, I would assume the 1024bytes by Epic might just be a "That will make sure things fit." number.
Sending data that is bigger than 1024 (or fwiw 1500) would I guess already be cut into pieces on the NetDriver level, to avoid any problems with other services (e.g. Router) to begin with.
That's my understanding at least. Doesn't necessarily prevent you from sending a lot of data though.
That's my impression as well
I raised it and ensures yelled at me
hey, what's the best place to store api keys and other sensitive data?
Potentially only on the Servers that Clients can't reach.
Probably just that. Standalone across 2 PCs is not really wanted.
You usually package and use the same packaged version on both.
You should also have this in your logs.
UE_LOG(LogHandshake, Log, TEXT("Server is running an incompatible version of the game, and has rejected the connection. ")
TEXT("Server version '%u', Local version '%u', Server features '%s', Local features '%s'."),
HandshakeData.RemoteNetworkVersion, LocalNetworkVersion, ToCStr(RemoteNetFeaturesDescription.ToString()),
ToCStr(LocalNetFeaturesDescription.ToString()));
Different NetDriver. You shouldn't even be able to connect by IP if you use Steam
Server and Client need to use Steam.
The error you get is one you'd get with and without Steam though. So not sure.
You don't. If you develop a Multiplayer Game with Steam, you are doomed to test with 2 PCs and thus properly package.
The Version error can potentially be fixed by ensuring that both provide the same version.
You'd need to check the Source code for what UE is actually comparing there.
Yeah the NetworkVersions are different.
const uint32 LocalNetworkVersion = FNetworkVersion::GetLocalNetworkVersion();
const bool bIsCompatible = FNetworkVersion::IsNetworkCompatible(LocalNetworkVersion, HandshakeData.RemoteNetworkVersion) &&
FNetworkVersion::AreNetworkRuntimeFeaturesCompatible(LocalNetworkFeatures, HandshakeData.RemoteNetworkFeatures);
@steep abyss You can try to use networkversionoverride as a console command to maybe set it to something that is compatible on both sides.
// add a cvar so it can be modified at runtime
static FAutoConsoleVariableRef CVarNetworkVersionOverride(
TEXT("networkversionoverride"), ReturnedVersion,
TEXT("Sets network version used for multiplayer "),
ECVF_Default);
Are you trying connect packaged build to editor game?
And both were packaged with the same changes?
Again, Server and Client also need to use the same SteamNetDriver setup.
Kb as in kilobits? Oh god.
that's a giant packet
So should any NetSerialize implementation I do not put more than that in the archive? I thought I could get away with a bit less than 64KBytes (size of UDP)
What on earth are you sending?
Keep in mind NetSerialize is generally used on structs that range from like 1 - 500ish bits or so by the time they're packed (very loose guide there)
And I do mean bits
UE replication is geared towards lots of high-frequency, small packets
Hi I have been doing a lot of reading and have a couple questions regarding it, Wonder if someone can answer please.
1 : Whats the difference between a Run On Server custom event and a Switch Has Authority Node ?? (After all everything after the switch (The Server Exit Pin obv ) gets run on the server doesnt it?)
2 : If you have a non replicated event inside a OnRep (Which is run server side as OnReps as I understand automatically pass down all info to clients) does it still pass all the information from that event outside the OnRep?
3 : When should you use a OnRep or a Multicast (If all info is passed to clients from OnRep why do we need Multicast?)
4 : Run On Owning Client means that "Only run this on the local machine", Although I am not sure when you would make use of this as I play Dead By Daylight as a example I cant seem to think of an instance of when you would use a "Run only on this machine" without passing any information to the server to be validated first.. IE. Health Potion, or Survivor Perks etc.
I understand these might be basica questions but was looking for a laymans explanation of each and a "use" case scenario for each if possible please.
-
Authority = You have authority over this actor locally. You can have authority over something you spawned locally as a client, or if the actor was previously replicated and "torn off" by the Server.
-
OnReps only run on Server in Blueprint because they are a nasty, horrible hack. "Proper" C++ OnReps only run client side. Other than that, they are like any other function.
-
Properties for state and/or anything that persists, multicast for transient events that you can miss. General golden rule.
-
Run on Owning Client = either the local machine if you are the local authority OR the client who is the "net owner" of the actor.
If in doubt check the compendium
Thank you for the reply! I have been reading a lot of differnet articles which is why I was looking for a clear concise answer here from someone whose knowledgable đ
Hi, I need someone's help these race conditions are driving me nuts đŹ ive got my OnPostLogin telling the player controller to create the pre lobby widget to avoid a race condition where OnPostLogin is called before BeginPlay on the player controller, but now when i try to update the players list of all players in the pre lobby the game state cast now fails for the client so it doesn't create any of the WBP_PlayerNameCards like it does for the server player, how can i get around this so everyone see's the same shit
The other race condition ive got is that OnLogout is called before the GameState>PlayerArray actually removes the exiting player so when OnLogout calls to update all players lists it still includes the player who's just left
I'm digging on making my GM logic viable for both Dedicated and Standalone. But I will have to use a "IsDedicated" Branch for absolutely everything, right ? Do I have to recode everything ?
Like, not only the GM
For example, in my character, some actions are locally done (i.e. shooting) without any change to the server, and done in the server at the same time, in order to give the player a smooth experience.
How do I make this LOCAL action (input action) "know" that it doesnt have to launch the fake shot, when in Standalone ? "IsDedicated" will only return false whether is Standalone, or simply the Client in a Dedicated environnement. So it doesn't know if it has to launch a fake shot in addition to the "real" one.
Should I create a custom variable that I set at the beginning ? Or is there a better practice ?
Hi, question, would it be possible for me to make a cross play game ? I mean so i can play from pc with a ps5 user without any licenses
well seeing as multiple cross-play unreal games exist... yes. but what does "without any licenses" mean
Technically - yes, realistically, no.
there are specific TRCs for it, but it's doable
Though, I guess it depends on your definition of "license"
EOS supports cross-play out of the box - but you need a license (it is 100% free, literally just make an account)
You could build your own servers too - but you'll most likely want to rent a server from some company, but you need a license
Could make your own internet as well - but you'll most likely want to use what is already in place, but you need a license to do so.
Wouldn't the PS5 part need a license, no matter if crossplatform or singleplayer?
Or what license are we talking about
Hmm license i mean like could a noob like me get it working p2p ?
I suppose
Or something
Just a language barrier most likely.
UE doesn't support P2P out of the box. You would need to do a custom networking solution.
You'd still need a dev kit for PS to even release on the platform
So, you still need a license.
i honestly dont see why you would want P2P when you got LS
Hm mkey but even with LS it sounds like its more advanced then watching 30min tutorial so guess thats out of the question then đ«
It's mostly backend and platform involved. It's not even that much unreal engine related.
Do you know the difference between listen server and peer-to-peer?
almost nothing is true peer to peer nowadays
last game I know of like that mighta been Starbase
Crossplatform is like the last thing you want to do as a new developer.
Focus on making a game that works first.
I remember "p2p" term got abused a lot around CODMW2 (2009) because that was all listen servers too
the EOS plugin does have support for EOS p2p, which is mostly just acting as a NAT punchthrough
what is the way you compile your C++ visual studio file?
do you use this button here with enabled live codin?
I have seen that after i use that, i get a specific error:
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000018
UnrealEditor_LicenseGame_patch_0_PID_28616!FindFieldChecked<FProperty>() [C:\ProgramFiles\EpicGames\UE_5.3\Engine\Source\Runtime\CoreUObject\Public\UObject\UnrealType.h:6843]
UnrealEditor_LicenseGame_patch_0_PID_28616!GetReplicatedProperty() [C:\Program Files\Epic Games\UE_5.3\Engine\Source\Runtime\Engine\Public\Net\UnrealNetwork.h:223]
UnrealEditor_LicenseGame_patch_0_PID_28616!AThirdPersonCharacter::GetLifetimeReplicatedProps() [C:\Users\ycarp\Documents\Unreal Projects\LicenseGame\Source\LicenseGame\Private\ThirdPersonCharacter.cpp:125]
no
you close the editor and compile. live coding has limited uses that it won't corrupt your project, like modifying the body of a non-ctor function
could you re-watch what i added in there please ?:))
that doesn't change my answer
like could be this the real reason it fucks up
because i been on this
for a bit
and i get frustated
Yeah, the Host Migration support was mostly what I think people want when they hear P2P
Especially for UE.
I have this inside a BPEnemy which on BeginPlay creates a reference to the Widget to be used but I get a Accessed None for the W_HealthBar when changing the CurPercent value. I understand that Widgets are not replicated (Or at least the articles I,ve read and stuff say they cant)
The server can update the Health Widget no problem but when the client deals damage the health bar does not update on anyones screen. Im driving myself crazy trying to apply the Cedric's articles to this or the Wizardcells and numerous tutorials I have seen all do Player to Player HP modification and not like if 2 players are beating up the same enemy.
Please can someone help me before I drown in numerous articles and even more hours on youtube trying to work out how this is done.
Sorry - instead, we're going to give you server meshing.
đ€· I think Host Migration is pretty niche.
I'd say server meshing is even more niche
It's a nice-to-have more so than a need.
Agreed
As you can see from the Images on Press of 1 (Inside the Player Character Blueprint) run the DealDamage and pass value of 100 which is in turn passed to a component which does the health reduction and returns a percentage for use inside a HealthBar I did add a Set CurPercent after the TakeDamage and ReturnPercent node (To trigger the OnRep function for CurPercent) to attempt to update the enemy health bar.
Are you doing the damage locally?
Is this a listen server setup?
Is the player the host?
Or the client?
Yes its listen server.
I get a WHealthBar accessed none when using the Reference insside the OnRep.
How does the enemy get the reference to it?
This is where i set the reference for the enemy player
So the enemy "knows" about their Health Bar Widget
but for some reason when the OnRep triggers it complainss "Hey we dont know about the health bar"
Could be a race condition.
Do a validated get inside of the onrep
Actors can receive onreps before BeginPlay runs
like this ?
You can, or you can right click the property node and click "convert to validated get"
server deals damage (from the server window)
Then if it isn't valid, get it.
Client 1 deals damage As you can see it doesnt update on the others the same as it does for the server.