#multiplayer
1 messages · Page 270 of 1
In PostLogin, it’s to provide the info beforehand if the character is supposed to be sleeping. At that point, the character pawn hasn’t spawned yet
Should one client know if another is sleeping?
// character
Super::BeginPlay();
if (IsValid(PC) && PC->IsLocalPlayerController())
{
if (PC->bIsSleep)
{
Sleep();
}
BeginPlay is too early to grab the PC locally.
Yes, If a player is sleeping, other players should see them in the sleeping animation
Clients can't see each other's player controllers.
bSleep should be a property of the character, and you should use an onrep. This can be much simpler and more robust.
So put sleep in the character and onrep it to play the anims
You can store the property on the PC initially or on the PlayerState fwiw. But the actual replication etc has to happen in the Character
Actually, I think I’m already doing what you said, but maybe there’s a mistake. Can you review? There could be a logical issue
Put it in the character
Why does the player controller care about pawn state? Also nobody but the owning client will see that.
How will the character know if it should be sleeping when it joins the game for the first time or reconnects after disconnecting?
void AMPGameMode::PostLogin(APlayerController* NewPlayer)
{
Super::PostLogin(NewPlayer);
AMPPlayerController* PC = Cast<AMPPlayerController>(NewPlayer);
if (IsValid(PC) && GetNetDriver())
{
PC->bIsSleep = true;
}
}
However you want. Why would player controller change things? Sleeping is a property of the pawn, not of the private player controller
First join -> sleeping is just whatever it's default is
Rejoin -> pull up the save game for that player -> set sleep on pawn based on that
You’re right, having this feature in player controller doesn’t make sense, but like I said, I couldn’t think of another way to get this info to the pawn
Alright, I’ll do it that way. If the problem isn’t solved, then I must be making a mistake logic. Give me a short time, I’ll come back
@dark edge I don’t know what the problem was, but basically the right logical approach (yours) was enough to fix it 🙂 Thanks a lot 🙏
and @thin stratus to you too 🙏
what is your exact issue?
@nocturne quail basically aniamtion lag on host watching clients. Guys above suggested me to add lines to DefaultGame.ini and animations are still slower on the host side. I suppose that the code just doesn't work without steam enabled in PiE and i should test in the shipping
you can test build, and yeah testing in editor not always gives the correct results
or start two clients in a separate process
also show a small clip recording of the issue, i think you are facing jittering issue
if yeah, you will have to adjust CMC
I tested the issue in a build and the problem persists. As a client, I experience no jitter or lag while moving, but from the host’s perspective, the animations sometimes run at almost half the expected speed. I also tested with and without modifications to DefaultGame.ini, but I didn't notice any changes in animation speed regardless of the ini settings. Any ideas on what might be causing this?
are you changing speeds of character?
yeah, if you want to I can send my .cpp and .h files
there is your issue, when you change speed the server or client desynced
how are you changing speed, can you show me that function?
The GetMaxSpeed itself is totally fine, i was writing about the speed of the animation(it's like 2x slower sometimes) not the speed of the character
speed of animation should derive from the character velocity
how are you setting it in your animation class?
you should have a speed and direction variable in your UAnimInstance class
and the speed and direction variables should be used in the animation graph connected to the blendspace
I am using locomotion. In locomotion i have state(walk/run) and i am setting the blend space according to the character velocity. To be honest i don't think that it's the problem. because before implementing the sprint system, using simple multicast, animations worked fine. and other people in this chat had the same issue after implementing client prediction thing
Get Player Controller (index) and all other nodes that ask for index shouldn't be used in multiplayer code.
they suggested me to modify DefaultGame.ini, but while testing i saw no difference of animations' speed at all
They are as slow as they were before modifying DeafaultGame.ini
when you sprint, your character speed increased and then the velocity also increased, if you used the velocity correctly your animations will never stutter
animations play rate is different thing, you can increase it in animation settings
if your animation is slow, you can open it and set this value to 2 and test
It seems like we are on different topics now. I have no issues with animations rate speed at all. The problem is that the host sees other clients' animation slower than clients see locally, that's the issue. it has something to do with client prediction. If you wish, you can read the chat.
Clients see each other's animations correctly as @thin stratus stated that's the problem
you said character speed is fine, animations are slow
Show the code that determines the animation rate
it should 100% be derived from character state
Just for sanity I would suggest printing the value you use to drive the AnimBP.
here it is. but, guys, it's working fine, as i said, only the host see the issue
But if that turns out to be correct, then the problem remains the fact that the ListenServer ticks the Pose through the RPCs. If they don't come in 60 times per second, then the Anim might look choppy. There isn't really a way around it, cause the CMC needs to tick the Pose to properly sync RootMotion.
what is setting and how the groundspeed variable?
I have added lines to defaultgame.ini that suppose to fix the issue. at least for other people in the chat it did
for me it didn't help
btw, that looks like something that could be just one BlendSpace with Idle/Walk/Run in it.
have you ever shared a video of what this looks like?
Cause you might be explaining something so vague that we misunderstand the problem and suggest the wrong thing.
it's like 2x slower from the host view
So the character walking in that video is the client?
Print the GroundSpeed please and ensure the values are the same on Server and Client.
yes it is. other clients see animation as the client that walks see. so there's no difference as you said above here
What's the FPS of the Client and Server in that video?
idk to be honest, but above 60 certainly
i tested and the values are the same
I have tested it also in the shipping build, and fps was fine. the animations are just slow from the host view. locally and other clients see them correctly
`[/Script/Engine.GameNetworkManager]
TotalNetBandwidth=960000
MaxDynamicBandwidth=120000
MinDynamicBandwidth=45000
ClientAuthorativePosition=false
ClientErrorUpdateRateLimit=0.015f
MAXCLIENTUPDATEINTERVAL=0.25f
MAXPOSITIONERRORSQUARED=6.f
MaxClientForcedUpdateDuration=1.f
ServerForcedUpdateHitchThreshold=0.150f
ServerForcedUpdateHitchCooldown=0.100f
MaxMoveDeltaTime=0.125f
ClientNetSendMoveThrottleOverPlayerCount=3
ClientNetSendMoveDeltaTime=0.0166f
ClientNetSendMoveDeltaTimeThrottled=0.0222f
ClientNetSendMoveDeltaTimeStationary=0.0166f
ClientNetSendMoveThrottleAtNetSpeed=60000
bMovementTimeDiscrepancyDetection=false
bMovementTimeDiscrepancyResolution=false
MovementTimeDiscrepancyMaxTimeMargin=0.25f
MovementTimeDiscrepancyMinTimeMargin=-0.25f
MovementTimeDiscrepancyResolutionRate=1.0f
MovementTimeDiscrepancyDriftAllowance=0.05f
bMovementTimeDiscrepancyForceCorrectionsDuringResolution=true
ClientNetCamUpdateDeltaTime=0.066f
BadPingThreshold=200
SeverePingThreshold=500
BadPacketLossThreshold=0.05
SeverePacketLossThreshold=0.15
[/Script/Engine.Player]
ConfiguredInternetSpeed=60000
ConfiguredLanSpeed=60000
[/Script/SteamSockets.SteamSocketsNetDriver]
NetConnectionClassName=/Script/SteamSockets.SteamSocketsNetConnection
ReplicationDriverClassName="/Script/TwinStick.RTS_ReplicationGraph"
ConnectionTimeout=80.0
bNeverApplyNetworkEmulationSettings=true
InitialConnectTimeout=120.0
NetServerMaxTickRate=60
bClampListenServerTickRate=true
MaxNetTickRate=30
KeepAliveTime=0.2
MaxClientRate=120000
MaxInternetClientRate=120000
RelevantTimeout=5.0
SpawnPrioritySeconds=2.0
ServerTravelPause=4.0`
this was supposed to fix the issue
yeah, i may, because it has nothing to do with the ground speed. The client predicted animations being played slowly only if host look at client, locally they play fine. you've said to adjust some of the smoothing settings now-a-days. so i did. clients see other clients' animations correctly, only the host sees them wrong and again as you said
There is only one case where Animations looks shite by default, and that's the ListenServer's view of SimProxies.
But Clients looking at other Clients shouldn't have any problems in theory.
so basically we have already spoken about it and you defined the issue
Right, sadly despite specifically changing the ListenServer Smoothing Settings on the CMC, there isn't much else I can suggest.
i did and unfortunately nothing changed
Hey. I’ve changed my previous setup where multicast was used incorrectly, as you pointed out. Is it correct now to use RepNotify and multicast only for spawning the effect? (I want everyone to see this effect).
RPCs for one shot events and rep notifies for states
if its an effect that must be visible while an effect is active you can use a rep notify
but if its a short visual effect for decoration you should use unreliable multicast RPC
Hi i’m developing a multiplayer game. Right now I’ve written a game phase system to manage overall flow. At the moment it works exactly as intended and everything runs fine. When game phase changes, a delegate is broadcast. Two things happen then: the character does what it’s supposed to, and HUD shows/hides correct widgets. For example, before map transitions I set phase to IN_LOADING, after map loads if phase is still that, I switch to IN_GAME. At this point loading screen shows/hides automatically. We always have phase info because it’s inside GameInstance, and this object never gets destroyed until game closes.
Here’s my confusion: having this info only locally feels like a security issue. Should I maybe remove this whole game phase logic? I can’t find a good alternative. Or how do I replicate this info in a way that won’t break during map transitions?
Is the change of game phase the updating of some state variable, and an OnRep being called?
if it's not it should be
But security isn't an issue as long as what goes from clients to the server is commands, not state
"I want my character to move there"
vs
"My character moved there"
Right now there’s no OnRep, it all works locally. Actually, thinking about it, replicating this info feels like it would just add extra unnecessary complexity
Replicating WhatPhaseTheGameIsIn is kinda the core bit of state everyone should agree on
that drives EVERYTHING
Got it, yeah, keeping this in GameState makes sense?
Yup
Just think about the minumum amount of state that needs to be replicated so everyone can agree on the total state of the game.
if it's Chess, it's Who'sTurnItIs, TurnTimer, and the chessboard state
Hi, using VOIP in 5.4 and there’s a really harsh crackling sound when talking in game. I tried with other mics too but got the same result.
Is there any way to get rid of this crackling?
Could be too low of a latency making a high CPU demand. Is that something you can change?
Im currently tweaking a few settings related to that I’ll let you know if it works
using UVOIPTalker?
Struggling to get my head around this replication question....This is all in blueprints... I have two replicated actors. One is stationary (actor 1), the other is moved by the player (actor 2). Actor 2 has a replicated actor ref variable. If I run GAAC serverside on Actor 2 to find Actor 1 and set the variable on Actor 2 when it is not in render distance of Actor 1, then that variable is valid on the server and invalid on the client, as you would expect given the actor does not currently exist on the client. If I set the variable when Actor 2 is in render range of Actor 1, then that variable is valid on both server and client, also as you would expect.
However, if I set the variable when Actor 2 is not in render range of Actor 1, then move Actor 2 into render range of Actor 1, the variable remains valid on the server but invalid on the client. Also, if I set the variable when Actor 2 is in render range of Actor 1, then move Actor 2 out of render range and back in again, the variable starts as valid on the client, then becomes invalid as Actor 1 goes out of render, but it does not become valid again when Actor 1 is in render again.
So the instance of Actor 1 on the client is destroyed as Actor 2 leaves render range of Actor 1, and a new instance is created on the client when they enter render again, but that connection between the server reference and the client reference is not remade? Is that how it works? And is there any way around it?
yes
Maybe the wrong channel but still related to multiplayer .. Is the order of BeginPlay() for level actors deterministic - i.e BeginPlay() is always called on level actors in the same order each time? And if so, is that also true for Clients - that the order of BeginPlay() for level actors is the same each time, and in the same order as the Server?
No. Don't rely on BeginPlay order
Even in single player - BeginPlay is not deterministic
Ok thanks! My use case is that I want to randomize some attributes on level actors, using RandRange() etc .. and I would like to be able to use a single seed to do it, giving the same results each time. Do you know of any other relatively simple way to do that?
Have the seed set in the game state. The game state is what calls begin play.
But if it is a replicated property, then you need to handle that as well
Yea so Ive currently got the seed synced properly but not sure about how to actually use it in a deterministic way on all the relevant level actors. How would that be done in single player?
Lets say I have a level with 10 flower pots in it, and I want to randomize which pots have flowers in them. And I want it to be the same every time when using the same seed.
But you just get the seed in begin play and then feed it into that.
Yea but you're saying the order of BeginPlay() of the actors in the level is not deterministic across runs? So I need to find something else to use? Constructor or such maybe?
Why does the order of BP calls matter? Are you changing the seed each call?
you either have the seed made on the server and replicated to clients, and each client runs w/e logic you have with the seed
or the server makes the seed and generates w/e is needed on server and replicate the results
if you wanted to randomize how many flower pot you want to fill with flowers, i would have the server generate the random result, then for each flower pot actor set a replicated "has flower" boolean, and on client when its replicated you set the mesh or W/E (just and example there are other ways to achieve this)
there is also optimization that can come in play if you had like hundreds or thousands of flower pots
Yea and that's the part that I'm wondering if it can be done without replication. Since the server and the client are using the same seed, if the initialization of the level actors would be deterministic then they wouldn't need to replicate anything.
We're currently replicating that state using InitialOnly, but I want to get rid of that.
If the seed is hardcoded in the GS, then just get that
BP order does not matter in this case
seed isnt static here
Because the "randomization" is deterministic. At least it should be if Epic did their job right.
each new game changes the randomness
What Fishy says.. each time a flower pot uses Rand(), it would update the FRandomStream state for the next flower pot using Rand() .. etc
Oh - then in that case, it needs to be done via server only
And then server replicates the state down
Well - you could build your own queue
Thanks for the help guys, I'll do some more digging! 🙏
I could maybe use the "global" game state seed combined with a calculation of something deterministic out of the level actor position, or some other known attribute of the actor, unique to each instance.
Their name
Assuming you're talking about staticly placed actors
Yeah
Thanks a lot!
Its not multiplayer tho this is all local for conneting and joining
i have a basic multiplayer question i think? When spawning projectiles, I know you need to set the replicated flag to true, what i am unsure about, is do you also set the replicated on the projectilemovementcomponent to true? Or once the projectile spawns, it is up to the client to update the projectiles position on their end?
Only replicates is needed.
Personally I don't replicate the projectile itself. I have each proxy fire its own projectile.
The simple answer to the simple question is... Only the projectile actor needs replicated.
The real answer to the not so simple question that seems simple... Is that it depends. 😄
Simply put, yes. If you replicate the projectile. It'll arrive on client and shoot same as it was on server as long as it's initiated at the same place and same direction same everything etc etc.
The issue comes in when you factor latency. The server sent the data for when it spawned. The client got it some time later and on the server it's already moved several times and may even be dead. Client gets the actor and spawns it way offset. Traditional lag situation.
If you're fine with that, it works. But you can also do some timing simulation interpolation on the clients. And it's also important to note that the client's side should be visual only. Let server apply damage, multicast hit effects, etc.
Client shoots locally, RPC server to shoot.
Server does its own calculations for velocity, then fires, it passes its values to sims via multicast.
Sims execute the MC and fire a local shot on all other clients.
Use Base Aim Rotation and Camera Manager -> Camera Location for your calculations.
100 percent agree. I think i am fine with that for now.
if you do this, then you do NOT need to set the projectile's replicate flag right? EDIT: you already said this, my bad
Correct, in my setup projectiles are not replicated. Only simple data (few vectors, normals) are sent via RPC.
I have a question about unreliable RPCs.
I have an unreliable RPC send every frame on tick in character. According to documentation by default it's supposed to be send at the end of the frame in the next net update call, but most of my packets end up with 2 instances of that RPC. Any idea what is this about? I checked the movement component RPC and that is send only once...
Make sure you are testing under real world circumstances: editor preferences > network emulation profile (average / bad)
You might find the delay unplayable.
500ms (min/max) in/out with 5% loss is a solid standard.
Unless you implement kicking for bad connections.
5 percent packet loss? pretty sure this is just completely unplayable, in legitimately any circumstance
don't think that's a solid standard
and 500ms in and out, would be 1000ms, if not mistaken, which if you're doing that on client AND server, i believe this is basically saying 2000ms then
if im understanding correctly, that is never going to playable and should not be used as a standard for testing your game with latency
Wtf? That's going to be completely unplayable in any circumstance
The only thing you could test with that is ensuring you don't have any race conditions
lmao, glad i wasn't tripping on that
Battlefield series allows for 500ms pings and on a regular you'll see 300+ in the scoreboard. Bulk you'll see 100-200ms
PuBG you get oor's using VPN from China to USA (250+)
the 500ms test is to check networking, not playability
CMC applies an assload of network smoothing. high pingers don't warp on their end
fair for testing extreme conditions, but again, the 500ms (in/out) would be 1000ms, and if on both client and server then again, it will double if im not missing something
yup 1 sec delays on network alone, then ticks, game thread, render thread, clientsendmovedelta delays etc
the 5p packet loss is actually where it's unplayable tho
100ms w/5% loss is almost a standard in it self. Shitball wifi.
100 is 1/5th of 500 so on that i agree. but 5 pecent packet loss? no, i dont think that's standard
if you have any packet loss, it's bascially going to "break" the experience
it does and can happen, but 5 percent is saying 1/20 networked events are dropped , and i feel like no one would play a game like that
assuming move events are part of this 1/20, you're going to be rubberbanding insane
1-3% is normal will most games. It's not continuous. Playerstate ping/loss is avg over 1 sec duration
1-3 percent is again, half - 1/5th of what you said with 5 percent, but i still am not sure i would agree to that
either wya, it's good to test with bad conditions
if plays good w those settings, you're all good lmao
intermittent 5% is playable. just rubberbanding here and there.
The 500/5% is a networking production test.
If a kid gets a spike how is the networking going to hold up.
what's the impact on OnRep, Reliables etc.
It's not saying you have to make your game playable at 500/5% for christ sake.
intermittent 5 percent, isn't really 5 percent then. 5 percent means 5/100 , meaning it's a deterministic level of dropping, which i argue is never the case
so, intermittent 5 pecent is more like .1 percent
your origignal statement was bascially saying it's a solid standard for testing with latency
i disagree with that , and we have come to further understanding what you meant
Jambax says a really bad connection is around 200+ ping and 5% packet loss. They worked on Hell Let Loose, so sounds reasonable.
Just got a random flashback to when we were tweaking our "your connection is bad" HUD indicators
I just permaban if a player drops a packet
You Only Drop A Packet Once
Sorry I used the term "Standard", while I should have said "Good Practice"
It's "Good Practice" because it helps identify edge cases, replication problems such as jittering/rubber-banding, UI and Feedback. It's also good for identifying issues with lag compensation and client-side prediction. How do these systems compensate for network delays?
no need to apologize, we are all learning, i was only pointing it out as a bit extreme so that someone isn't reading the chat thinking that if their game doesn't play at 500ms (in/out) on both server and client, with 5 percent packlet loss that they don't tweak out internally and think they are terrible and their game won't play in real circumstances
Also forgot that it helps identify exploits related to network tampering.
i totes feel the approach and now that you express it further of course i see the needt o test extreme conditions for those edge cases like you mentioned
500 is just for development aspects.
i have this on at all times, i consider this to be "my standard". like this would be potentially the majority of expreicnes
but it doesnt' handle those extreme cases like you mentioned
i can test with 500/5p packet loss anytime tho, and typically, it's just unplayable , but yea making sure they can at least get to the main menu / spawn in, etc. is good lol
i like it, but if you were to switch that to "both" instead of just client, it would be significantly worse experience
but assumig server is solid, it makes sense
Once an iteration is done I'll run the gambit. Great, Good, Bad (client)... then Great, Good, Bad (everyone)
I do highping and 0 loss testing as well.
I like having a granular views of metrics.
Been banging around with UE since 2000' UE 2.0
i like your approach and now tha tyou explain yourself a bit more, it makes sense. was only ensuring someone didn't get a wrong idea lol
👍
Lag Switch testing is the end all be all though.
Then writing code to detect and flag it.
i really don't tend to worry about cheating that much, more or less "fair" but if someone is doing all that and cheating, they are weird
Player base is going to fully let you know
Should see the server-side scrutinization I put on firing weapons.
what joy does someone get from cheating in a video game , still to this day makes no sense to me
No clue, but it's a rising plague.
true, but if my game got hit with that plague, i'd probably be already celebrating the sucess the game has acquired
DKOM is the king these days and very hard to detect.
then i find them, and ban them for life
Detection and proof is the key to that game.
If you have a player with insane stats, but you can't detect the cheat what do you do.
yea, not a problem i face but i imagine if i find a cheater even slightly, they would be banned immediately, zero questions asked
Just ban based on stats
you pose a good q, at first, i'd hope i actually know most of the players, but again, if game gets big and you can't possibly know all your players then thats where cheating becomes something that would be hard to manage, but for me, if any detection at all, you're banned, and can appeal to the court of MAiWORLD for unban
I am wanting to add single player to a strictly multiplayer game.
I am early into the project, but have coded all of my critical logic to assume the server is dedicated.
I think I can add single player by having the player open level as a "listen server"; but before I re-tool all of my "Is Server" checks, is there a better way?
I write SSAC as I go. I make it modular so I can yank aspects as needed due to server load. But I design/develop with a fundamental understanding that you cannot trust clients or any of their data.
First thing you need to come to terms with is once you package SP that utilizes all the things the server would you've given every would be cheater a huge look at the server code.
Don't like that..
Best option here is to create all new custom classes for the SP experience.
It does increase the work load and the final projects file size, but it keeps SP and MP 100% separated.
Think of all the cool stuff we could do in a world without cheaters. Appreciate the answer, thank you.
@crisp shard https://dev.epicgames.com/documentation/en-us/unreal-engine/using-network-emulation-in-unreal-engine
yea i agree now that we cleared up the purpose. "extremely harsh conditions" is accurate for those numbers
What you can do for your IsServer checks is to instead check HasAuthority since that (typically) means the server in MP but will also work for SP.
As far as testing it, just running it Standalone is enough.
I know that doesn't answer all of your issues, but maybe it helps a bit 🙂
How can i replicate correctly launch character?
In SP the client is the server.
Works just like Host in the Listen Server setup.
if you call it on server all clients should see it
I need to calculate direction on sv too?
Server always does its own calculations. It's the authority.
For there to not be a hitch and be predicted, you need to at least do the exact same thing on server and owning client
if you don't need to predict just yeet them on server
For character launching you want the server to handle it. Predicted movement requires Ack and Correction.
multiplayer dashing will not work like this
Why not?
I have to make all logic on sv, right?
Big old complicated reasons
https://discord.gg/uQjhcJSsRG
In this video I am introducing a series I will be making which explores the character movement component and how you can extend it in depth.
0:00 Intro
1:00 What is the CMC?
2:00 Do you need a custom CMC?
5:35 What does the CMC provide?
7:10 Outro
You need C++ to do a proper networked dash without rubberbanding
basically the act of dashing needs to be encoded in your saved moves, basically dash has to be a movement mode or something along those lines
So, it's impossible to do it on bp?
You can do SOME trickery in BP but it'd be trivially cheatable and idk if there's a way to do dashing with it
I know a way to do a BP sprint but it's client authoritative
Correctly, Yes
You can Hack a dash, but it opens up issues with potential correction, and other clients not seeing it correctly if at all.
If you just launch character on server it'll "work" for some definition of work
I need to create a CustomMovementComponent with sprint, dash,etc on c++??
I've worked with Unreal for over 10 years and I've never gone down the custom CMC route
need to do it soon though
might be really simple to find a plugin that's done all the basics for you if time is of the essence
idk why dash and sprint aren't in stock CMC tbh
You can do client-side prediction sprint pretty straight forward by changing CMC movement speed and setting an enum state. Then RPC server to try, if it cannot, then correct. rpc owning client to update its sprint state etc.
go do that with latency
You'll still correct as there's a set of moves where you and server disagree on max speed
Works fine on my end with high ping testing.
Better to go C++ route, but it does work.
Could you not just increase the max walk speed and play an animation to make a dash?
In that case you have increased the walk speed but the server doesn't know it at that timestamp so you end up correcting
you can maybe cover it with a dash anim
basically "don't walk during the time at which there's 2 max speeds floating about"
play dash anim instead
Seems like the easiest way
A really easy way but it's vulnerable to cheating is just to clamp inputs
don't change max speed, but clamp inputs when not sprinting. It'll do the job and be butter smooth, but is vulnerable since the client is being trusted to send small inputs when not sprinting
the option to disable all client correction is there... you don't need to worry about speed hacking in a co-op game without a competitive side to it
I have a component with a non replicated array of UObjects.
These objects are added to the component list of replicated SubObjects, have a StableName, and are created in the component's begin play.
I have a struct in the Object class that is marked as replicated.
If any replication of that struct happens after the client created all the UObjects, replication works fine.
But if replication happens too soon i get LogNet: Warning: UActorChannel::ProcessBunch: ReadContentBlockPayload failed to find/create object. RepObj: NULL, Channel: 4.
Is there a better place to create those replicate objects other than BeginPlay?
Edit: InitializeComponent does the job
I don't think that should be happening
Are you trying to do something on the client in beginplay on the actor or something?
If so, you probably need to wait for the client to receive the initial replication of the uobjects from the server
The objects have stable name so they were created on both server and client at begin play (using InitializeComponent instead fixes my issue).
Then after creation, an rpc was sent to the server to modify the struct in those objects (or just modified for the listen server).
Clients would receive that error for the objects on the component owned by the listen server's pawn
Is there a reason you are using a stable name as opposed to just creating them on the server?
If they are stably named, I don't believe they even need to be a subobject
Does someone know if Replication Graph and World Partition are working together?
Because i know already what objects i need. So there is no reason to have a replicated array of those objects when i can just spawn them locally
The array is fixed size and the objects in the array are always the same once the component is created
Up to you to make them work together
I'd imagine they would but I also wouldn't be surprised if Epic stops supporting Rep graph
Well, actively working on it at least
Iris and all
FN is on Iris now and Iris doesn't need rep graph
I wouldn't worry about that though
Sure, thats the goal, but it's not yet production ready - so not an option for now
Ah sorry I wasn't suggesting to use iris
Maybe I am wrong but it feels weird to stably name something that's a subobject of a replicated component
No problem - thanks for the answers. About WP and RG: so there is nothing known that both are incompatible - like one would break the other etc.?
Well, replication graph is entirely on you to setup. I can't immediately think of anything that would prevent them from working together
Thanks you! 🙂
Hey! We are trying to have a replication graph + world partition at once. We want to fit X players in the same dedicated server, all playing in individual-level instances without interacting with each other. We already have a setup (Actually a tool) that places all these level instances in a grid during editor time. Still, when launching the ga...
Found this thread, but the one who answered didn't tell why RG and WP aren't working together - maybe he is wrong...
Level instances don't replicate. You have to manage them loading in on clients
And actors inside of level instances can't replicate unless the level instance is stably named between the server and client
It isn't too bad to do
I used an actor as a level manager that holds an array of replicated UObjects.
These uobjects hold information about a LI like what level it is and its exact instanced name from the server.
Then when the uobject replicates to the client, have the uobject load then LI with the provided name.
Replication will then work
If you want different levels loaded for different players it would work differently, but I think rep graph would actually make that easier
Just change the relevancy of the UObjects
in an open mp world, and on a solo quest, would spawning enemies locally for that particular client be bad? i suppose i could do this normally on server, but i find many issues with that as well, where as the main issue i see with spawning the eneimies locally for the player on quest would just loook weird to other players seeing it, and also would perhaps lead to "cheating"? not sure if there's a method to allow what im looking to do, which is essnetially have solo based moments in the mp world. i have local client based objectives for interactions/locations/etc, but that's easier to validate on the server where as the enimies health/dmg would have no easy way to validate it, unless i just send like an int/float amount to the server and once a certain =number has been reached it would "validate" the enenmy being killed. not sure if im under/over thinking it, but any thoughts may help
Have you considered configuring relevancy?
I think replication graph could be helpful with that, buuuut I've never had to use it so it's just a blind guess.
ngl, i've never used the replication graph, unless it's something i've used without knowing
this is epic's plugin used in fortnite
though, I don't think it will work for you out of the box, from what I know actors have to spawn on server, they just won't replicate to other clients. That means the clients could interact with those actor by accident, you'd probably have to write some more logic around the system to make sure unrelevant client will not be able to affect those actor in any way.
yea that wouldn't be too hard, and i could spawn them locally like i mentioned but if server, yea i dont think it would be too hard to make it only interactable from the one on the quest, but the issue i see with this is the build up of enemies on server instead of just having the variable logic happen only for that client
so if like 10 people were on the quest, if logic was to just spawn eneimes, then server could have potetnial to have like 10x the amount of those enemies
im sure there's a work around for that as well, ubt yea this is why i was thinking that locally would just be easier just wouldn't have any way to really validate the actions
I don't think you can move around that, if you want to be sure clients won't cheat.
yea kinda what i figured
will say, it's not the most important thing to validate, as really the solo quests are more for fun rather than ensruing the client is doing something correctly
said it before but if you cheating in a solo quest, you mega weird!!!! lol
Cheaters probably don't care that you think that XD
i'd be willing to bet they care about very little if they are cheatin in a video game
In the end if your enemies won't be super expensive it shouldn't be that bad, all the MMOs have instanced dungeons and they mostly work.
i would actually be interested in instanced parts of the world i've never done it tho, would require some learnings
This would be a better option, I just thought you did not want it.
i've just never done it, that would be the best option as it would check all boxes. i've just never done it, would not know how difficult this would be
walking around the world and seeing x number of people fight with invisible enemies will break immersion
i'd rather them not have to go to a new level
yea no doubt
if the level change is a problem you could create a separated instance somewhere on the level and move player there. But again this is something I've only read about and I have not tried it.
hmm yea , that would work as well. essnetially like sapwning a whole level (small of course) like way under the map or something
that would work for sure in theory.. could have server spawn the "level" locally for that client and then can validate everything on server as there would be no other players around so wouldn't matter at that point
yeah something like, in this case probably the aforementioned replication graph would be helpful
will def look into that
thanks for the chat and thoughts
AI should be spawned by the server.
You can use NetCull Distance to help limit replication to other clients if needed.
Quest map instances should be on the same plane (Z axis) as the main level.
Teleporting to those instances should be handled by the Server as well.
How much memory the AI eat on the server is dependent on their complexity (behavior trees, EQS etc).
all good thoughts, hell yea. when you say quest map / level instacnes should be on the same plane (z axis) as the main level, i get what you mean literally, but im curiuos as to the why for that ?
So you can utilize the persistent levels atmospheric settings. Lighting, Post process, Fog, Sky etc.
If you go below the main level you run into lighting/shadow/fog etc issues. Unless you're doing interior/underground. Those can be below the map.
You can use Occlusion volumes to Hide these areas from the main level.
ahhh yes that makes sense. my inital thoguht is that most of these would be interior / dungeon esc, but in the case where i would need to be outside that's good to know
hmmmm this in general might be useful to do for certain things i already have, never thought about the obviousness of utilizing an occulsion volume to "occlude" things that i don't want someone to see from far away
One other note. For underground areas keep them close to their main level entry point. So like right below the landscape etc at the entry.
This will help take advantage of WP pre-loading. Otherwise you may have to disable CMC (movement mode none) during the loading process so the character doesn't fall through an unloaded floor.
not using WP in my case (perhaps i should be) but it's not quite THAT large yet, but a good point to be aware of. i have "cave" entraces that are esnsnetially that, a hole in the landscape and you go "down"
I'd totally use WP. World Composition is inferior.
this ahs been on my mind, but how much would it effect the world if i did switch to WP? would it break things or like would i need to significantly change how things are working ?
It's not that bad. Make a copy and transition that level and test it.
that's good idea for a test
So, I have a component that is basically a master component. Its a skeletal Mesh Component that is given to the player on event begin play. I have it set to add the component to the player on server. The first problem is, the first player to connect can see that the other player is holding the weapon with the proper animation. But the second play just sees the other player is the default idle stance with the weapon attached to their hand. The second problem I am having is replicating the bullet projectile. The bullet is spawned at the muzzle socket of the skeletal mesh and then rotates to the end of a line trace in the middle of the screen. The line trace exists so that the projectile moves to the middle of the screen where the crosshair is. The code to shoot is in the component. But I have a blueprint interface that is run on the server in the player blueprint so that I can have the code to shoot in the component that is simply called whenever the blueprint interface message is executed as apposed to having the code in the player blueprint. I have tried spawning the projectile on the server, on multicast, on the server and then multicast. But no matter what I have tried, the projectile works just fine for the server player, but immidietaly calls the "event hit" when spawned by the client player. Also whenever the client fires, it gets called twice. I have a print string at the end of the code that says "Hello" and whenever the client fires it says hello twice. Even when I am just replicating the Blueprint interface on server and none of the spawning code is replicated. I am having a lot of trouble with this so help would be appreciated.
Skeletal mesh components do not replicate.
You need to spawn an actor that is set to replicate, then attach it to the character.
This is done on the server side. Replication system will handle the rest.
Set whatever replicated states you need on the server as well.
For projectiles you RPC the server to shoot. The Shoot event would call the Interface event.
Projectile class has to spawned per shot and set to replicate.
You'd also multicast to Sim proxies to have them do a local dry fire... animation and fx only.
so
I could have it where when the player spawns i spawn an actor that just gives the player the component?
Only on the server side
yeah
Yup
You could wait until the client get the character class and on begin play, for Autonomous Proxies only, RPC the server to give you the gun.
yeah
how do i
yeah How would i wait until the client gets control of their character?
animations dont run by default on dedi server
so having the server shoot will be complete wrong if its relying on skelmesh
if its listen server, maybe best to show what your doing
cause your probably doing something fundamentally wrong
GM spawns characters (default pawn, gm settings) as soon as a connection has been validated... roughly when On Post Login fires.
Replication system sends you an RPC to spawn a copy of the character locally... this is all done under the hood.
Using Begin Play you'd run a conditional branch ( (Is Server NOT) && Get Local Role == Autonomous Proxy ) -> RPC Server
Server event would spawn the weapon class and attach it, then set any needed states.
Generally you wouldn't, just optional for new devs until they wrap their heads around proxies, rep system etc,
3 Views and all that jazz
im such a bad programmer
im trying to make a spiritual successor to quake
just
lemme ask you this
@obsidian ermine What would be the best way to create a weapon system for a multiplayer game, where when the player spawns they spawn with a default weapon. and then when they walk into other weapons it replaces the current weapon they have
the way I was trying to do it. is when the player spawns they are given a default component. and when they walk over the pick up actor it just changes all the stats, weapon model, sounds ect
In the character class you need to first thing define its role. Server, Autonomous (client), Sim
From there you can assign specific actions/logic etc based on the role.
For the server I'd have it spawn a weapon class and attach it.
would you have the weapon be a component or an actor?
ACTOR, Always and Actor.
Functionality in the Actor can be Actor Components.
i see
Okay I'm gonna take a break from programming for a but but When I get back on the editor ill start implimenting some of this stuff and let you know if i need help @obsidian ermine
👍 I'm on the forums. I've covered this there and shooting mechanics, replication etc... seems like to death.
I'm dealing with an issue where a character using NavWalking has two different positions on client and server. It's getting replicated down to the ground, then NavWalking tries to raise them back up to the height of the navmesh. Has anyone seen anything like that before?
Nope, Never had this type of issue with AI.
This is a big project so I don't know what a previous engineer may have changed.
Yes. I've confirmed that the issue is caused by replication.
Can you make a new simple map with a new nav mesh and run it?
Starting to sound like a Nav mesh or HLOD corruption issue.
rebuilding navigation might clear it.
for giggles make sure the AI mesh is positioned correctly relative to the capsule component.
Yes, it's not a mesh issue. It's the actor's root location that's changing.
I have the client include the navmesh already.
Untick hidden in game for the capsule
See if thats floating as well.
Yes, it is.
I tested in a blank project. NavMeshWalking has the character hover a little bit over the actual terrain.
wild.
draw a debug sphere at the actor location
if that's correct then the relative of the capsule has been changed.
beyond that I'm stumped.
Does anyone have any thoughts about how to implement a system where the player is constrained by a rope. E.g. climbing, abseiling, etc.
In broad terms, how might we go about integrating physics constraints with player movement component?
a Chained Together type constraint would be ideal, where each end could be attached to a player.
Wondering about using AActor::SetReplicates() vs AActor::SetNetDormancy() .. If I have an actor that should pause its' replication for some time, which one of those is preferred to toggle back and forth?
And if I have an actor with a single replicated property that is using COND_InitialOnly .. is the actor still being checked every frame for replication, or only when a new connection happens? Is there any relatively simple optimization that can be there?
Dormancy should be the way to go
Not sure about that, but you can always make it dormant
But if its dormant it won't even sync initially to late-joiners?
I wonder if DORM_DormantPartial would handle late joiners
another cheese thing might be to just crank down its net update rate an insane amount when in the "dormant" mode
Yea was thinking that too but it's not recommended to use it.
ah yeah nevermind then
honestly might be repgraph time unless you want to move to iris and make a custom filter/prioritizer
I would say at least check to see if dormancy isn't sent to new joiners first though... you should be able to test late joiners in PIE in with the new settings in newer versions
Hey, how are you? I’m working on an Unreal Engine game. I need help with something: I’ve set up create and join session locally, and it works on the same network. But now I want to make it so that the game can create or join a multiplayer session from any network.
Now you need to use an #online-subsystems, such as Steam, that provides that functionality.
You might get away with push model for that
does anyone have experience with sending client side input to a server side actor? for example, I have a lever that has an amnesia style interaction where the moving the mouse while holding will pull it back and forth. Works perfectly for the host and replicates to the client, however, I cannot seem to get the client's input interaction when they pull it. I am passing the values through a server RPC to the actor, but it always grabs 0 or null
" I am passing the values through a server RPC to the actor"
be specific about what you are actually doing, you need to not leave out which actor is doing that and who owns it
rpcs from the client to server only work from actors they "own" which will generally be their pawn, controller, and playerstate
also sending a reference to an object which is not replicated or a stable named asset will not resolve
as for how to do this nicely... I would say it might be a bit of a doozy
My first guess would be to send the sort of desired target rather than the raw rotation as the raw rotation unless you smooth it on the listen server
which I guess might already be done
if it looks fine as-is you might not need to go crazy though
also one thing that might be weird is that when they are moving it locally it might be fighting incoming replication
it might be useful to have the local client using it kind of override incoming changes to it moving
I don't really know how the lever is moving and sending that I guess
I am calling the RPC from the character and checking that it is locally controlled. The server RPC is on the server side actor (which is my lever). I am sending replicated variables to the other side, but thats a good point, maybe the replication is overriding it. Yeah it probably won't look too great at the moment, I just hopefully want to get it functional so the client itself can use it.
Yeah its a bit difficult to explain and understand over text. this video can at least show how it should work in game
and I realize this isn't the prettiest way but I was trying to get it to work, here are screenshots of the calls for the RPC and the RPC itself inside the lever actor
Hey, maybe someone has some tips for me... so far all my Multiplayer staff is working (I know experts may see problems but it is working), since begin of the year I skipped to c++ based approach. To my Problem. I working on a justom Jump mechanic which is driven by curves and some states (the animations played are based of different values, the Jump animation of Lyra was a "template" of it for me). In Singleplayer its not a problem also without network emulation its not a problem but with or as packaged build on steam the client jitters, if I understand it correct this comes from server corrections. Maybe someone has Tips for a approach to avoid it (currently I test with RMS, but basicly it seems that I need to completly redo my logic for this) its a coop game. The Jump for itself is more arcade like so I want to tweak it and link for example hold time to it and also give the player a small amount of control during jumping.
i have a variable name bSprinting.
SprintPressed and SprintReleased update the variable and increase the character speed
on server, it's working
but not on client
now i'm trying to replicate sprinting
variable
Hi, I have been trying to work out how a Mario Party style system would work (Where the start of game 4 players all have their own dices and jump to stop them) I have the dice spinnign and the server can stop his but the client cannot stop theirs I have this function atm
which takes the player controller in and then compares to the player controller owner of the dice and then sets the dice to SpinEnabled (False) as shown.
I thought because the server would update the SpinEnabled bool (so the client doesnt modify it but the server does it would auto know which controller's rotation component to disable?)
Execute on server I was under the impression that the server would process the request from a client and know which client has requested the server action but it doesnt seem to either
A: Know which controller has requestyed the action or
B: Which Controller owns the dice actor
I am obviously doing something wrong but not sure how to fix.
StopDice function is inside GameState (Which gets called from Character blueprint from pressing jump) and OnRep SpinEnabled is inside the Dice Actor.
There doesn't seem to be an ID of some kind (name, guid, etc) for actors placed in a level, that is stable across multiple loads of the same level? Is this correct?
This sounds exactly like the problem I’m having as well. Do you maybe have a video of the problem?
Sadly I don’t have a solution, but I’ve been stuck on this for weeks now, and since it even happens on a dead simple minimum example, I’m starting to believe it could be a deeper issue within the engine.
Was able to fix it.
I want to make sprint only in forward direction
45 to -45 degrees only, not sideways (90 and -90) or backwards
Hey guys, I have some errors in my code that don't affect gameplay and I'm not sure how to go about fixing them. One involves one of the UI systems and the other has something to do with spawning players in.
Client jitter on moving object. anyone know how to stop this jittering? I attached the blueprint for that moving object. Any fix?
does anyone have a good guide/documentation on integrating steam with eos? (i have eos working)
Don't replicate the movement of the platform. Replicate (repnotify) the Forward/Backward State (enum) and have OnRep function call Play from Start, Reverse from End.
Server side instance will determine its state and set it.
can you elaborate a little more, im new to ue5
I can DM you a tutorial I did.
sure that will be so helpful
Sent
Exact same principles as working with Doors and Elevators.
You send States via RepNotify and each clients copy of the actor executes the new state.
Open, Close... Up, Down... Forward, Backward
I assume the Platform has ReplicatesMovement enabled.
Just so you learn why the jitter happens, it's not necessarily the Character that is jittering, it's the platform, because the ReplicateMovement will just set the local Location/Rotation with what gets replicated, and you ain't gonna get 60 replicates updates per second.
If you move the Platform locally, after the Server tells you to start moving it, it will update per frame and be smooth.
They won't be in sync, but the CharacterMovementComponent can handle "based movement", which communicates the Location of the Characte relative to the "base" (the Platform). You will potentially get a small correction upon landing/jumping off, depending on how out of sync they are.
Unfortunately not, I've made some progress... I need to say I'am not a pro at Network stuff... but I used the InputDir from Pawn Owners Input (PawnOwner->GetLastMovementInputVector().GetSafeNormal2D();) to change the directions and also manipulate the jump behavior now I did a bit different approach based on the Acceleration (FVector InputDir = Acceleration.GetSafeNormal2D(); ) and the glitches are gone... I think that some data from my first approach are not completly communicated between server and client and so it comes to corrections
LastMovementInputVector never makes it to the Server.
so this seems the problem
The Server will have it in the form of InputAcceleration (the normal of it).
Client will have the same during a given CMC tick. So that would be the better value to use, yes.
this stuff takes me about 2 days 🥲 this was very frustrating xD
now I need to retweak the jump timings / curves a bit
It's also important to use the same variable for Server and Client and to keep in mind that some values might be rounded for the Server to save bandwidth.
Acceleration gets manually rounded by the Client to match the Server's version.
But if you, for example, compare the ControlRotation, you might get a less precise version on the Server.
i was using replicate movement
ok, the movement stuff is tricky hm
Sent him a tutorial I did that explains the server tick update frequency (delay) and Ping.... causes the jitter.
Flip book updates + correction + interpolation
My platform, your platform or anyone else's is never synced, just as character position and movment is never synced.
Pings, loss, connection jitter etc.
Yeah, but the Platform doesn't need to be 100% in sync. That's what Based Movement is for.
The jitter comes from the ReplicatesMovement part.
Which is what you more specifically label update frequency and ping.
Don't get me started :D
Tut I sent covers that. Just replicating enum States... Up, Down and having the Onrep function execute.
Server sets them.
Yeah I get that. I don't have access to your tut, so just adding info that wasn't shared here. Also for others that are reading along.
So far I only want a custom Jump behavior because I dont like the ues default... but I had no idea how complicated it is... I know my network stuff isnt perfect but all the stuff so far worked, which makes me kind of proud xD
Have you bothered working with CMC's jump settings?
yeah I test around a lot, maybe I didnt spend enough time into this. but I did alot during the jump implementation (about 2-3 weeks) and its still not polished and my custom stuff feels the best for me so far
Hi, I was developing my game on LAN with OnlineSubsystemNull. Now I need to integrate Steam, and later EOS too. Do these mean very big changes? What will I basically need to change? For example, how should my DefaultEngine.ini look?
now the only problem is that jump on client feels a bit different which may comes from differnt delta time @thin stratus thanks so far 🙂
Yeah, you are usually expected to handle most movement inside your own CMC, not outside of it, with exceptions for RMS and things that leverage existing movement logic that is already "in sync" (such as reacting to OnLanded).
A little stuck at the moment, not sure what is going wrong here
Basically I'm trying to use Velocity based character rotation (similar to ALS) but I'm having trouble getting it to actually replicate the mesh rotation to all players (it only works locally)
I'm calculating and replicating the target Rotator via RepNotify (and print statements confirm proper replication) but the actual rotation of the mesh doesnt seem to be replicating at all.
https://cdn.discordapp.com/attachments/1184696424038940702/1417921046186819615/2025-09-17_13-09-36.mp4?ex=68cc3d61&is=68caebe1&hm=b3324d53ed40f3b0aeacba949dbdfe8502a37441d380994b263e9e417cbc12c3&
This is the function on the player that calculates the target rotation, and also the RepNotify
i have also tried getting rid of the lerp entirely and setting the rotation as is, but that still doesn't fix the issue
void ASoldierCharacter::MoveForward(float Value)
{
GetCharacterMovement()->MaxWalkSpeed = (bSprint == true && Value > 0.f ) ? RunSpeed : WalkSpeed;
if (Controller && Value != 0.f)
{
const FRotator YawRotation(0.f, Controller->GetControlRotation().Yaw, 0.f);
const FVector Direction(FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X));
AddMovementInput(Direction, Value);
}
}
void ASoldierCharacter::SprintPressed()
{
bSprint = true; // Set for client
Server_SetSprint(true); // server
}
void ASoldierCharacter::SprintReleased()
{
bSprint = false;
Server_SetSprint(false);
}
void ASoldierCharacter::Server_SetSprint_Implementation(bool bSprinting)
{
bSprint = bSprinting;
}
I want the player only to move forward (including forward diagonally) but not sideway or backward
Isn't that whole behavior built into the CMC by default?
/**
* If true, rotate the Character toward the direction of acceleration, using RotationRate as the rate of rotation change. Overrides UseControllerDesiredRotation.
* Normally you will want to make sure that other settings are cleared, such as bUseControllerRotationYaw on the Character.
*/
UPROPERTY(Category="Character Movement (Rotation Settings)", EditAnywhere, BlueprintReadWrite)
uint8 bOrientRotationToMovement:1;
Or is the point that you want to rotate the Mesh instead of the Actor?
it is, yes
however, im rotating the actual character mesh
the character movement component is working perfectly
Where is that OnRep/Replicated Property located?
i feel slightly dumb lol
turning that on fixed it
you are literally a life saver
although im not sure how ALS does it, since it does not use OrientRotationToMovement
it handles it all internally
all of this logic is happening on the player
If you want this to be guarded against cheating, you would handle this in your own CMC where the acceleration/velocity is calculated on server and client and then clamp it.
If you don't care about cheating, then clamp the Direction vector you pass into the AddMovementInput.
There are reasons for rotating the Mesh vs Rotating the Actor, especially for Turn In Place.
Most peeps use the Mesh. @grand kestrel made something that rotates the Actor iirc. Idk why ALS does XYZ, cause I never used it.
interesting, didnt know that
again ty, ive been stuck on this a while this is a huge help
How? And doing this in multiplayer is kinda hard. Improving my skills in networking and multiplayer
Hii I'm trying to test the fundamentals of a dedicated server.
It's basically following this guide: https://www.youtube.com/watch?v=Aj-CaWwSPJg
in the server cmd I run
[ProjectName]Server.exe -log
and in the client cmd I run
[ProjectName]Client.exe -windowed -resx=800 -resy=450
When I press "Login" on the client, the player disappears and the camera gets stuck at 0,0,0 location and I get the following error in the server cmd
Not so simple to explain. CMC is difficult. Check the pinned messages for some CMC repositories to learn.
That error is probably not directly related. The whole SlateApplication said bye and clocked out. Check what happened before that.
I'm not entirely sure how to do that
Open the log file in your builds Saved/Logs folder.
ah yes got it ty
Ha! Now the jump feels as the servers, I swaped the deltatime by a server deltatime and do a oneway estimate for lags - and it feels good now - I'am sure this isn't a best practise but it works for now
😅 the rest of polish are animation / transition timing side
Hello, in my game we can have 200vs200 on some small locations like siege castle.
World Partition Multi-Server is a solution, but the size of chunk map can receive all ppl, should i split lower these locations like castles ? (more chunk of castles to dispatch better?)
Hey, I got directed here for help on a multiplayer game. I was also told that get player controller should not be used for multiplayer games which is what my studio uses and the game seems to work just fine, I just get a lot of errors, what should I use instead of get player controller?
GetPlayerController will return the local controllers first, so typically it's good for local stuff like UI.
Typically when you need a player controller in a multiplayer context you grab it from a pawn, or pass the controller as a parameter to whatever functions you need. Could you give an example on where GetPlayerController is used in a place you think it shouldn't in your game?
these are two of the parts i get errors for
sorry wrong pics hold on
these two
So the server is spawning a third person character, I assume for the client? That Add Mapping Context is typically done in the begin play of the Pawn itself. Notice that it says "local" player subsystem. This means that the mapping context should be added locally, and not on the server.
I assume that the SpawnActor screenshot you sent is running on the server only
As for that screenshot you send with the UI, using GetPlayerController(0) for local UI stuff is fine, as long as it doesn't execute on the server or other clients as well
tbh I don't know someone else made this system and I have to fix it
What is this system trying to achieve? Spawn a pawn for a client?
Its supposed to spawn the player and then connect them to the button mapping so things like movement and double jump wotk
This is typically how input is added to a player
This will need to happen after you get a controller to possess a pawn
This breaks in 5.6
Should be in the controller class for clients only.
how do I make sure it is for clients only
Branch ( (Is Server NOT) && (Get Local Role == Autonomous Proxy)) [TRUE]
What changed in 5.6 that would break this? I haven't actually used 5.6 yet so I don't know about changes
Not sure. It doesn't really break, but it throws an error.
I started moving IMC over to the controller when enhanced input released.
First/Third person templates started throwing the error in 5.6
I think this blueprint code should be fine, unless they made the enhanced input local subsystem only accessible in a player controller somehow?
One thing to note is that if you just need a player to spawn immediately after joining a game, the Default Pawn in the GameMode should automatically spawn it and assign the controller to it.
If this is happening after the fact, just make sure to pass the controller of whatever client is asking for the pawn, and call possess on the controller with the new pawn passed as a parameter on the authority
Ok so here's how I setup Begin Play on Controller and Character due to Proxies.
Proxy Role enum is now used through out to control flow for server/client
for context this is the entire code
Shouldn't use any of the Get X by index nodes in multiplayer. Regardless if the code executed is client-side / local only.
None of these
From Character/Pawn you use Get Controller
If you need Player Controller Type, simple cast it to Player Controller
Even better is to use an interface function
Better than that, put IMC in the controller class.
whats and IMC
I have one of those in already
Epic/Lyra/Fortnite use the mesh
But there is no advantage to this over rotating the actor, and plenty of disadvantages (as listed on the repo you linked)
i.e. they established a standard but mine is better 😉
@ivory oar too
yea i have since learned lol
im not sure why its so hard to do, it seems like im doing everything correctly
My solution is fully battle tested btw, its in a released game and I've used it in many projects since
in yours you are rotating the mesh ?
woops, Eric just answered that
and i assume you cant say in what released game you used it
You have it in the Character class and you're using a single player local node for Player 2 to set it.
Should be in controller class using SELF
GTA6!
when I get cast to player controller it looks different
^^^ What @lament flax said. It's the very last option in the context menu
I get an error now that says self is not a pawn and it needs a target
Legacy: Steel & Sorcery
This is in the character class right?
this is for spawning in the characters and assigning them to a controller
You code in IMC in either the character class or preferably the controller class.
I’m trying to create a Mordhau mod for my server without turning it into a modded server I want it to be a server-side mod. Based on this brief explanation, I’m looking for a solution to my idea: I want to modify the widget shown in the pictures so I can add any text I want and also change its position for example, put it in the middle of the screen or scale it up. Is this possible through Blueprints (BP)?
I’m using the game’s SDK, which is an Unreal Engine 4 template that includes all of the game’s Blueprints.
Does anyone have any idea why my stunned/weakened anim montage works at the start of the battle if a character is at 25% health but the death animation doesn't start at the beginning of battle even when the characters' HP is 0? I can't quite figure out why one works but the other doesn't work at all.
For a start, your InRange includes zero. So if health is zero, it will still go to true.
Second, don't ever == floats. It's playing with fire. Always use a NearlyEquals or an <= style.
Oof! That makes sense! 😅 Oh shit, I didn't know that, I will remember that then and not mess with those. I ended up changing that information and for whatever reason it will not play the death animation, even if I plug that in directly and disconnect the stun animation montage. Any idea as to why that might happen? The character just goes into it's default idle stance at the start of battle.
Not certain, but sounds like the death animation isn't slotted correctly in the Anim BP? Does it use a different slot than the stun?
So the information is being sent between the UnitBase_Blueprint and the ThirdPersonCharacter_Blueprint, and the characters' animations are stored in the same place. It's odd because when the character dies in battle it plays the animation just fine, it almost seems like the idle animation is overriding the death animation.
Do it like this:
In -> HP > Low? -> Yes -> normal
-> No -> HP > Dead? -> Yes -> lowhp
-> no -> dead
Is this what you mean Adriel?
why do you have 3 branches
how many end cases are there, 3? Normal, Injured, Dead?
Hi @grand kestrel, I was checking out your PredictedMovement plugin, specifically how you handle CMC modifiers, I am wondering why do you use tags to define a modifier's potency (aka Boost.Level1, Boost.Level2, Boost.Level3)? The tags themselves eventually resolve into a uint8 under the hood, so my question is why use tags instead of raw ints?
My guess is so it works with GAS, which you do mention, but I believe that needs a lot of extra work because the CMC can't deduce the EModifierNetType from whatever modifier tag the ASC has. And you can't easily locally predict adding a tag unless you have it granted by a GE, but then predicting the removal of a GE is another pain point to deal with.
On a side note, the work you've done is sick.
Levels don't need to be levels, they can be anything, designers may want to define them, that was just the obvious example implementation
You could have a speed modifier based on equipped weapon
It isn't for GAS. On Legacy we did use modifiers for snares via GE components, but it has been a long time since I looked at that
Yeah I did read that they could be anything, I just can't think of what lol, but I'm sure it could be of use. I tried having it work with GAS by granting tags from GEs, works great except I don't wanna deal with GE removal prediction... And since CMC modifiers are only needed on players, I figured I'd just apply the modifier directly from the player's class
IIRC - in UpdateCharacterStateBeforeMovement read the tags from the ASC, and set the predicted modifier level from there
Then let CMC handle the prediction
Yeah I have the GE granting a modifier tag, it works when the GE is predictively added but when it's removed, it causes a noticeable correction since it's not predicted. Must say that I only tried it using NetType::LocalCorrection and not LocalPredicted
When the GE ends, the tag is removed on the server before the client and so that happens
Though it works perfectly without GAS, and if I want a temporary modifier then I use timers
I also wonder why Snares are only available as ServerInitiated? I assume it'd be fine if I make them localpredicted like Boosts. I do feel like I'd be adding too much data for the CMC :C
I have a blueprint that is meant to fire off an event in the player controller to create a widget, however using the switch authority when the client interacts with it, it still comes back as authority?
If you're playing on a Listenserver, AKA one client is a host, then that player is authority even though it's still a client.
Need more context. What is the blueprint? Why does it tell the controller to create a widget?
a player interacts with an actor, this actor then cast's to the player controller to fire off an event that creates a widget on the players screen that intereacted with it
Unless you need networking here, this is all local mostly.
so i believe the issue here is that since the client fires off as authority, it only works on the listen server. How do i make either the client send a remote signal or the actor recognise its a client? im still new to all this sorry if this is frustrating
Are you trying to do anything more than display the widget on the single client that interacted with the thing?
no, thats it
Remove the checks then. Your input is local to the client pressing the key. They'll get their own player controller, and push a widget to their own screen.
by "checks" you mean the switch authority?
Yep
i have, its still only displaying on the listen server and not the client
despite the client being the one who interacts with itr
How does your interaction work?
uuuuuhhhhhh its piggy backing off of a plugin im alr struggling to wrap my head around
Are you able to show how it's calling into the actor it's interacting with?
Or even maybe just the actor's implementation where it's asking the controller to show the widget.
this is it at its simplest, as if it was designed for singleplayer
i was then using a cast, to cast to the player controller
Yeah. This will be your issue. But to fix it, we need to see the callsite of that Interact function.
im struggling to figure that one out myself
Right click the node, and Find References. Then click on the binoculars icon. It'll do a FindInAllBlueprints search
I believe the Interact event is a server RPC? makes sense that it displays the widget on the server and not the client.
You can't see a single server RPC, how are you making that assumption?
Oh I don't know anything about blueprints so I don't know if the Event node would have written somewhere that it's coming from a server if it was a server rpc?
Assumed it was a server rpc cause interacting with an actor goes through it normally
There's an RPC somewhere, but not here. The interaction itself is likely a server RPC. But nothing here is showing it. This code is running on server somehow. It's using the server's player controller, IE index 0.
Oh yeah I see the get player controller node, I don't like that.
Need to see the callsite for whatever is calling this, cause that needs to pass a controller or playerstate or pawn through, which can then get the controller and call a client RPC to show the widget maybe.
Would be much easier if the input had some sort of distinction for authoritive or local interaction. It makes stuff like this much cleaner.
Yeah normally calling the Interact server rpc should pass something that identifies the instigator.
If the sole purpose of the actor is to display the widget then no need to call an rpc, just call its interface interact function and display the widget
how do i fix materials being bright white material even if i have a differebnt material on i
for me i dont see it but others do idk
Is it a specific actor or everything is like that?
okay im back with another error on the same topic, ive made my own interaction system using an interface and a line trace. However now the client cannot interact with the actor. I have the authority switch that runs off remote into a custom event that executes on server and it doesnt work
this is how my interaction system works
if i change the run on owning client node to execute on server, then the actor im interacting with wont recognise remote and only authority. But this means that the widget that is created upon interacting with it after the repnotify has been executed to true, will only affect the listen server and not the client when the client interacts with the actor
so i believe the issue is within the actor itself, not executing on the server
As I said earlier, if the sole purpose of the actor is to display the widget then no need to call an rpc, just call directly its interface interact function and display the widget
In theory, you do one or two things. Either you only do the server RPC and expect everything on the actor you interact with to be server side, and then handle everything else via replicated variables for state and potentially RPCs for one time effects.
Or you do the above but also call the interact stuff locally on top of the server RPC to do any kind of prediction logic.
The second case is more complicated and has more edge cases
One thing you gotta realize is:
That RPC won't work. Server and ClientRPC require the Actor you call them on to be owned by the Client.
A random Actor in the scene/level ain't owned by the Client. The ServerRPC has to happen before you interact, e.g. in your Character or a Component on it.
And in case you care about people cheating:
This ain't good either, cause cheaters can send any Actor through that and act like they are in range of them.
You'd want to perform the RPC and then do the Trace on the Server.
After that you then don't need the additional RPC anymore of course.
So it's a bit like this:
Character: OnKeyPress -> ServerRPC_TryInteract
ServerRPC_TryInteract -> LineTrace -> Interface_Interact(HitActor)
HitActor: Interface_Interact -> DoStuff
If you don't care about cheating it can stay like this:
Character: OnKeyPress -> LineTrace -> ServerRPC_TryInteract(HitActor)
ServerRPC_TryInteract -> Interface_Interact(HitActor)
HitActor: Interface_Interact -> DoStuff
And the second option with the local prediction would be something like this:
Character: OnKeyPress -> LineTrace -> Interface_Interactor(HitActor) -> ServerRPC_TryInteract(HitActor)
ServerRPC_TryInteract -> Interface_Interact(HitActor)
HitActor: Interface_Interact -> SwitchHasAuthority
Authority -> DoStuffOnServer
Remove -> DoStuffOnClient
But the second case is more complex. Whatever you predict is stuff you don't want to happen on that Client again if the Server replicates it via an OnRep/Replicated Variable or a Multicast, so you need to filter, etc.
And you could mispredict, so changing state locally is something that you need to be able to undo, etc.
I would suggest staying with the ServerRPC-only approach for starters.
I would also suggest adding some information to the Interface function, such as the Instigator of the Interaction.
You can then pass the Character/Pawn from which you are tracing along.
Helps if you later need to call a ClientRPC on that specific Instigator, as that again requires an Actor that is owned by that Client.
And it helps if you later want to allow only one player at a time to interact with something.
:P Hope this helps, gotta start my own work now.
In CMC, where does the MoveData in ServerCheckClientError come from? I think it's filled in ClientFillNetworkMoveData?
Which MoveData specifically? Cause I don't see anything called MoveData in that method.
I meant the GetCurrentNetworkMoveData()
But that's your own code :<
Oh my I forgot, my bad... I had this code a year ago
/**
* Current move data being processed or handled.
* This is set before MoveAutonomous (for replayed moves and server moves), and cleared thereafter.
* Useful for being able to access custom movement data during internal movement functions such as MoveAutonomous() or UpdateFromCompressedFlags() to be able to maintain backwards API compatibility.
*/
FCharacterNetworkMoveData* GetCurrentNetworkMoveData() const { return CurrentNetworkMoveData; }
/**
* Used internally to set the FCharacterNetworkMoveData currently being processed, either being serialized or replayed on the client, or being received and processed on the server.
* @see GetCurrentNetworkMoveData()
*/
void SetCurrentNetworkMoveData(FCharacterNetworkMoveData* CurrentData) { CurrentNetworkMoveData = CurrentData; }
Oh you had me thinking for a sec that the function is mine, yeah it's in the CMC
The Client can potentially send 3 different MoveData containers.
Server handles them in ServerMove_HandleMoveData
Every time, before call ServerMove_PerformMovement, it will call SetCurrentNetworkMoveData.
Once for OldMoveData, once for PendingMoveData and once for NewMoveData.
Oh I see
If and when those are actually send is something that gets decided on Client-side.
Got it. I was wondering cause I noticed that for those "WantsX" type of properties, I don't have to call them both locally and on the server at the same time
And yes, they ultimately are set on the Container via ClientFillNetworkMoveData.
CallServerMovePacked(NewMove, ClientData->PendingMove.Get(), OldMove.Get());
Inside CharacterMovementComponent::ReplicateMoveToServer
That function is, iirc, mostly responsible for deciding if those 3 pointers are actually set. So you can find the conditions for them in there iirc.
The getter is just so you don't have to care which of the 3 is processed by the server, cause the server shouldn't care.
Ah I see the function, I'll explore more about it, but yeah I see it sends a packed move to the server
Got it
In short:
- OldMove is the "oldest unacknowledged important move, which is NOT the most recent move, as that could be combined with the new move.
- NewMove should be clear.
- PendingMove is a move that got delayed, and wasn't sent last frame due to "reasons". It is usually attempted to be combined with NewMove, but that isn't always possible, in which case both Moves are send individually.
Sending OldMove is just a matter of telling the Server "Hey, this move should really happen, but I haven't heard back from you yet.". Basically your average cold email.
If NewMove isn't sent, then none of them are. A NewMove that isn't send will be parked in the PendingMove.
Makes sense, thanks for clearing that up
And Move Combining is the act of putting the data of two Moves into one, but only IF that makes sense. E.g. if a player holds forward and does nothing else, moving forward twice for 0.016 seconds, or once for 0.032 seconds makes no difference. But if the NewMove is for example a jump, then it can't combine them (Walk + Jump can't be logically combined), at which point it sends both individually.
MoveCombining usually only starts triggering if your Client has more than 60 FPS.
Also a big pitfall when doing custom movement stuff and not going over 60 FPS in the editor.
I see, it's so we send fewer moves, I think that's handled in CanCombineWith
The big annoyance here is that: The original move that got stored as PendingMove does actually get processed by the Client, just not sent to the Server. After combining, the combined move is also processed by the Client, potentially doing the PendingMove twice. So the SavedMove has FSavedMove_Character::SetInitialPosition which stores data that is used to later reset the Character back to what it was before processing the pending move.
I got hit by that when I added support for Stamina to the CMC, where I didn't know about that and the Client started consuming Stamina twice every time it combined moves.
Oh I see so SetInitialPosition makes PendingMove not process twice if it would've by any chance
Added StartStamina to it, set that in SetInitialPosition and used it in FSavedMove_Character::CombineWith to restore the Stamina on the Character.
The function does say "Set the properties describing the position, etc. of the moved pawn at the start of the move." so yeah makes sense
Yus.
You can check the pinned CMC repo by Vaei for more.
I gotta get back to work now :D
@thin stratus sorry for the direct ping, but I see from channel history you are experienced with Mover and as of April were still recommending it not be used.
I am looking to implement a climbing prototype involving ropes/pitons, and maybe even tying characters together. Physics Mover would seem a good choice to start from, but it doesn't feel very nice to use in the demo level in 5.5. And I am concerned when I read about the issues people are having with Mover in general, physics mover being the worst of the lot.
So I guess I am asking, do you still believe Mover is a bad choice? And do you have any thoughts/pointers on implementing rope/constraint movement in CMC instead?
- I still believe Mover is not ready to be used.
- It is lacking in features compared to the CMC.
- It is not as battle tested as the CMC, which has tons and tons of large games released with it, including Fortnite.
- It's prediction base, being NPP, is not as great as people hoped it would be. It has a lot of unfinished features, bugs, and doesn't solve the problems that the CMC has.
- It's Physics side is dead. And with that I mean the Physics code in the Mover plugin itself.
- If you want to use Physics with Mover, you should use Chaos Mover, which is what Epic still actively works on. This should be a separate plugin iirc. But this is also not at a point that I would suggest using.
- Rope/Constraint logic in the CMC would work the same way any other stuff that, in theory, needs physics would work: You fake it with vector math.
Ok, thanks. Sounds like CMC is still the way to go.
the actors purpose is top generate an integer and to act as a vector in which players will teleport betweem
the widget will be in the player controller
void AWeapon::BeginPlay()
{
Super::BeginPlay();
if (HasAuthority())
{
WeaponMesh->SetSimulatePhysics(true);
AreaSphere->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
AreaSphere->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);
AreaSphere->OnComponentBeginOverlap.AddDynamic(this, &ThisClass::OnSphereOverlap);
AreaSphere->OnComponentEndOverlap.AddDynamic(this, &ThisClass::OnSphereEndOverlap);
}
}
void AWeapon::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
ASoldierCharacter* SoldierCharacter = Cast<ASoldierCharacter>(OtherActor);
if (SoldierCharacter)
{
SoldierCharacter->SetOverlappingWeapon(this);
}
}
void AWeapon::OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
ASoldierCharacter* SoldierCharacter = Cast<ASoldierCharacter>(OtherActor);
if (SoldierCharacter)
{
SoldierCharacter->SetOverlappingWeapon(nullptr);
}
}
void AWeapon::OnRep_WeaponState()
{
switch (WeaponState)
{
case EWeaponState::EWS_Equipped:
ShowPickupWidget(false);
WeaponMesh->SetSimulatePhysics(false);
WeaponMesh->SetEnableGravity(false);
AreaSphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
break;
case EWeaponState::EWS_Dropped:
if (HasAuthority())
{
AreaSphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
}
WeaponMesh->SetSimulatePhysics(true);
WeaponMesh->SetEnableGravity(true);
WeaponMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
break;
}
}
i have a variable on character Overlapping Weapon, but it's being null even when i'm on it
No it’s jus a cube and a subtraction volume
What variable is null?
this is fixed
i'm fixing UI
ShowPickupWidget is not hiding when overlap end
void ASoldierCharacter::OnRep_OverlappingWeapon(AWeapon* LastWeapon)
{
UE_LOG(LogTemp, Warning, TEXT("Last Weapon: %p"), LastWeapon);
if (LastWeapon)
{
LastWeapon->ShowPickupWidget(false);
}
if (OverlappingWeapon)
{
OverlappingWeapon->ShowPickupWidget(true);
}
}
void ASoldierCharacter::SetOverlappingWeapon(AWeapon* OverlappedWeapon)
{
OverlappingWeapon = OverlappedWeapon;
if (IsLocallyControlled())
{
if (OverlappingWeapon)
{
OverlappingWeapon->ShowPickupWidget(true);
}
}
}
void AWeapon::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
//UE_LOG(LogTemp, Warning, TEXT("Sphere overlap begin"));
ASoldierCharacter* SoldierCharacter = Cast<ASoldierCharacter>(OtherActor);
if (SoldierCharacter)
{
SoldierCharacter->SetOverlappingWeapon(this);
}
}
void AWeapon::OnSphereEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
ASoldierCharacter* SoldierCharacter = Cast<ASoldierCharacter>(OtherActor);
if (SoldierCharacter)
{
SoldierCharacter->SetOverlappingWeapon(nullptr);
}
}
DedicatedServer or ListenServer?
ListenServer
Right, so you call it manually for the Server's own Character.
Does the OverlappingWeapon have a replication condition?
this is the replication
I meant in the DOREPLIFETIME part
COND_OwnerOnly
So LastWeapon is invalid then I guess?
DOREPLIFETIME_CONDITION(ASoldierCharacter, OverlappingWeapon, COND_OwnerOnly);
yes
though it worked once
then didn't
LogTemp: Warning: Last Weapon: 0000000000000000
LogTemp: Warning: Last Weapon: 0000047B7E6D8200
Hm. Strange.
That would only happen if the Weapon is not existing anymore on the Client.
that happen when client is endoverlap
At which point EndPlay of the Weapon should have called, where you'd want to Hide the Widget in addition.
Also, widget is 2D AddToViewport widget. not 3D
Hm. So the Weapon is definitely still there?
yes
LastWeapon should only be invalid if the Actor is gone on the Client or if the value of OverlappingWeapon was nullptr before the OnRep called.
okay?
i still don't understand how can i fix this?
maybe a weird UE5 bug... a while back I was testing/previewing in standalone game mode. when I switch back to PIE, and select 2 players, the first opens in a normal window as expected, but then the second player is still opening in standalone game mode. is there a setting or config file i can delete to get this back to normal where all windows open in PIE?
Did you maybe select that it shouldn't be a single process?
That single process box is unchecked. Does it need to be checked? I didn’t even remember toggling it ever so I thought it was always like that
how do i stop rubberbanding from default walk anim? like idk why it does that only on client tho and on network emulation
Does your climbing mechanic really need prediction?
Climbing isn't a very twitchy transient movement mode
Perhaps not 🤔
Or even this, does your climbing mechanic need predicted server authoritative movement
If ping lag or client authoritative movement is ok then you can just roll your own system and have a much easier time IMO
although if it's climbing I'd probably use physics
a climber is basically a chain of masses with a few constraints, some of which have force limits (holds)
Mismatch in movement speeds between client and server (authority).
Rubber-banding and Jitter are server correction.
would you mind showing me an example
ion get it how autgority works
even tho ive read docs
Iris got moved out of Experimental in the 5.7 branch apparently
Can't wait to use it in 5.10
Read the CMC docs, specifically the movement replication summary.
https://dev.epicgames.com/documentation/en-us/unreal-engine/understanding-networked-movement-in-the-character-movement-component-for-unreal-engine#movementreplicationsummary
Troubleshoot Velocity.
Also, turn on p.NetShowCorrections in the console.
If there's no issue here, then look at your Anim Sequence for walking. Make sure you're not using Root Motion.
Its a coop game so does not need to be authorative, but it does mean multiple players might be involved in the same constraint. Might need to try and avoid that where possible.
If there's a lot of cross-connected constraining going on I'd use physics and not have prediction
if you made a system from scratch it'd end up basically BEING a physics engine
That sounds like an interesting approach. But how does that integrate with the CMC? Don't use CMC at all?
No cmc in what I'm suggesting
What does the CMC get you in a climbing game? You'll have to make the movement modes yourself, and it'll be pure hell to get tightly coupled systems of characters to sync and not correct all the time.
Well, its a first person adventure game predominantly, with some climbing in it.
Imagine an FPS that was more about running into each other than shooting. resolving the results of multiple independently predicted movements is the worst case I can imagine, and that's all that climbing with dudes tied to each other is.
In that case it changes the calculus a bit. Design around what your main mechanic is.
Kinda curious how Chained Together pulled it off
I'd have to see the edge cases but if it's on Unreal it could be a custom movement mode
99% of the time the chain is doing nothing
and I think I kinda see enough leeway in it that the distance constraint coming from the chain could be server authoritative, that is, your state at the start of every frame is "how far can you go from the end of the chain"
Yeah, if it just constrains players together then I can see how that might be done in cmc.
I didn't see any evidence of the chain having physicality but I didn't watch much of it
I'd guess how they enforce the distance constraint is that your distance limit is old
you can move x distance from where buddy was recently, not from where he "is"
can you end up in this situation in Chained Together?
2 dudes hanging from chains draped over an obstacle
I dont know
would be worth investigating
anyway if CMC is what you wanna use, get a distance constraint working
Yeah that sounds like a good first step
I like physics since lots of complicated behavior falls out
2 guys on one end of the rope going down, and the 1 guy going up, that just falls out with physics. Hard to do kinematically
Physics Mover feels close, yet still quite far away from shippable
I mean the fundamental problem is hard
I go left, you go right, we're tied together. We each predict we have the slack to do it. Who's correct?
yeah anim works fine and theres some correction, however ive lowered some settings a bit and it kinda made problem less noticable
It's the same problem as collision in normal character movement
Predicted vs Predicted is much harder to handle than Predicted vs Static (terrain, etc)
Yes there will always have to be some correction.
You'll be correcting all the time if at rope limits.
So I'm still struggling to get my characters that have 0 hp at the start of battle to play the death animation. Right now each character is dying at the start of battle despite the conditions in the function (the characters have roughly 1/4 of health at the start of the battle). The Stunned function does work on it's own, and if I increase the character's HP to start the battle with half health, then there is no stunned effect on them, as it should be. The death function seems to override everything for some reason, regardless of where the characters' health is. Any idea why the Stun function is working and the Death function is not? What am I missing? 😅
Create an Enum to handle health status. (Normal, Stunned, Dead)
Conditional Flow....
IF (Health > (Max Health * 0.25)) Set HealthState [Normal]
ELSE IF ( Health Between (0.001 && (Max Health * 0.25)) -> Set HealthState [Stunned]
ELSE IF (Health <= 0.00) -> Set HealthState [Dead]
Anytime HP is modified run that conditional.
I would also make HealthState a repnotify. Make all health changes on the server and then run the conditional logic.
Use the Onrep_HealthState function to drive actions. Stun effect, montage etc.
Furthermore if you need Apply any of these effects immediately you need to have the server execute the conditional logic right off of begin play.
This will Set the current "True" state and network flush it.... 0 HP on begin play will immediately result in death.
It looks like you are missing a check to call the "isDead" func. You are setting "Character is Dead" with a <= bool but that bool doesnt connect to a Branch anywhere in your logic from what I am seeing.
Same with the Stunned func
Also, I would move the check for health being <= 0 outside of the functions, IE the isDead func should be called after you check if the health is <= 0, the func only setting the bool to true and playing the anim
I think this is what you meant?
I appreciate your comment and honestly, I think I will start looking into that too. It's been on my mind and I may be at a junction where I should really be using such a set up.
The last image is exactly what I would do, I would also use an enum like RevOverDrive suggested, but using bools to start isnt a bad idea. I would remove the check inside the Functions as they are redundant, in fact I would create a func that does these checks so you can call it any time you take damage
Im just giving you ideas on different work flows but the logic must contain a check with a branch or something similar otherwise you will always call your functions, only setting the bools appropriately
I'm making a zombie game, fps.
Should I go with 2 skeletal mesh or single skeletal mesh? Like COD before 2019 uses 2 meshes but in mw2019, they started using single mesh for character.
In 2 mesh, one is non local mesh which'll be replicated and one is local, that is only hands
You can keep two and just disable the first person mesh when needed
or even have the first person mesh attached to the camera itself
It might be useful to consider what happens if you need to spectate the other players
If so you need to show the hands to them as well, assuming you do so in first person
having two is also going to be required if you want to have the shadows exist for the third person mesh and not show the first person mesh's shadows
fps/tps setup is generally more fluid, allows the players to easily tweak the fov and head bob intensity, animations also look better compared to a true first person setup even though you have to make two versions of each animation, however seeing your own shadow in first person isn't easy at all if you want it to make sense (aka you can't have shadow of floating arms, and if instead you enable your tps body shadows then it may look strange in some animations as fps and tps animations aren't 1:1), thus in most games with this setup have it so you can't see your own shadow in first person.
True first person setup is more immersive (if your animations are good) as the shadow reflects what you do perfectly, and you can see your whole body, notable games that have it are EFT, Star Citizen, DayZ, and Outlast. It's hard to stabilize the intense head bobbing it causes and/or disable it completely without it looking weird, and it's hard to make animations look good in first person, you need to be really skilled in IK to implement stuff like aiming etc. True first person is definitely easier to implement in singleplayer though as animations can be made to look good in first person without having to worry about how other players see you.
I'm not an expert but not a beginner as well. Would be hard but nothing achieved without hard work. So what do you suggest? I'm confused between how should I go with FPS? Like 2 mesh or single mesh. Currently in single mesh, my camera is attached to hand and right hand will be rotated to the Hit point that is being started from center of screen.
While left hand will be FABRIK
One great advantage that true first person has is the accuracy of what you're seeing. BF4 had a big problem when fps/tps animations weren't identical, not to mention head glitching... All of this depends on your game, not all games are the same.
Why isn't your camera attached to your head or neck bone if you're on true fps?
My camera is attached to Head socket
Right that's how it should be. Well if you go down the true fps road, then you just to have to be perseverant, as it's not easy by any means compared to fps/tps setup. Just make sure it's worth it
The game is more like COD but based in Zombie with 4 players
So I'm a bit confused between true fps or just single mesh and set camera on it
Ready or Not though achieved it ?
IIRC Ready Or Not doesn't have true fps
They use a setup of local fps arms + local body without head + local hidden full body with cast hidden shadows enabled for shadows + full tps body for other players
That's a messy thing
Can you advice on this ?
it's what Mirror's Edge did
It's quite heavy but could definitely be optimized
It really depends on you, I listed the pros/cons of each, you can do more research and decide.
To me personally I wouldn't go with a true fps setup for such game
Hello, using blueprints how can i do the same effect of this loop but not in a single frame because it freezes the host
Right! I'm leaning toward that too. Since I'm not making AAA game either
you can use a timer or simply delay to the next frame (a zero delay)
It might be easiest to just pop one element at a time from the back of the array if num - 1 is a valid index
Btw I've a wierd bug if anyone can understand this?
Immersiveness isn't the big focus and it's coop so who cares about whether fps/tps animations are 1:1 accurate
fps/tps setup can still be immersive though but the easy route that compromises on that is to just disable shadows on first person, which is not a big deal at all for such game
You mean the true fps right? 2 meshes
semi baffled atm, i have an enemy AI that i've had for a while but just tested it again, and when i kill it, my character gets destroyed and i cannot find where this logic is happening... as i started with im quite baffled. idk if anyone can offer some thoughts here but any would be helpful
Overlaps run on both the server and client if I'm not wrong, so make sure to only run the code on HasAuthority, and remove that if is locally controlled check since the server wouldn't be controlling the client who overlapped
true first person is 1 full body mesh only
Ohk.
2 meshes is the fps/tps setup (one mesh for first person, one other for third person)
I'll go with the True fps ig
true fps can be awful if you have ever played nuclear nightmare they just slapped a camera on the meshes head and line up the guns to be excusable at best
i mean if i was making a game where you didnt really hold anything i might do true fps like a basic horror game
Yeah true fps is an easy choice for games where your rarely holding anything, that's what Outlast did
can you just drag off an array though get the item at the index and destroy it?
i might have to whip on c++ for this one
If it helps level streaming actually works in a very similar manner to doing X new registrations per-frame with a budget you can tweak
yeah i think you can remove index but it just removes it from the array, i have to destroy all the rooms
So looks like I've to go with fps/tps settings
You can read the index, destroy it and then remove it from the array or just keep a running tally of the current index and reset it all later
of course if you remove a specific index do it in reverse order starting at the end, or else they will change positions
One doubt, what about mirrors?
You just don't wanna see hands and gun in mirror right?
How do the mirrors render here? are they a scene capture? raytraced? reflection probes?
And yeah of course you would prefer to see the third person mesh
In many ways of capturing the scene you can choose to omit or include primitives
it depends
i think its worth thuging it out and geting first person arms
i suck at animating but i made a control rig which is use to make all my fps animation and they are passable
well i dont suck at animating i just dont do it often lol
anyone doing steam next fest?
how do i get player names in order and store them for display in widget from overlap collision box? multiplayer blueprint
the pawns that overlap the box should have a playerstate which contains their name
the widget just needs to know which playerstates overlapped the collision box and the list them out with reading their name
when i kill an enenmy AI, my charcter is being destroyed. i have zero idea how this is happening, i never call "destroy actor" at all on my character, so nothing easy to point to in this case. it has been a while since i tested the AIs but yea can someone give me some thoughts
breakpoint it
it could be something like the kill z being encroached from moving down... you need to actually debug to reason about what happens though
yea prob a good idea, although, i don't know where to start with it but i suppose putting it somewhere to start would be a good place to begin
it's as soon as the enemy dies, as if im killing myself
what I mean here is to breakpoint the endplay
I do not know how else you would start with it
unless there was some clear thing that was being triggered alongside
ahhh like breakpoint the event destroyed?
on the char*
either that or them ending play
well controller still exists, so it's definitley just destroying the character but this is a good idea to start. that should help point to what happens before
will it tell me what called the destroyed event ?
it depends on how it is called
i never call destroy actor for a character tho, which is why im omega confused
the bp debugger should give a full callstack unless it is in native code
yeah, that is why I am trying to solve the problem instead of guessing
but I did guess about it being kill-z related... I have had that one happen before lol
basically in your world settings there is a set "kill floor z" where anything that falls below that is destroyed
this is useful to clean up things that fall off of a level but not super nice when you are actually trying to play the game and just happen to move down that far
so you might need to lower that a bit more if it is in the way
nice to know about that, i will definteitly be using that
but i can rest assure that is not the issue in this case
It's on by default to some value I forget
i know it isn't the issue only becuase im not going lower in the world at all, but i will check that value out
but appreciate the advice on where to start, will just put a breakpoint and see what it tells me from there
the default is around 10km below the origin so... maybe not this lol
it's good it's so high by default but I would say it's worth considering if you have lots of things falling out of sight forever to clean them up sooner
Have you guys ever tried implementing slomo for multiplayer game? Is it feasible or it will eventually desync?
that kind of depends on what you slow down... I think it would be fairly difficult to make work out of the box but buffering incoming inputs isn't that tough if you have complete control
also knowing about the slowdown would not be instantaneous unless you had a shared start time to account for round trip (ping) that all clients knew of
it is possible to just run slomo on the server too I guess if that helps but it won't be very smooth to start it
Yeah I guess I'll have to do some testing.
my concern with local time dilation stuff would be if it starts fighting cmc timestamps but I think they might already account for that
not sure
Iirc client tells the server the timestamp. Can't recall if any of that takes into account that it's slowed down or sped up. Might even cause problems yeah
I think if they are both in the same slomo inside of like a second it will probably be fine (could still correct but might not outright reject the timestamp)
Otherwise, one could just tell the server a higher timestamp/deltatime and speedhack
If the slowdown happens on both sides it's probably fine. And if it's triggered by an overlap or so it's also in sync.
But cool thing to test (local time dilation)
oh, UCharacterMovementComponent::ProcessClientTimeStampForTimeDiscrepancy already knows about CustomTimeDilation
so yeah that might kinda just work
ofc the timing being similar would be critical... might even be worth moving into the saved move itself
it being off for like a couple frames without moving fast might survive I guess
oof yeah that is 1.7 cm lol
is that a network settings float?
I think for this game limiting corrections during the transitions is reasonable (can be done dynamically but doing it globally could help)
Yeah somewhere from the net manager or so
Btw saved move probably already contains the delta time of the move. So it kinda has the dilation
oh yeah, I guess it would kinda be baked in
it does indeed have the DeltaTime which of course it would have to to compare the distance moved at all
oh, well there lol
problem solved
I should have known... they DO pack roll into a smaller byte instead of a short
that is smart because you really rarely roll a character
so i did the breakpoint and all i got back was that it was calling the "event destroyed" in the callstack. so basically gives me nothing to go off of, but maybe there's more info somewhere im missing ?
show the callstack
`Script call stack:
Function /Game/MAiBLUEPRINTS/CHARACTER/BP_NEWTHIRDPERSONCHARACTER.BP_NEWTHIRDPERSONCHARACTER_C:ReceiveDestroyed
`
But if you do, Epic made sure you have a bad time all around!
yeah unfortunately capsules do not consider rolling when sweeping
I think people get a bit like "oh, I can just roll the capsule" when they see it has an up vector
like... yeah but not really lol
i found
really dumb
really really dumb
typical
heated
but chill
need i say mo?
nothing shameful about missing stuff with something as complicated as a game
these complicated debug tools do not exist because people can just simulate the whole game in their minds... we need to see wtf is happening to reason about anything
love that. had one of those days today... lots of errors , lots of "bugs"... but alas.... i'll be back tomorrow ... better than ever before
for the record, i had an old AI controller that i remembered was not working correctly but it appears that the logic is working now, and i peeped the old logic and i was "destroying" the target that the AI had. so essentially upon killing the enemy i was destroying it's target (me/the player attacking it)
i should have never been "destorying" the AIs target to begin with, i should have either just set the ref to NULL or had a different method, but this was a while ago
but glad i found
created this overlap event, i implemented avoid duplication mechanic too - it takes player state and store it in variable, if its already stored, it wont add it again. i tested in editor but it only happens once. is it only happens in editor because it all same player state or its something diffeent?
"Hey, do you think Mover is usable by now?"
check notes
DefaultModeName is set but never used, so even though one specifies it it's not actually causing that Mode to be the first one to tick.
Which in return can cause Sync/AuxStates, which are added via InitializeSimulationState, to be lost if the user keeps them alive by hand within the Mode's SimulationTick.
"Probably not."
EDIT:
And yes, I only noticed that right about now, and only because I have a setup where a Mover Actor has exactly one MoverMode, but the SyncState I'm adding is optional based on the Actor's settings. So it's added via InitSimState and kept alive by hand during SimTick, so that the PersistentSyncState stuff doesn't end up adding the SyncState anyway, causing additional data to be replicated for no reason.
you have not mentioned which part actually only happens once, the overlap or the resulting list
we can only see this things we are shown
also... this number has NOTHING to do with a player state index
get the player state from the pawn
body index refers to components with multiple bodies
break only happens if it doesnt contain colloiding player state in player state stored
do not use the body index to find a player state in the player array
Can I change an actor’s properties from the server? I want to adjust its lighting settings and set cast shadows to false. How can I do that without running a modded server, using only a server-side mod that applies the actor property changes on the client?
I managed to delete the actor from the server, but I also want to modify its properties, especially turning cast shadows off. How can I do that?
Puh, you are throwing around some terms that I'm not sure apply here.
What do you mean by "modded server" and "server-side mod"?
what i need to store that unique to each player
Modifying properties works the exact way it is described within the documentation and the pinned Compendium. Assuming the modification is supposed to happen on the Clients, the Actor has to be marked as replicated, including the properties that you change. And if those changes need to be applied to something, those properties should be RepNotify properties, allowing you to use the OnRep of the properties to call some stuff you need.
If that's not what you mean then you'll have to explain more.
each playerstate is a unique reference already
but you need to get the playerstate for the pawn that overlapped the object
just because both the body ID and the player index are green does not mean they are related, they are just both integers
you are already obtaining the playerstate to get the name from the pawn
but it keep storing value , including duplicates
it prints again and again for each overlap from same player
what is the playerstate obtained from this? what is in the array?
does anything else change the array? are there multiple overlaps? which component triggers the overlap? does ending overlap remove them?
see here to better understand me : #multiplayer message
Right, but you do realize that "Mod for Server without it being a modded Server", sounds pretty impossible.
The Blueprint setups you see are working for me and implement my idea of deleting things, in other words actors, from the map on my server, and this deletion also applies to the clients. However, I ran into a shadow issue, so I wanted to ask whether I can change cast shadow specifically from true to false
Yes, I know that, but what I mean is that there are many ways and examples to try to change things on the server without making the server modded, and I agree that extensive modifications may require a modded server, but my goal and idea are to make changes without making the server modded
- I wouldn't be too sure about the "GetObjectName" always been what you expect. Depending on what condition you want to delete those actors on, you'd be better off using a more specific test, like the Class, or giving those Actors a Tag.
- You don't need to mark them as Replicated during the loop. If they aren't replicated, then they are usually also not linked to the Client. The only exception would be Actors that are placed into the level upfront, which would have a stable name due to being part of the level by default.
- Looping over all Actors can be pretty expensive. You need to realize that this entails literally every single Actor in the scene, and you perform a String comparison (contains) on every single one. That goes back to point 1., which you really might want to rethink.
- Destroying the Actors if they are replicated will replicate to Clients, but this is called on the Server, so I'm unsure how you are expecting this to work without applying those changes to said Server, which would turn it into a modded Server, or not?
- Combining 2. and 3., you are currently marking every single Actor as replicated, even ones that shouldn't be, like the GameMode, this is really really bad.
yo its my fault, i didnt add anything to the add node before. it worked thanks
My point is that any code that has to execute on the Server will require to "mod" the Server, or not? Like, you can't add logic to the Server without it being modded. That doesn't make sense to me at least.
And replication like this has to go through the Server. You can't get those Actors removed with a Client-only change, unless the Game already has logic for this.
The Shadows you are on about are probably baked shadows because you are removing an Actor that is pre-placed into the level at the time the shadows were baked.
:p i dont know how you understand me
Aka, you can't remove them runtime iirc, you would need to have those set to be Dynamic instead of Static and rebuilt the light to get rid of the static shadows that are baked.
this impelemntation is worked for me, so all what i want to change the cast shadow to false its simple
e.g. this is a baked shadow I would guess. Those were cast and baked when lighting was built. Removing the Mesh/Actor that was standing there doesn't cause the Shadows to go away. You'd need to ensure that this Actor doesn't cause Shadows to be baked.
You do you, but that loop you showed is really bad and will break stuff.
You can't just mark every single Actor as replicated...
break stuff like what ?
i dont get your point its worked perfectly without anything happend in fact all the issue i have is the shadow, and i can fix it by place other actor on top of it but i dont do that brefore i asked here to find if there a way to remove it
There are Actors that aren't meant to exist on Clients, like the GameMode. There is code in there that will call with the assumption to run on the Server only and can very much crash. On top of that, replicating Actors means Bandwidth usage. A Multiplayer game only replicates the bare minimum to keep bandwidth usage low. If you mark all of them as replicated it will cause a huge bandwidth. On top of that, a lot of those are probably using default values, which means they will be considered for replication, which costs performance on the CPU too. And then you might run into Actors being out of relevancy range and despawn locally, even though they shouldn't.
It's overal really not something you should do. At least move the SetReplicates behind the branch, before you destroy the actor.
You don't get my point cause you are a beginner in Multiplayer coding.
So either you take it that I have way more experience and that you are doing something really bad, or you ignore it and live with it. It won't ruin my day if you think that's all fine.
And the shadow stuff I explained already.
It remains cause it's baked. You have to change the specific Actor in the Scene to not bake static Shadows but have dynamic ones. Then rebuilt the lighting and it will cause the shadows to be runtime cast, which means they go away if the actor goes away.
yea im so beginner in fact but im just trying my best
With increased performance cost of course.
Turning "Cast Shadows" off won't do anything. If you delete the whole Actor, what are you going to set "Cast Shadows" to false on? That Actor is gone after all, there is nothing to set that bool on. You are basically asking something along the lines of "How can I split an apple after I already ate it?". You gotta split it before. Aka you gotta turn off Cast Shadows in the Editor already, which means no shadows at all even if the Actor is there, or you gotta change it to not cast static shadows, rebuilt the lighting of the level and push that as a new map/mod to the clients.
In the game in general, there are servers that have implemented this idea and they’ve been running for years without any issues. What I’m trying to do now is the same concept but in my own way, so I don’t know whether they use the same Blueprint as mine or not, but I haven’t seen any other way to do it. Also, even the developers in the game’s modding community recommend enabling replication
Yeah but not on every single Actor. At least limit it to the ones you want to Destroy.
And they might also meant that you do this before building the mod not during runtime.
But even if during runtime, at least limit it to the ones that pass the String Contains Branch.
Of course, I’ll modify the Blueprint to set “cast shadows” to false, then proceed with deleting it. Isn’t that logical?
Not really, no.
when i set a breakpoint in rider, how can i know if it's on server or client?
Should I just look at the Tread ID and if it's different then one might be server and the other the client?
There is context string that you can add as watch
But beats me what the exact string is. I'm not in reach of my PC atm
Ok cool, thanks! Gotta look into that! 🙂
Cool thanks a lot!!! 🙂
haha true 😅
Hi, does anyone know if the Network Prediction Plugin in 5.6 calls SimulationTick on simulated proxies? I have the Simulated Proxy Network LOD set to "Forward Predict" and I am using UMoverComponent. I noticed that simulated proxies never execute any code in the active movement mode's SimulationTick implementation (confirmed with a simple output using UE_LOG). I'd have thought simulated proxies would run this in forward prediction so they can accurately predict player motion between ticks.
If this is not the case, then what does "forward prediction" actually do? Just extrapolate last known velocity and location?
Afaik forward prediction isn't implemented and by the looks of it never will. Progress on the plugin is pretty dead.
So no, SimProxies won't call SimTick. Only FinalizeFrame.
@thin stratus Weird, I thought 5.6 had a bunch of Mover updates, so presumably NPP should be in active development since Mover is and is dependent on it. Bizarre
Mover can use NPP or Chaos. And Fortnite needs Chaos. So that's where the focus is.
@quasi tide Thank you! So the recommendation would be to switch to Chaos instead?
I think the main recommendation right now is to avoid Mover unless you absolutely need it. Because CMC is far more battle tested and can handle a majority of peoples games.
As for if you do decide to stick with it, couldn't say. Because the small amount of people that I know that are using it have heavily modified things.
But Chaos backend is the one Epic is working on mainly. Take that information and use it however you see fit.
im using the chaos backend one
it works fine
NPP is so rough, and i heard they are not touching it right now, due to time constraints
ofc cause as Duroxxigar said, fortnite uses chaos.
Is that the one that y'all are using for Atre?
Pretty sure Epic will only consider Chaos Mover. NPP barely gets any updates. Like one tiny change per month if at all.
And I would still stay away from Mover if you don't need it. CMC is still better.
Well, movement generally works great for the game so I'd rather not restart with CMC, I guess I just need to investigate Chaos Mover and see how much work is required to migrate
I was wondering why the character mover examples were so broken in places. Using the example map it completely freaks out if you try to climb the stairs, and jumping causes constant corrections