#multiplayer
1 messages · Page 77 of 1
I think epic at some point added some stuff for that cause they needed cloud instances to be debuggable
But no idea how that works
doing c++ is fine, I have a custom projectile movement component i created there
@peak fossil I posted about this already a while ago. Maybe you can find the chat via the search function
Just search for messages from me in here and then something something projectile
Hey I've asked this before, but haven't got any answers to it yet.
There is a mismatch between my animations on the server and on the client. No clue how to fix it.
Look at the first picture here, the trace is supposed to be traced forwards from the gun. This is playing as a client. The trace is going down in the ground.
The gif here shows me switching between the animation blueprint as the server and the client. You can see the animations are not the same. (The animation playing on the server here has the gun pointing downwards which explains the trace)
https://gyazo.com/119bd7c027efea7967b8983d6edd8032
But on the second image you can see the animations working fine in multiplayer both on the client and the server.
What is going on here and how do I fix it?
There is only one variable driving the animations and its an enum containing the type of weapon. This variable is replicated and only changed through the server
Can you confirm via Print Strings that the enum is indeed correct ?
Cause in your Gif I see a replicated variable on the AnimBP
Which would already be hella wrong
The enum here simulating the client is "rifle" which should start transitioning away from that "hands down" animation
Should there not be any replicated variables on the animBP?
No
AnimBP isn't replicated
Those variables need to be replicated in your Character already
Yeah they are replicated there
Made all the variables in the animBP itself not replicated, but same thing is still happening with the "hands down" animation
That animation is the "entry" state of the animation
So the enum is also replicated in your character?
Can you now print the value and ensure it's correct on server and Client?
Does that always happen or only when your server isn't looking at the client?
https://gyazo.com/f584d59f61f5239888d93aec32037835 You can see it working when swapping weapons too
Yeah! Ive felt like thats the case sometimes!
Ensure that your SkeletalMeshComponent is set to always tick and refresh bones
That's by default set to only do when rendered
I can't recall the settings name but it's a drop-down menu
You absolute hero ❤️ You have no clue how much of a headache this has been! Fixed the issue immediately
Yeah you are by far not the first one that encountered this hehe
I'll update my forum post with the solution too. Thank you so much
No worries
I thought my project was corrupted at one point there 😅
I implemented your solution and I wonder if you call the "ApplyVelocityAndGravity()" on Server or only on client?
We did that on both
Cause our ball is shot by the client
So we can predict it in addition to calling it on the server
I keep getting these warnings in packaged game, causing travel to never happen.
[2023.04.15-15.34.48:591][660]LogStreaming: Warning: LoadPackage: SkipPackage: /Game/Levels/Prototype (0xB0D9EB847E0DB048) - The package to load does not exist on disk or in the loader
[2023.04.15-15.34.48:591][660]LogLoad: Warning: UEngine::TickWorldTravel failed to Handle server travel to URL: /Game/Levels/Prototype?listen. Error: Failed to load package '/Game/Levels/Prototype'
What could be the cause since it works fine in editor 🤔 I've tried full clean and repackaging as well as absolute/relative path for server travel
hm okay, because the ball is not moving after setting "SetUpdatedComponent", I tried client, server and netMulticast
might be some other oversight on my part
Map might not be packaged
And how do I check?
Can you just do "open levelname" in the console?
If not then it's probably not packaged
Might need to add it to the maps you wish to package in the package settings
Yeah doesn't seem to work either, what am I looking for in package settings
Aha wait I think I've found it already, let me retry
Is there something special about using SetSkeletalMesh() on server
void AClothingBase::EquipClothing(AVRPlayerCharacter* VRPlayerCharacter)
{
if (HasAuthority())
{
if (Hat)
{
VRPlayerCharacter->HatMesh->SetSkeletalMesh(InventoryItemData.ClothingMesh);
}
if (Torso)
{
VRPlayerCharacter->TorsoMesh->SetSkeletalMesh(InventoryItemData.ClothingMesh);
}
if (Gloves)
{
VRPlayerCharacter->GlovesMesh->SetSkeletalMesh(InventoryItemData.ClothingMesh);
}
if (Pants)
{
VRPlayerCharacter->PantsMesh->SetSkeletalMesh(InventoryItemData.ClothingMesh);
}
}
}```
Im 100% sure that Im on the server when calling this function but it just does not want to set the mesh for the client. The mesh parts are set to Component Replicates
Yep that was it, thanks 👍
Who says the mesh of a SkeletalMeshComponent replicates
Okay so i'm debugging the "PostNetReceiveVelocity" and the velocity on that is 0, even after calling the "SetUpdatedComponent", does that indicate a replication problem or where is the "PostNetReceiveVelocity" getting the velocity from.
Never used that function so sorry for the noob questions.
That's a client function and it should be the one of the UpdatedComponent
On the VRPlayerCharacter BP
Why would that mean the mesh replicates
You only replicate the component that way
That doesn't mean the properties magically replicate
You need to make your own RepNotify variable for the mesh parts
If you need to set multiple you should wrap them into a struct
Oh yeah I completely forgot to set them into the GetLifetimeReplicatedProps
Ill try to add them there ty
ok it has a value now when I run the function with the "SetUpdatedComponent" on server, still no movement, I need to investigate further, but it's weird 'cause the way I had it working first was also calling "SetUpdatedComponent" on server and after that the ball applied the newVelocity
np I just try some different stuff, maybe I find my mistake.
What movement comp?
@thin stratus but thanks for the answers, it helped!
The projectile one
Ok just adding the mesh parts to GetLifetimeReplicatedProps was not enough but I got it to work with this:
void AClothingBase::EquipClothing(AVRPlayerCharacter* VRPlayerCharacter)
{
if (HasAuthority())
{
if (Torso)
{
VRPlayerCharacter->RepNotifyTorsoMesh = InventoryItemData.ClothingMesh;
}
And when RepNotifyTorsoMesh changes:cpp void AVRPlayerCharacter::OnRep_ChangeClothing() { TorsoMesh->SetSkeletalMesh(RepNotifyTorsoMesh); }
Is this what you ment
Yes
If you have multiple parts then maybe bundle them in a struct
So you only need one variable and OnRep function
The performance would be the same if I made OnRep functions for each of them right? I only have 4 different parts
Replicating those componenets isnt free though
Ok so if I would make a struct and then when the OnRep is called I would update the different parts again with SetSkeletalMesh even if it does not change?
No, server evaluating components for replication isnt cheap
Well I have to either replicate the struct or all the different parts of the mesh so in the end I will still have to replicate something
For now Ill just keep it with different parts and call different OnReps for them
Well they shouldn't be replicating the component anyway
The replication is inside that character
The component replication can be turned off again
Oh that is what he ment ok thanks
Hey guys, I want to replicate these two variables, which are compared to check if the mouse is going up, down, left or right on the screen, and then does a corresponding animation. Im struggling having this work properly on the client, what am I doing wrong?
Event from client
Feeding those values into the logic, an event run on owning client
Nothing you have there sends anything to the server.
So if I changed the event to a RunOnServer (tried that earlier aswell), and maybe sent that to the owning player? 🤔
Well, how are you sending your mouse stuff to the server in the first place?
"Replication" only happens from server to client, not the other way around.
Hmmm, so in this case I shouldn't be getting the variable on the client, but in the Server event instead, and then send that to the owning client?
The mouse stuff has to start on the owning client, surely? How does the server know what your mouse is doing?
@thin stratus If your interested I found the problem: The blueprint component got corrupted by the live coding, I reverted to an old state and carefully implemented everything again. Now everything is working... that's was kinda frustrating 🥲
Awesome, got it to work, thanks a lot 🙂
np
Yeah I don't use any form of hot reload. Not even live coding
Just too unreliable
Yeah looks like it... but the ball movement looks good now 😄
When moving at high speed it's still a bit jittery, but I think that should be finde for now.
I will look into predicting stuff in the future i guess
you only predict what local client caused with direct input
for everything else you just have to wait for server to replicate
How "bad" is tracing really? Is it ok to trace every 0.2 seconds on each client? Or should this be avoided? For stuff like interactions and pickups.
tracing isn't bad
tracing is plenty fast. Do hundreds or thousands of traces every frame and maybe you'll have a problem.
don't bother thinking about it until it gets to that point.
Ah, perfect. Thank you!
thats goofy
input happens locally only
only way server knows about it is if it's told
Yup, I redid the setup and got it working now 🙂
Ive seen some posts online saying blueprint interfaces do not work in multiplayer. This true? It does not seem to be firing on the client. Only the server.
blueprint interfaces are not affected by multiplayer
it doesn't fire on client because you haven't called it
So the message has to be called on multicast?
I’ve set it up like this “input E -> pickup event (run on server)”
that should not run on clients at all
actors involved and whatever is managing your inventory
should replicate that, no rpcs
Hm, alright. I’ll keep trying. Thanks!
In Unreal Engine 5, I am developing a multiplayer game where the PlayerScores variable, an array of structs (score, ID, player state), is stored in the game state. When a new user logs in via the Event OnPostLogin in the game mode, the game state is cast, and the new user is added as a player with the struct data. Each player is also assigned a unique ID.
When transitioning between levels, the PlayerScores array is stored in the game instance, and after the new level is loaded, the data is retrieved from the game instance and added back to the game state.
The problem I am encountering is that after opening a new level, the player state resets, making it impossible to track which scores and IDs belong to each player. Additionally, new player states are created when opening a new level, disconnecting them from the PlayerState stored in the PlayerScores array.
I would greatly appreciate any suggestions or feedback on how to resolve this issue.
You are totally reinventing something that UE already handles for you
You already have the PlayerState that should keep track of the Scores
The PlayerArray on the GameState is already handled for you
And when traveling between maps while being on a Server you should ensure that you SEAMLESS Travel (boolean on GameMode), which allows you to use "CopyProperties" in the PlayerState to move the data to the next PlayerState.
There is 0 need of creating yet another array of structs
Thank you @thin stratus you are a legend!
I have an issue with replicating a value change on a UObject within an array. I have an array of UObjects that I believe are replicated correctly (SupportedForNetworking(), GetLifetimeReplicatedProps(), and ReplicateSubobjects()). Now, I don't know if this is normal behavior, but if I change a value within the UObject and also change something within the array, like adding or moving an element, it all replicates including the value on the UObject, but if I only change the value in the UObject nothing happens.
Is chaos destruction okay to use in multiplayer? if it only plays for say 2 seconds while a rock breaks, then gets removed
I know they use it in Fortnite, but I suppose the destruction pieces themselves are not replicated, but simulated on each client? Just guessing here
yeah that was my thinking, they dont need to look the same really
I've got my Blueprint interface a step closer to working when calling it without RPCs. Now the player picks up the object just fine, problem is, since it gets called through the client and not the server, how do I destroy the object after its been picked up?
The "Execute on server destroy actor" event does not fire when the client is picking up the weapon
Its set up like this now, the client presses a button to pick up the weapon hes looking at, calls a interface message on that actor to be picked up.
The pickup actor then sets the new weapon on the player, spawns a new pickup of the old weapon and destroys itself.
But spawning and destroying should only happen on the server, so how can the interface message only be called on the client?
Think I figured it out. Having an event back to the pawn and handle the spawning and destroying from there
Are ServerTarget not working in 5.1.1?I got this erros when packaging my servertarget: Server targets are not currently supported from this engine distribution. BuildException: Server targets are not currently supported from this engine distribution. at UnrealBuildTool.UEBuildTarget.Create(TargetDescriptor Descriptor, Boolean bSkipRulesCompile, Boolean bForceRulesCompile, Boolean bUsePrecompiled, ILogger Logger) in D:\build\++UE5\Sync\Engine\Saved\CsTools\Engine\Source\Programs\UnrealBuildTool\Configuration\UEBuildTarget.cs:line 733 at UnrealBuildTool.BuildMode.CreateMakefile(BuildConfiguration BuildConfiguration, TargetDescriptor TargetDescriptor, ISourceFileWorkingSet WorkingSet, ILogger Logger) in D:\build\++UE5\Sync\Engine\Saved\CsTools\Engine\Source\Programs\UnrealBuildTool\Modes\BuildMode.cs:line 741 at UnrealBuildTool.BuildMode.Build(List1 TargetDescriptors, BuildConfiguration BuildConfiguration, ISourceFileWorkingSet WorkingSet, BuildOptions Options, FileReference WriteOutdatedActionsFile, ILogger Logger, Boolean bSkipPreBuildTargets) in D:\build++UE5\Sync\Engine\Saved\CsTools\Engine\Source\Programs\UnrealBuildTool\Modes\BuildMode.cs:line 275
at UnrealBuildTool.BuildMode.Execute(CommandLineArguments Arguments, ILogger Logger) in D:\build++UE5\Sync\Engine\Saved\CsTools\Engine\Source\Programs\UnrealBuildTool\Modes\BuildMode.cs:line 242
at UnrealBuildTool.UnrealBuildTool.Main(String[] ArgumentsArray) in D:\build++UE5\Sync\Engine\Saved\CsTools\Engine\Source\Programs\UnrealBuildTool\UnrealBuildTool.cs:line 648
WriteFileIfChanged() wrote 0 changed files of 0 requested writes.
@broken grail u have to package from source
Thanks i am on it. So i guess i can delete the engine that i downloaded via the homepage as installer. And when a new version drops and i want to update i have to update my files via git again and compile again?
If you're building engine from source, then you'll have to merge whenever there's a new git drop.
You might have local engine changes, so it's not a simple drop and replace.
I’d heard there’s a plug-in that helps implement prediction with correction into more home brew systems (not using GAS), is that true? Googling provides conflicting results
Anyone know why when I print a string from a BP Function Library it doesn't say server or client? It just prints "Hello"
The BPFL is being executed by the server
are you playing standalone, as client, as listen server?
Client
It actually wasn't causing my issue tho, afterall. I was populating arrays on BeginPlay in one BP and trying to read them on BeginPlay in another BP and ofc they weren't ready yet.
So I put in the jankiest of all jank method for checking that the arrays were done lol
it has no world context to figure it out
I should replace this with a custom event that fires on the Complete pin in Game State when the For Each Loop is done.
or maybe there's a way to do it with an Interface
or an event dispatcher? 😛
yeah, only done that once... need to relearn it
you create an event dispatcher in GS (below variables), add any payload it needs to carry as inputs
and CallMyEventDispatcher when that for loop is done
whatever the class that screen is from, instead does BindEventToMyEventDispatcher from your custom GS class pointer
and when GS calls it, the handlers bound to it all execute
nice, lemme try that now
bind node has a red square pin bottom left
you pull from that and type custom event
that will put your handler function on the event graph
get game state -> cast to your custom GS -> Bind
oh, aye, but you need an execution pin to cast from
note that you have 2 scenarios here
BeginPlay is "too soon"
GS finished for loop before your bind logic runs and after your bind logic runs
in scenario 1, you need to call your handler manually, as the call was already done by the time you bound it
ya
so my other logic is in another blueprint (a Loot blueprint, for stuff to interact with on the ground)
if the GS event dispatcher fires, after the for each loop is complete (on the complete pin) I can call an event in the other BP?
binding event to an event dispatcher means "hey, whenever you are called, execute this event"
so just need to make a custom event in the Loot BP and bind it?
if thats what you need, keep in mind i don't know your code
k I need to re-read what you wrote a few times and see if I can get this
thank you
So I'm still confused a little, the Bind Event to Arrays Are Done won't execute unless it has an execution logic already connected?
Should I just put it On Tick?
so basically it won't even run but once, and it won't consume much resource on tick?
seems like what I did originally was make a manual dispatcher with a bool in GS that gets picked up by the Cast to GS after the arrays load (checking true/false every tick til then) and once they load it sets the bool and then on tick it stops going any further
each event should only be bound once
aye but my struggle is how to feed that execution pin on the bind
which one?
you should call BindEventToArraysAreDone when you start doing the thing
or begin play maybe?
ok so on begin play it becomes bound, and stays bound, and will eventually execute once GS does it business. that makes sense
yeah, you call BindEvent to tell the system, this is what you should call, when you call it.
then it just chills until GS says hey bud, it's titme
time
think I get it now, lemme hook it up to begin play
event dispatchers (know as delegates in c++ because why wouldn't we name things differently) keep invocation lists
in this scenario, its a dynamic multicast delegate, meaning it can have more then 1 event/function bound to it and its exposed to blueprints
the event dispatcher keeps all bound events in its invocation list (pointer to object + event Name) and calling it makes it go through the entire invocation list and execute each event/function on it once
Hey there guys, has anyone ever replicated time dilation? Should we use a replicated notify variable for the time float or a multicast? What’s the best approach to fire it on a montage start/end notify?
damn I think it works like a charm
that "Generate Name" function is yuge, and takes a moment to run
if its called by BeginPlay in GS, and its synchronous
actually, I am wrong. What takes a moment to run is creating the arrays that the function depends on
it doesn't matter how long it takes to run, the game will wait for it
and there is no guarantee of BeginPlay order, so some of your BeginPlays can happen before and some after the GS loop
do take note that your GameState doesn't need to know that object that binds an event to its dispatcher exists
right so no weird references that could break
i'm gonna dispatch so much shit
thanks for explaining this in multiplayer btw, it's not on topic here
can/should i replicated a FGameplayTag?
yes
note that is maps to an integer and replicates as integer
not as whatever dot separated text you have for it
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Avalon")
FGameplayTag GenderTag;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Avalon")
FGameplayTag RaceTag;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Avalon")
FGameplayTag ClassTag;
i just created the above, and thought hmm, ok the only thing i need to replicate is the ClassTag on the blueprint
you don't need to replicate tags that are defaults of a class
as they are defaults on the clients as well
only if you change them at runtime
the Class will need to be set (
i could create multiple bases
and then forget replication
thank you @winged badger 🙂
you gave me a good idea
Does the HUD class persist between deaths? Or is a new one created on spawn?
hello guys how can i replicate GetHitResultUnderCursorForObjects's actor to server? i take it in gameplayability class so it is replicated class and i cant create replicated variable in it.
In ListenServer scenario, how do I force all connected players to connect as spectators (at first)? Currently I'm overriding MustSpectate_Implementation where I compare NewPlayerController to first local player controller, but I'm not sure that the first player controller will always be the host
HUDs are owned by the player controller, plus the base pawns do not have the concept of health or death, so they would persist
RPC the result to the server.
client authoritative variable and/or RPC it 🤔
every click an RPC seems like quite a spam... but I am not sure, let somebody that actually knows their shit answer 😅
how would I optimize a playercontroller in a open world survival game so it's not taking up as much data
for a dedicated server
Anything stand out in my netprofiler?
Is there a way to hide a projectile that was spawned on the server from the client that shot it?
Reason being the client spawns their own proxy projectile so it feels more fluid if they were playing with latency.
I'm using Blueprint.
The "easy" way would be to simply set the projectiles owner to the player who shot it and set "owner no see" (https://docs.unrealengine.com/4.26/en-US/BlueprintAPI/Rendering/SetOwnerNoSee/)
The problem with this method is that you don't really get any way to correct the client's version of the projectile if the server disagrees with where it spawned or ended up. That's somewhat advanced ™️ network prediction territory though. Basic idea would be to send an id with the request to fire a projectile, the server's projectile keeps that id and then the client can interpolate its own projectile to the server's projectile's location once it receives a projectile with that id.
I can just make 2 projectile Proxys then. One for the client that is just visual, and the server, which is set to no see.
I think that would do the trick
When it comes to prediction, it's very overwhelming as somebody who doesn't know any actual programing outside blueprint.
Right - it's not something I'd recommend especially if you're just doing it in blueprint.
What I mentioned first should be a pretty serviceable method to get started with.
And yeah - you're just spawning two projectiles, one "fake" on the client and one "real" on the server that the owner never sees.
Yeah, well thanks for this. I think I attempted the Owner no see, but didn't have the owner set at the time.
Okay, setting Owner no see worked, and then on the client, I just set the mesh part of the projectile to be seen for their projectile.
Now the only remaining issue I have is that the particle effect, and Decal still show up even if the server projectile is hidden. It is Delayed, and I would like to also hide those from the owner/client who shot.
I believe SetOwnerNoSee is per-component, you'd have to set it on each. Ideally the actor wouldn't even be relevant to its owner but I don't believe that's something you can control from blueprint alone.
you might want a more detailed network insights trace
this is basically just a table with numbers on it per class
Is there a reason why spawning a Projectile on a Server makes it appear like it spawns much further from the point it should? Would anybody know how to fix this?
homie, can you shine a light on me and send the docs for this profiler??
Does anyone know how to get visual studio properly working inside macros like UE_SERVER?
how can i make something only run for the owner? if i use has auth to remote, it only runs for clients and the listen server cant do it themselves
just dont make a rpc to spawn a projectile and spawn a projectile in some condition
is it is locally controlled? then the server wont run it but clients + listen server player will?
it will yes
Is there a built in way to know that all Clients have had a variable updated and are matching so that we can continue or server would have to manually perform this check?
send RPC to the server saying that a client is ready, if you REALLY want to be sure.
no - but any code that depends on that is inherently scary
I'd say its in the spirit of Halloween but we are not in that month yet so I have no excuse atm.
I do think it is not required for me like I originally thought so no need
You could do what LeoStone suggests. You basically have each client send some acknowledgement to the server and the server counts how many acknowledgements it receives and compares against the number of players it expects (usually this would be all players but you might want to exclude spectators for example)
we do similar for procedural generation
clients report back when its finished loading the map, once all clients have done that, server will continue and start the game and dispatch beginplay's etc
I'm trying to do something simple - set the initial speed of a projectile based on some stats prior to spawning the projectile.
I'm having trouble doing this though. If i set it in the construction script, it gets jittery on the client side. What's the solution for this case?
are EndPlay and BeginPlay expected to be called for actors saved during seamless travel in AGameMode::GetSeamlessTravelActorList?
nevermind seems like thy aren't
ok, now how do I make editor to start with net.AllowPIESeamlessTravel = 1? I know that you can do it in DefaultEngine.ini, but i'm not sure what the header in square brackets should be
Each config entry has to have prop of the same name
Find it, then look what class is it in snd what config specifiers it has
That drtermines the header and which .ini
I think its [Script.ClassNameWithNoPrefix]
it seems that simple
[ConsoleVariables]
net.AllowPIESeamlessTravel=1
worked
Des that work by now? That outright crashed for me the last time I tried it
I have a dedicated server running on an Azure virtual desktop and while everything in the game works just fine, movement and rotation are a bit laggy (playing as a client in unreal works just fine)
I tried deleting performance heavy actors but nothing changed it looks like it’s an issue not caused by connection/performance
Any suggestions/help?
For EOS, do you have to create a project in C++?
If you’re not using an out of the box plugin I believe yeah, check Betide Studios channel, they cover both approaches
Is this supposed to be called on Client & Server? DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnClearTarget); UPROPERTY(BlueprintAssignable) FOnClearTarget OnClearTarget; OnClearTarget.Broadcast(); Or am I missing something?
There's nothing replicated about delegates
Ah okay
I know about server reliable functions, but I needed C++ to call bp replicated
Then you need a multicast RPC, which might be confusing because of the shared terminology
This made me a bit confused
On an Event Dispatcher, you can set Replication to “Replicated” or “RepNotify” and conditions. These settings are usually on Properties(C++)/Variables(BP). An Event Dispatcher, in my mind anyway, is more like a RPC(C++)/CustomEventNode(BP). It’s a function delegate/event that gets called and then triggers on the recipient. You mark them as rel...
You would need to make the function with the Broadcast() call a NetMulticast UFUNCTION
There's nothing replicated about event dispatchers
Has anyone ever changed the owner of a dormant actor and it no longer fires rep notify events?
I have a weapon that is dormant and whenever something is updated I flush the net dormancy. Before changing its owner everything works perfectly after a new owner is set and the weapon is equipped (Which is a rep notify variable) the rep notify doesn't fire. So all of the client sided logic like showing the mesh or linking the animation layer never runs.
it's not ideal but it may be easier to just recreate it entirely when the owner changes 😦
I'm definitely no expert but I imagine the net owner changing might not reroute the repnotifies after the fact
Yea I was trying to avoid that but I cant find anything on why its not sending rep notifies so I'm probably going to just destroy the actor and respawn them. Sucks because that means everytime a player dies they spawn in a new array of weapons they had equipped.
why does the owner have to change when they spawn in?
you could maybe avoid destroying the actor connection
Currently when the player dies the owner pawn is set to null and when they spawn in again and possess a pawn I set that pawn as the new owner of the weapons. I could try setting the owner to the controller or the player state since those never get destroyed.
But then I dont get the benefit of owner net relevancy since those actors are always relevant.
you can control net relevancy yourself
mind you, there may be some other more simple solution
Definitely much more experienced people on here for mp stuff than me
Simple solution is just to destroy all the actors and spawn them back in when the player controller possess a new pawn. Its just not the most optimal since a player could spawn and die OFTEN ... If they trash lol
Welp, just found out that it wasn't working because while debugging the rep notify was getting missed. When just playing and dying and respawning everything is working as intended
is it the the breakpoint making it time out if you freeze the exe? 😮
scary
I know that some things that rely on platform time will get weird with that
Not sure actually. I keep running test, each time is different. Once I died with my ability out and came back, my primary weapon fired the on rep. Another died with my secondary out after just using my ability I came back with no weapon but was in the state of selecting an ability target area. lol I did however find out that if I manually equip a weapon like by hitting the key that weapon slot is on or the scroll when the on rep will fire. So my guess is its a time based thing but I'm not really certain
In order to disable input, let's say for the end of the game, is the only way using a multicast RPC to call DisableInput on every client locally? This feels like trusting to client which doesn't.. sound safe. Am I missing something here?
Or I think you can make an RPC with validation that server doesn't accept client's input at that moment too
How do we do the server doesn't accept client's input part?
https://docs.unrealengine.com/5.0/en-US/rpcs-in-unreal-engine/
Check the validation block here.
Okay but this is for straight server RPCs. What about CMC, do we have control over that as well?
I'm sorry that I don't understand what CMC is.
Character movement component
Like, we're not sending WASD or mouse inputs over RPCs right?
There are functions to move the character and rotate the controller to make the pawn rotate as well
Can those be disabled with validation as well?
Ah, okay. If you are talking about this, so the clients are also simulating the character movement.
https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/Networking/CharacterMovementComponent/
It is quite complicated and I think you can do something customized from getting through this document. But I probably won't suggest doing so...
The CMC is handling stuff for you. It's sending moves to server
What I'm asking is if it's possible to disable that behavior from server
Yes that can work, thanks
I mean, if you can call Unpossess, then you are on the Server
So you can set some flag on the CMC
Or change its MovementMode to None
My concern is disabling input completely for a user, not just movement. Like DisableInput. I asked "what about CMC" because I was suggested to use RPC validations in order to see if I should accept the input or not. Since both unpossessing and using DisableInput prevents all inputs from that actor, character for the case, it seems suitable to me
Unpossess and DisableInput are two different things though
You can't possess on the Client
But you can EnableInput
So they aren't equal in cheat protection fwiw
If possess is fine for you, then do that
Or unpossess fwiw
Yeah that was my initial question here, I was asking if there was something like DisableInput that I can call from server for the clients instead of doing it locally
I don't think so. Let me double check
So I guess unpossessing is the closest that I can get to that logic, assuming all my inputs are in the character
You have SetIgnoreMoveInput
On the Controller
That ultimately gets pushed through until the MovementComp
bool UPawnMovementComponent::IsMoveInputIgnored() const
{
if (UpdatedComponent)
{
if (PawnOwner)
{
return PawnOwner->IsMoveInputIgnored();
}
}
// No UpdatedComponent or Pawn, no movement.
return true;
}```
But not sure it's actively used
It controls locally if the Pawn can AddMovementInput
But probably not on the Server
You could use it in your own CMC though
Hello everyone, I have a question that is kinda very specific. I am currently working on a project with some custom split screen for 5 players (but I guess this does not really matter). The case is that we have local multiplayer and split screen. There are some different widgets on each screen. And there is an issue with a touch. We are using 5.1.1 version and the touch does not work in standalone mode or in package. However it works normally when running it editor (PIE). One person tested it on other engine versions and it also does not work on 4.26, but it works for example on 4.23.
Does anyone ever have such case and might know what is going on.
In the picture, only top-left one button is clickable
Or you can use the ability system to give them a dummy passive ability that cannot move🤣
There're always tricky ways to make the thing work 
If I'm only interested in Server->Client replication of sub objects, it is enough to call AddReplicatedSubObject() and RemoveReplicatedSubObject() on the server, right? ReplicatedComponentsInfo on an actor doesn't seem to be replicated also.
There are guides for replicating subobjects around.
To replicate UObject, instance must have owner (AActor), who can replicate this. AActor must have next functions (You can use AGameState for storing items) virtual bool ReplicateSubobjects(class UActorChannel *Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProp...
im facing a big problem rn, i have a character who can shoot a projectile but after he spawns the projectile i make him possess that projectile so he can control it (turning left/right) and after the lifetime is over or the projectile hit something i want to possess the character who shot the projectile again.
it works fine on the server, but now on the client i got the problem.
- the character doesnt stop moving after possessing the projectile
- when the character gets possessed again he takes over the last rotation of the projectile and also he gets teleported back to the location where he shot that projectile (so if he moves while shooting the projectile , he will continue moving forward until he gets possessed again, and then he teleports back)
but i only have that problem on the client
can someone help me?
Return of the Redeemer!
When you say doesn't stop moving, do you mean that they carry on in a straight line from what they were doing? Or that they still respond to the client's controls?
they carry on a straight line from what they were doing, but only on the client, on the server it stops
Sounds like it's not receiving the "key up" events because you stop possessing it.
Do you do your movement input on your character class?
yes i do
well i did it a bit different
i can control the players speed with "W/S" when i press W it increases the maxwalkspeed and when i press S it decreases the maxwalkspeed
and in the even TICK i do "Add movement input value = 1"
which means there is no KEY UP event
That'll be why then.
but why only on the client?
Good question.
i have the same problem with the rotation
i simply use "add controller yaw input"
so when it possesses the player again he takes over the last rotation of the projectile
So store the control rotation and reset it when you posses teh character again.
but how can i reset the control rotation?
as far as i know i can only get the control rotation but not set
Shrug
well so the movement is fixed now, thank you
but still the rotation makes me crazy
it just takes over the control rotation of the projectile
i have never seen that before to be honest
still doesnt feel like the correct way, i think its a multiplayer issue because it does work on server
Pretty sure you need editor for rhat
But if you want shitty internet just connect you pc wirelessly over mobile hotspot
I have an issue with replicating a value change on a UObject within an array. I have an array of UObjects that I believe are replicated correctly (SupportedForNetworking(), GetLifetimeReplicatedProps(), and ReplicateSubobjects()). Now, I don't know if this is normal behavior, but if I change a value within the UObject and also change something within the array, like adding or moving an element, it all replicates including the value on the UObject, but if I only change the value in the UObject nothing happens on the client.
what is your test case for this?
hm maybe its not callled dedicated server 😛
second, you're not joining a dedicated server from 2nd event, you're telling them to open the level themselves in listen mode
hmm but it works if i use 2 clients on test ?
joining someone else doesn't happen with open level
most common technique would be creating session on host, then finding and joining it from client
most basic one is ExecuteConsoleCommand open ip:port
hm
My use case for this is an inventory system, where the items are objects.
i meant if you're testing it from OnRep_InventoryArray
the pointer to your UObject doesn't change because a value in it changed
so it would have no reason to fire
array remains exactly the same
if you're using c++ i strongly suggest using a FFastArraySerializer instead of TArray, replicate structs with item data and create UObjects locally on server/clients
its capable of individual per item callbacks for add/remove/change
Ah yes I see, my bad. For testing I just tried on tick getting the currentAmount. Also for FFastArraySerializer I will have to look into that, thank you for the suggestion.
so yeah i'm having an issue that's breaking my patience on my online multiplayer racing game where when i try to teleport a vehicle that goes out of bounds back to the track an invisible actor spawns in the place the vehicle was teleported, but it only affects other players, the thing is, i can't see what that actor is even if i unpossess the vehicle during gameplay, also tried to use a trace by channel thing and nothing
ik it's rare to have help in here (not blaming anyone) but yeah just ping or dm me if you have some help
ik it's rare to have help in here
Well - that's one sure way to encourage people to not help you.
I've seen worse
i'm just annoyed, don't take it personally
So is the vehicle teleporting to the destination at all? And by the place the vehicle teleported, you mean the origin or destination?
2 days trying to fix this
I was reading through their problem and was like, "Okay, well let's try this". Saw that comment and was like, "Nah. Nevermind."
yeah it does teleport on both the client and server, and it does get teleported to the destination i give it
Eh, you break your head over something for 2 days, it can get very frustrating lol
yeah, thanks for understanding and helping
So you get a random actor spawning at the origin or at the destination?
at the destination just like the vehicle
however it does not affect the player that was teleported, it only affects the other clients
and yeah if another client gets teleported (goes out of bounds) all the other clients get affected besides the one that caused it
it spawns like a invisible small object
at least from the collision it seems like it
Hmm, could it be just a box collision @solid hawk ?
@winged badgerhttps://youtu.be/1MA9_U3XRZs
acording to this tutorial from wich i follow this works ?
This video will show you how to create a multiplayer game using Unreal Engine.
- Links -
Website: https://elias-wick.com
Patreon: https://www.patreon.com/EliasWick
Twitter: https://twitter.com/EliasWick
Instagram: https://www.instagram.com/EliasWick
and i can join with 2 clients from my pc atleast :/ ?
it's what i've been trying to figure out, i tried to add a trace by channel node in a event tick to see what would output from it
and nothing
Does your vehicle have a box collision component?
it does have more components besides the base mesh yeah, a character riding the vehicle (which has no collision) and a fork that moves up and down (it's a forklift xD)
it's just weird i can't see it both in player collision view
hey there, quick question guys. If we need a replicated blueprint event to be implemented, would the approach be something like a repnotify that calls a multicast delegate? Or is there a better approach for this?
anyway i'll just keep looking for it, maybe i've been badly replicating the teleportation part and a component gets stuck or whatever
anyway, thanks for your help, if you have any more ideas please tell me
Could be, I’d try to play around with each component on the vehicle that could cause a collision and see if you can narrow it down maybe
Like temporarily disable its collision and test or something along those lines
But yeah, replication is a likely culprit
There is no such thing as a replicated BP event. An event is either an RPC or not.
That said, I believe what you're asking is about an Event Dispatcher (which is also not something that is replicated).
As for using Onrep or not - it is quite straightforward:
If you need STATE to be sent to clients (IE - "the character's mesh should be this"), then you use Onrep.
If you need STATELESS to be sent to clients (IE - "this one-off sound should play"), then you use an RPC
If you want to call a multicast delegate inside of your Onrep or RPC, that is completely up to you.
hmm I see what you mean, the reason why I wanted an event is because it's actor component that calls a bp event to be implemented by the character, they have no references other than being attached
Think of it this way.
Does it matter if a client misses the thing? If it DOES matter (stateful), use a repnotify. If it doesn't matter (not stateful), use an RPC.
You'll find yourself using RPC mostly for cosmetic stuff
it's for replicating or not at certain moment bOrientRotationtoMovement
I don't really need to send the bool, just toggle on/off so I'm guessing maybe not stateful
I did some digging into the FastArraySerializer and it doesn't seem to hard to setup. But what "item data" would I put into it? I guess I didn't really mention it but I was using uobjects because I could implement just about any function or variable I wanted without hassle, and I am not sure if fast array serializer would allow me to do that.
it is stateful
whether or not you're orienting rotation to movement is stateful
whether or not a sound got played is not
but you better learn the CMC in and out if you're doing anything wacky. It does things different
I see okay
yeah, possibly a custom CMC would help covering all edge cases for things like that
$350 plugin, interesting
I'm curious if something like this would be of any value at work. Probably not.
on that note: when is epic putting out their new and improved movement component?
Is that a thing? I dind't see any milestone in that regard
The more I deal with network + CMC the more I'm noticing issues, so I'm in a desperate journey of finding a solution
someone at work was talking about this... years ago, when they were trying to get GAS and movement to play nicely over the network. Some bug or limitation in the current movement component precluded it.
I don't know if this was announced, or something they said to my coworker over email or what.
Yeah, I believe nothing is coming short term, more than extra spegatthi related with Iris
at least judging by the source code diff
Hopefully, one day...
it won't, you replicate networked data from your UObjects, then use it to instantiate and initalize UObject on clients from replication callbacks
If it's as good as everyone says, it's probably worth 100x that. But it depends on what it's actually doing.
I'd be interested to see if it's just a more generalized CMC or if it's actually doing something drastically different
I see. I'm wondering if it supports root motion + arbitrary rotations
Trying to find more reliable ways of replication root motions with rotations, I still have an annoying bug in Vanilla CMC causing teleporting overtime
so, yeah, saw this and I might consider
https://forums.unrealengine.com/t/a-holistic-look-at-replicated-movement/265041 I found this gem last week. Might help.
I'd also be interested in seeing a video of someone who bought that GMC plugin and can show what it looks like with the "bad" simulated network lag profile set to everyone.
There was a video review of someone saying this plugin saved their game.
For what its worth - this plugin also has WizardCell's stamp of approval
Probably around the same time as their NPP.
Also, do note - they are planning for a pretty major update with the GMC plugin.
What do ya'll think of this free plugin?
https://github.com/Reddy-dev/SMN2
Kinda like a free GMC Lite alternative
I need to find that YouTube video (State of Unreal I think) where an Epic Games developer presents the Replication Graph and how it is used in Fortnite. It was a very interesting talk presented I think 3 years ago. I can't find it on YouTube. I don't know if it was GDC or it was an Unreal event, but I am 90% sure it was an Unreal Event.
Anyone know where I can find it? It was pretty big, people here definitely saw it. Surprised it's taking me so long to find that video on the internet.
I found this one, but this is not it. This doesn't introduce Replication Graph https://www.youtube.com/watch?v=KHWquMYtji0
Fortnite has served as a development sandbox for UE4, and in this presentation from GDC 2018 we explore the effort involved with taking FNBR from 30fps to 60fps on consoles.
Learn more at http://www.UnrealEngine.com
You are looking for this one: https://www.youtube.com/watch?v=CDnNAAzgltw&ab_channel=UnrealEngine
Working on a multiplayer game? Are there many players in-game together? On this livestream, our networking team will demonstrate 4.20's new Replication Graph Plugin and the server optimizations that were implemented for Fortnite Battle Royale.
NEWS
Unreal Engine Drives Monster Puppet for The Mill and Monster.com
https://www.unrealengine.com/...
It was really just "replication graph unreal engine"
Hi everybody! does anyone know if when you are running a listen-server setup, if the server disconnects is it possible to transfer ownership to any other client at runtime?
ForExample: Diablo 2 on unreal engine. I'm the Server and my 2 friends are clients. If I disconnect I want them to continue their multiplayer session normaly.
Not without a pretty massive amount of work.
It's a pain. The game I worked years ago like the game designer wanted this feature and we persuade him not doing so. Listen server is not designed for this.
its okey. its not neccesary at all. just a nice feature if it comes out of the box
Assuming you have all the pertinent state being synced between the clients and have the capability to save and load, it wouldn't be too hard to detect the host drop and recover with one of the clients as a new host. Totally seamless though? no way.
It's basically the same as saving game, disconnecting, starting new session, resuming
Idk enough about sessions to know if clients can be aware of each other in them but you'd want some protocol to decide order of succession etc.
Does anybody know if it is possible to animate the screen (mainly size) for local multiplayer when removing or adding the players? I assume this is not possible directly from UE, but changing source code is an option. Because by default when we are removing local players or adding them the change is done immediately
Guys I am using OWS and on Unreal V 5.2 it's giving this
Hey guys, has anyone had an issue with connecting packaged Unreal Engine build to a session hosted in the editor in PIE mode?
that looks like missing include
or you're using rider and it ninja included something it shouldn't had
My server's pawn automatically unpossesses even without the code in my game mode, which I later added so he would spawn and possess another pawn which works for the client but the server just remains unpossessed.
whenever your server function is called
its Target pin get a new value
so if your client logs in before server/host delays have passed and it spawned
the Target pin has a reference to client PC
PostLogin is server only event, so it doesn't need a server RPC
nor does anything executed on GameMode since clients don't have one
Delays for init are generally pretty bad
you don't need to destroy previous Pawn explicitly
i think my server doesnt have a player controller
because i searched for it through the level
Possessing a new Pawn automatically Unpossesses the last one
but there is only one
if its a listen server, it does
it is but i dont see one in the search
if its a dedicated server then thats expected
no its listen only
also, your outliner has to be in server mode
for you to see 2 PCs
they are replicated to owner only, so host has 2, client only has its own
how do i put it into server mode
theres only one both ways
toggle on or off
thats why the server unposses
when the client spawns
because client takes over the PC
it doesnt
idk i still havent figured it out
hy i have a doubt, im complete beginner in this just learning stuff so i was just randomly thinking had this doubt there are so many videos on yt which says multiplayer they make the game but how do they uk setup a server so that my friends can play a built version of the game
is it hard to make a custom movement system and have it work with the default replication? I'm trying to port over my movement code but its stateless and doesn't fit with how unreal does movement with PhysWalking states ect. I tried to override StartNewPhysics function in my movement component but that seems to break the proxies
Using the Sessions stuff in Unreal. For servers they'll use a 3rd party service like Amazon or Google or DigitalOcean to host the dedicated servers. For listen server stuff, they'd use Steam or EOS to handle the connection part. Or they'd just open a port at home.
is there anywhere or any video where i can learn detailed process
Probably
Is a "Transition Map" an actual Level ? For seamless travel.
yes, usually a very lightweight/empty one
99% of the time it's an empty level
but still a level yeah
hi guys do we need source code for sure?
to do multiplayer ?
in unreal 5 or 5.1
Yea you need a source build if you want to use dedicated servers.
But not for listen hosted games.
So, I added a string print to the servertravel node and it prints out "server traveling!" but I see this on the client that joined the game, not the client that hosted (play as listen server) the game.
are there any free ones, also whats a dedicated server
You can google this
ya im googling rn xDD
Then don't start with multiplayer. Learn your way around and work up.
Hmmm just tried a normal character launch and I'm seeing a lot of net corrections, possibly because of the speed of it? Is it better for me to create my own custom launch instead to avoid the corrections? I would think that Launch shouldn't be correcting out of the box at all...
Toned down the strength, and it still has immense corrections at the beginning when trying to launch on client and server.
There are few ways to achieve a "free" multiplayer game setup. But none of them are perfect.
- Use listen server. One of the players becomes the server. (Makes it easy for cheaters.)
- Use p2p networking. (not really supported by Unreal Engine without lots of customization)
- Use your own dedicated server than you have the actual hardware for. (Example: an old computer)
- Design your game in a way that you let the community host servers themselves. (Rust for example)
- Carefully stay within the free-trial tier of a cloud provider with hard billing limits setup (will run out of free credits eventually).
But if you want the best performance and least amount of cheaters you have to rent dedicated servers.
ah no im not planning to make anytime soon just got curious how they host ue games thats it
so started googling it
icic ty
after doing a Level Travel my main Client´s character cant attack ppl or anything but the other clients can
is there something im missing with level traveling that could affect it somehow :/
its the client that initiate the servertravel that getts bugged somehow :/
hi all, is it possible for a client to keep ownership of a pawn they no longer possesS?
my client can swap between pawns, but id like them to still call RPCs on their unpossessed pawns
I see pawns UnPosess function calles SetOwner(nullptr), maybe thats what I can change
Yes. After the unpossession happens, you'd do a server rpc to transfer ownership back
Possession/UnPossession transfers ownership.
So you can either do what I said or change the source code. (I don't recall if possession/unpossession is virtual or not. If it is, makes it easier)
so I'd have client request ownership once they lose possession?
Pretty much
nice, thanks
so this is just after a server travel the client 1 cant affect others but the 2nd client works as supposed to ?
what could cause this im tottaly lost .O
at least you get both clients after server travel (how did you do it? and in what blueprint?) , one of my clients gets everything but the character (score, timer, map, etc all there).
@ivory bearwell a widget from the playerchar_Bp start the send and the gameinstance is doing the transfer really
this is everything related to the travel
@ivory bear any ideas ?
its like the first client is not on the server somehow
Getting a save object or the game instance from a player controller in a multiplayer game, will always give me the local client save object and instance, regardless if I'm server or client, correct?
Right. It doesn't automagically travel to the other side and bring that object to you
Thanks. I was getting paranoid of why client didn't save an struct, just noticed the save game happened only on the controller server side, which I guess translates in nothing saved locally in the client machine
Got another question, any techniques or good practices to fire a repnotify from an array change? either by adding or setting members?
You can use FastArrays for that
Per-item callbacks: pre-remove, post-add, post-change
If we use a delegate and broadcast it (C++) inside a repnotify, should it call the event on all clients ?
Replicating a variable that goes to all clients and has an OnRepNotify that calls a delegate, works on clients.
Should be quick enough to set up and test.
if the OnRep is C++ then you should manually call the OnRep function serverside
BP silently does this for you
Gotcha, I just wanted to know if this is a possible approach, probably not replicating for some bug here then, I’ll double check it
Yeah, it’s C++ side
That is probably the issue then
Thanks
you mean in the case that it's a listen server and you want the delegate to be called there as well as the clients?
what behavior are you seeing @cerulean lintel ?
if it's ROLE_Authority then you'll want to manually call an OnRep in C++
since you're authority, there's no replication happening, so therefore no automatic OnRep call
mmm, depends on whether you want it called on a dedicated server vs listen server
Listen server
Currently it’s only running on server
yes, listen server won't get OnRep calls and you'll need to call it manually
do you want to call it on dedicated server?
checking for ROLE_Authority is going to return true for both of those
assuming it's some actor that the server owns
I want it to call on listen server and clients, it’s a toggle for on/off rotating to target
Character
Client traces and set replicated active target (AActor*)
I wanted to trigger the rotate to target event inside the notify
Does this really need to use network bandwidth to trace on server? Or can I just repnotify the active target
I'm not sure I understand what you're asking.
Traces on the server don't use bandwidth.
The trace function is not a server function, is a local regular function
But it sets the repnotify variable
Which holds the delegate I want to broadcast to all
let's start over
What is it you're trying to do? Then I'll tell you how I would go about doing this. Then we can figure out where our approaches differ and talk about them.
Ok, so basically I have a regular function (not replicated) that traces and based on the result sets ActiveTarget (Repnotify)
This one is replicated
nope, don't talk about code
tell me about the gameplay you're trying to do
Ah
I have a target system component attached to the actor
void ASomeActor::SetTargetActor(AActor* NewTarget)
{
TargetActor = NewTarget;
if (HasAuthority())
{
OnRep_TargetActor();
}
}
This is the general flow
It is supposed to change bOrientToMovement and other booleans of character movement true/false depending if there’s a valid target
a player controlled pawn? an AI controlled pawn? random NPC?
If you want the client to be more authoritative, you'd do a server rpc to set the target actor. Then the server would just call SetTargetActor
Player only
so each player has a targetting component on their pawn
Yeap
ok
I’m trying to replicate clients looking at their targets, player and players proxies
how does the targetting component get a target specified?
But it’s not required this approach to replicate the notify right
Trace result, blocking hit
Vinny, really going to need you to learn the terminology mate. It is quite important to be able to communicate.
You don't replicate a notify
I mean the variable holding the notify sorry
how is it triggered?
Blueprint side
I'm not asking about the code. I want to know about higher level stuff.
OnRep Notify is just a function that gets called when a variable is replicated. It is only called locally.
is the player doing it? on tick?
Input trigger
so a player presses a button, then their targetting component... shoots a trace to see if they're aiming at anything?
It is always called in BP, but in C++, the server has to call it manually
Basically yeah
So - if you change the variable on the server, you must call the OnRep function by hand (as I showed)
But, clients will call that function when they receive the updated value.
However - the OnRep will not fire on clients if the value did not change.
okay, which might hit an actor? another character? if so, you want all the other clients to know what it hit?
Ah, that might be the reason. Currently if no active target it gets a nullptr, may be why it’s not replicating
Correct, but no interfaces used
Instead using delegates
I'm just trying to figure out where information comes from, and who needs it.
I wasn't worrying about implementation details yet.
I can't debug what you're doing and where it's going wrong, if I don't know what you want to have happen.
Sure, no problem
all that said, assuming I understand, then I think your approach is reasonable
choosing a target does seem like a client auth thing
It’s just that I haven’t seen so far examples on “broadcasting a delegate inside a repnotify function” so I was confused if this approach is wrong
I call delegates inside repnotify all the time.
There doesn't need to be an example. OnRep functions are just regular ol' functions
if you're new, it's hard to tell what things are the same. :P
You'll end up doing delegate broadcasting quite often for UI stuff
yep
Gotcha, yeah, if this is fine
I’m totally down to it
I’m a bit new to replication yeah, not UE particularly
Yeah, for UI I thought the same for some use cases too
I’ll try out your suggestion snippet @quasi tide thanks!
Do you need it to be called if the value didn't change? Or was that a red herring in debugging?
I have two delegates for target set and cleared
But if the ActiveTarget won’t get replicated if it’s a nullptr
Then I’ll probably handle that in a boolean
Or check replicate condition
so it's not that ActiveTarget isn't replicated if it's null
it's that it won't get replicated if it doesn't change
could you use one delegate instead of two?
I would use one delegate that is OnTargetChanged or something like that. Let consuming systems handle null however they want.
I'm guessing clients don't need to do anything if the target doesn't change. But I suppose it could.
So doesn’t matter if it turns at some point to a nullptr will still get replicated
if it's nullptr and I set it to 1 then it will be replicated
if I set it to 1, no replication
if I set it to nullptr, replication
if you don't need to do anything if it didn't change, you could optimize by checking client side if it didn't change before you inform the server
Good point
Yeah, that works for me
I also recommend you test everything with "play as client" and not just standalone/listen server. It can be easy to take shortcuts for the host player and not realize it and then you have things the host does properly, but clients don't.
I've found implementing for "play as client" first forces me to address the hard parts, leaving me with the easy work of making sure it still works with listen server (for the OnRep oddities we've discussed here).
awesome
sorry if things were a bit more in depth than strictly necessary
it's always a bummer when you spend a bunch of time telling someone how to replicate a thing in some specific way only to learn they should have done ALL of it on the server and none of it needed to be replicated
:P
No worries haha I know there are many ways to achieve the same result but with different objectives so it does make sense
Hello, where would be the ideal place to put my API calling code to initialize character data? For instance, my API has the information like, character stats, current inventory etc.
Should I use one of GameMode functions to retrieve the data first, then spawn my pawn with the retrieved data?
Does anyone know the best practices?
Do you need to retrieve the data from server or it is saved locally? If it is from server, you will spawn the character from server anyway, so you might have a replicated variable which stores all tons of your character info (I guess by index for your items or other stuff) and search the asset by these indexes on the local client then spawn them.
It is on remote server and I make a http request, to fetch the data. Yes I am spawning the character on server. I just want to set character defaults and was wondering where is the correct place to do that. The request I made is asnyc, so I need to delay character spawning until I need all the data from web server such as stats, inventory, attributes etc.
I think you can spawn it first and make it invisible and after all the stuff is done, posses it and make it visible. Does it sound right?
Yes, that could be one way to do it.
I wish there is a better documentation somewhere, there are many methods in gamemode that can be overriden.
I think I will go with HandleStartingNewPlayer for now.
I stopped paying attention but this is false
Listen server host and dedicated server (the actual headless process running on a server) BOTH need manual OnRep calls after setting a replicated variable
On a listen server host there's no replication happening to the playing host. ReplicatedUsing calls depend on the replication system on the C++ side. Blueprint can handle that bit of boilerplate on its own
Checking net mode in some cases can be perfectly valid, you'd check against NM_DedicatedServer for if you wanted to spawn VFX or audio for example
True. I was more thinking that some OnRep don't need to go to the server. UI stuff for example. Agree on everything though.
https://gyazo.com/1d82df5c6ab0bf071d752fcaa1e1caae
so this is just after a server travel the client 1 cant affect others but the 2nd client works as supposed to ?
what could cause this im tottaly lost .O
I have different functions in my shops, like "BuyRandomCards","SellCards" (cards are items basically). And I want to RPC from a button in my widget so i need to cast an object that i own like PlayerController..
I think I got it but.. That would mean creating for each shop function a matching replicated event ?
Its fine i have like 10 functions but it looks like awkward
Hi! I have a out of the box multiplayer character which works perfectly well(rotates with controller yaw which is tied to camera controller)
now, i wanted to add some pitch and roll to this character, and i did this by updating the pitch and toll of a mesh
*roll
but this does not work well on remote proxy (seems like the mesh rolla and pitch get rotated, but immediately go back to zero value in the next frame)
any way to work around this?
It won't work because the network smoothing blends the mesh back to it's default rotation.
You can't really add pitch or roll to the default character implementation easily, it's designed to be an upright capsule that rotates on Z only.
hmmmmm
but it's only a visual representation
can i work around it somehow( rotate bone, or perhaps rotate a controller instead of a mesh)
hi guys, i just found out that if i have an Actor that is not replicated and i attach it to a Character's component that is replicated, the actor will move with this component and its movement is replicated to other clients...
How can i avoid this behaviour?
@chrome bay if i rotated controller pitch and roll and set the actor to inherit pitch and roll(just as yaw is inherited by default), do you think it could work?
No as the character pawn doesn't do anything with those
Actually i'm using the VR Character of VRExpansion plugin
And the "problem" is the GripMotionController component
When i grab an object, i attach it to this component
@grand kestrel I just realized and encountered that damn TImestamp reset on the CMC
Client of mine has a short 0.2 cooldown between 2 activations of a boost. The code was checking if the BoostCooldownTimestamp and the CurrentTimestamp results in a remaining cooldown of > 0
If the cooldown was triggered before the reset (e.g. 235 timestamp), and the next check would be after the reset, it could be that the function reports remaining time of e.g. 150
Cause CurrentTimestamp is then suddenly less than BoostCooldownTimestamp
We now added a check if similar to how the CMC does it to check if there was a reset and then adjust the math.
Might be worth keeping in mind for the CMC Repo
ok so i still have the bugg it not related to the servertravel but its from the start when i join with 2x clients the "host" client is not affected by others and can interact with other !?
@queen escarp Relatively sure that's almost impossible for us to debug, because that is probably a bug in your code
you but ive searched thru the web for a solotion or any tip or whatever but cant find it , it works if i have 4 friends joining theyre clients works fine (character) just the hostinging one cant interact with anything really
idnno how i should troubbleshoot it either really
Yeah then you have somewhere a code that specifically checks for Authority and Remote and only works for Remote
You really only have one SwitchHasAuthority in your whole project?
well i just started my project 2 weeks ago so yeah i think so
Hm okay
What does all not work?
Can the Host take damage?
Can the Host deal damage?
And the Clients can Take and Deal damage?
yeah
And your Damage code isn't doing anything that would stop the host from performing the damage?
Then you need to start placing Print Strings into your functions
And see where the Server stops execution
You can't debug this by just repeating the bug
Also both of these are Clients
yeah
When you say "Hosting Client" do you mean the one that has a Dedicated Server running on its PC as well?
and it can only be seen on 1 client the effects etc
Or just that it's the first one that joined?
server running on its pc aswell
But this also breaks in the Editor or?
dont have dedicated server playing thru "lan" i suppose ?
the thing is if i start a level with 2x clients everything works, but if i start form the "main menu" where i connect one client to the other(host) then the host is bugging i suppose
Are you testing this in the Editor?
yeah like in this chase if i start at the "specific map" with both clients it works as intended
ive tested both editor/built
Editor could be a bit strange
Because if you start in the MainMenu
And you select PlayAsClient
Then your Clients are already connected to the Server or not?
But if the same happens with a Packaged Server and Client, then nvm
oh
true
but if i test as a "standalone game" then that should simulate playing with others right ?
I never tried selecting Standalone and having PlayAsClient selected
I usually only test Dedicated Servers via packaged builds
Well the connection process
Actual gameplay, as long as not via MainMenu, is something I test in Editor
You can also start the Dedicated Server via .bat file outside of the editor
Still with Editor Cooked files, but at least it's its own instance
tbh I would try to either pakcage Server and Client
Or to use the bat file to start a proper standalone server
And see if that problem still exists
Before you are hunting an Editor bug
You packaged Server and Client in 3 minutes?
Just ensuring that you aren't mixing terms up
erhm, im packaging my project x) iddno i dont have 2 different onces, i dont have a dedicated server its just connecting to my pc i suppose :/ ?
Wait a minute
So, there are two different ways to play a Multiplayer Game
- Listen Server
- Dedicated Server
aye, listen server thats the one i use
Listen Server means a Player clicks HOST in their Game, and starts a game by opening with ?listen
Dedicated Server means a standalone Server is created that player can connect to
If you press "Play As Client" in the Editor
You are simulating a Dedicated Server setup
In your Videos, the Text at the Top Bar of your Window says "Client 1" and "Client 2"
In a Listen Server setup, the first player should say "Server"
erhm, ok so i think this is the problem then that the "client1" is the "server" and clients 2,3,4,5 are playing on clients 1 as a server ?
Well
If you aren't planning on doing Dedicated Server
Then don't use "Play as Client"
eh
Sorry, one sec
corrected it
Whew - I was about to have to reply 😈
Go back to work!
z)
Work don't start for an hour boss
well i mean i just went after a tutorial,
Either way, you should use "Play as Listen Server"
When you test multiplayer
And if you want to test connecting to each other
You should use "Play as Standalone"
Which ensures both players are unconnected
Your hosting Client, in Editor, should have "Server" at the top of the Window
ohhhh
And if you do the connection test, they should both say "Standalone" iirc.
Don't have a project at hand to confirm that
But if you have 2 Players, and you have both of htem say "Client", then you are testing Dedicated Server
Which you said you aren't planning on using
So that is wrong
Not that this would explain your bug
But at least you aren't mixing stuff up
aye this really clears things up for me
thanks, however dosent explain the bug really ? i now know where its comming from but
Well both of your players were clients
Still not sure what the bug is
Or why it happens
Or rather, it might explain why you didn't have the bug when playing on the gameplay map
Because then both were clients I guess
And when you played from main menu you were creating a ListenServer setup
So maybe if you do Play as Listen Server on your Gameplay map it now also breaks
yeah true when i play as listed server now that dont work aswell
Which would at least remove some of the randomness
Yeah then it's clearly something in your code that prevents the Server from doing stuff
And you'll need to place some print strings and breakpoints along the code path
And see where and why it stops
hm and in case i would want to use dedicated server the short answer is i would need 2x projects wich 1 project is the "server" and the other is the clients right ?
You have 1 Project
But you package a Client and Server
For that you need to build the Engine from Source though
You can't package Dedicated Servers via the Launcher Engine Version
ok so for my first small "friend multiplayer project" what do you think i should focus on ? getting stuff to work as listed or should i focus on dedicated ?
Listen Server
ok, so probably its with the code then since ive apparently played as 2 clients so i guess thers alot of multicasts and run on server thaths messing with it :/
i mean for instance the "replicates" should this event be replicated to all clients when called on the server ?
dose this mean that this wont affect the "client1(server)" ?
Multicasts are called on all Clients and the Server when executed by the Server
Again, instead of theorizing this, place PrintStrings and check where it fails
yeah but i dont know where to begin witht that :/ i mean should i check on liek "the take damage" and se where it fails ? or why its not even colliding or something
Start where the whole thing starts
obviously you dont know this since u dont know my code buty xd
On the Key Press
ok
The key press that executes the attack
And then go along the code path
Somewhere it must stop calling for the server
ok so that dient take long
in this case server,,1/2 is both client 1 right ?
or client 0 **
ok so i found a issue its a variable "CanAttack(Bool)" that i have on Replicated since all clients have their own
Just see Server as ListenServer
And Client as Client
Otherwise this gets confusing
Run on Owning Client/ Run on Server
for a listedserver i should always use "Run On Owning Client" instead of Run on Server ?
@thin stratus
No
There is no rule that binds them like that
Run On Owning Client targets a Client, called by a Server
The Owning Client of that Actor to be precise
Run on Server targets the Server, called by a Client, if the Client owns the Actor
so that would only affect the "host" then in my cacse i suppose
Idk what you are doing
You don't need to Server RPC to the Host if you are already on the Host code side
well my problem is for almost all my functions whatnots
im calling a function that is "run on server" then after that runs functions that Multicasts"
the problem is from what i can se that server client(listedserver my client) dosent seem affected by this but all other clients works as intended
it must be something related to that
There is rarely a reason to call a lot of RPCs
Most ServerRPCs are only required if Clients perform Client side actions the Server has to know about
e.g. a Key Press
And MulticastRPCs are usually only needed if the Clients have to do a specific thing in that very moment
Anything else is usually handled by Replicated Variables
when ping getting higher client my camera movement become laggy. My camera moving with aimoffset animation. void UCameraControlComponent::LookUpAtRate(float Rate) { OwnerCharacter->AddControllerPitchInput(-Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds()); ServerAimOffsetCalc(); }
Am I doing wrong?
{
ACharacter* character = Cast<ACharacter>(GetOwner());
AimOffsetPitch = UKismetMathLibrary::NormalizedDeltaRotator(character->GetActorRotation(), character->GetControlRotation()).Pitch;
}
Are you saying your camera movement is tied to your latency?
Yep
What is your Camera Component attached to
Of the Mesh Component?
yes
Not your own Mesh Component or stuff like that?
Because only the children of the build in Mesh Component are smoothed
Everything else that is child of the Capsule is teleported
Its built in mesh component of character
Hm okay, then not sure
when camera goes down or up with aimoffset, its laggy
Aimoffset angle is calculated by that function void UCameraControlComponent::ServerAimOffsetCalc_Implementation() { ACharacter* character = Cast<ACharacter>(GetOwner()); AimOffsetPitch = UKismetMathLibrary::NormalizedDeltaRotator(character->GetActorRotation(), character->GetControlRotation()).Pitch; }
Why is that a ServerRPC though?
but i dont get it then, on the clients everything works 100% as intended, but the "listenserver" nothing works, or well i mena nothing gets replicated etcetc, shouldent it be treated as a client aswell ! 😮 thats what im not getting theyre supposed to be treated the same way
I'm not sure what exactly you mean that is not replicated
aimoffset variable have to be replicated because others player have to see third person movement
But Pitch is already replicated
That's what GetBaseAimDirection is for
Or rotation?
https://gyazo.com/7ebb9f459035d7060ae201ec8f4cb7bf
like this both "clients everything works" but the lsiten server is blank
So I can use GetBaseAimDirection as AimOffsetPitch
Yeah it returns the RemoteViewPitch for Players that have no access to the COntroller of the pawn
FRotator APawn::GetBaseAimRotation() const
{
// If we have a controller, by default we aim at the player's 'eyes' direction
// that is by default Controller.Rotation for AI, and camera (crosshair) rotation for human players.
FVector POVLoc;
FRotator POVRot;
if( Controller != nullptr && !InFreeCam() )
{
Controller->GetPlayerViewPoint(POVLoc, POVRot);
return POVRot;
}
// If we have no controller, we simply use our rotation
POVRot = GetActorRotation();
// If our Pitch is 0, then use a replicated view pitch
if( FMath::IsNearlyZero(POVRot.Pitch) )
{
if (BlendedReplayViewPitch != 0.0f)
{
// If we are in a replay and have a blended value for playback, use that
POVRot.Pitch = BlendedReplayViewPitch;
}
else
{
// Else use the RemoteViewPitch
POVRot.Pitch = RemoteViewPitch;
POVRot.Pitch = POVRot.Pitch * 360.0f / 255.0f;
}
}
return POVRot;
}
let me try
hmm, what is wrong with that line UKismetMathLibrary::NormalizedDeltaRotator(VexCharacter->GetActorRotation(), VexCharacter->GetBaseAimRotation()).Pitch;
Seems fine to me
camera not moving
Check the values of the Rotators :P
Values are correct
but aimoffset not working 😄
I am on check them
@thin stratus I am using other skeletal mesh for FPS and its not working
I think something different with default character mesh and my own skeletal mesh
I wonder why they replicated only pitch
Holdover from the old days?
Defo. UT/Gears kinda stuff
What happens if i broadcast a delegate on server ? Only server can see it ? I have a shop that refreshes its items based on this delegate, the update should be server-side only so it would be appreciated if the delegate is only fired server-side
delegates are local only
I am getting duplicate entries in the playerarray of GameState after seamless travel, but running locally is fine when using Steam App ID 480
Any idea ?
there is no way to replicate them ?
Hello, I am having problems with the following flow: using seamless travel I have the server lobby, then travels to gameplay level, then to WinScreen and after win screen i need to travel to the Lobby again. I used ServerTravel on server for the server lobby-> gameplay, gameplay->winScreen, but for the winscreen to lobby I am using a client travel as the core logic resides in the UI widget in each client (is a timer that calls the client travel when reach 0segs), so using server travel doesn't work, when the client do the travel, if stays connected to the aws server but when reaching the level the player cant do anything and the pawn is deleted after an left the game in an unplayable state, do i need to more in the client travel custom?
repnotify -> refresh
or
repnotify -> delegate
delegate -> refresh
but I will need this repnotify to make sure delegates are called on server side
thank you !
And what if it is not really a variable that i can set replicated with RepNotify ? A delegate I need to call when something is happening
isn't shop inventory a variable?
wait are you talking about the shop refreshing items or the view of the shops items refreshing?
It'd probably be like
Delegate -> shop refreshes -> shop repnotifies new items
repnotify -> do things based on shop having new items now
This is this kind of code (pretty rare in games) :
{
for (FCardsData& CardData : AllCardsData) {
if (CardData == Card && CardData.IsCardAvailable()) {
if (CardData.CurrentCards == 0) {
OnCardChanged.Broadcast(CardData.CardRowName, false);
}
}
}```
delegates are local only, for doing something on clients when shop refreshes, your options are a repnotify (if it's stateful) or a multicast RPC (if it's not)
What is that code doing in plain English?
i see but i'm talking about GameState calling a delegate that many shops bound refresh functions (which might be not an ideal setup, just the solution i came up with)
The shop data is replicated right?
or is it query only (clients only know about it when they open the shop or whatever)
I re-checked the code to make sure i'm not saying bs and actually shop has a replicated TArray that contains cards (items) that can be buyable and are displayed in a widget
so just repnotify on that to update stuff clientside
But the code in the gamestate is updating card availibility, so I thought that card is not available anymore -> fires delegates over network
-> Card Shops who have bound this delegate call the refresh function -> refresh function removes or add the card
But how to notify shops to update their content ? if not with delegate
Oh, refresh each shop in the server (gamestate in this example) ?
No i don't think i have this
You're doing refresh after broadcasting over the network
You should do this.
Server:
Whatever condition -> delegate? -> update shops -> repnotify
Everywhere:
Repnotify -> update stuff that needs to know about the new shop inventories
I had this code in the shop class Super::BeginPlay(); if (HasAuthority()) { TArray<FName> RowNames = ItemDataTable->GetRowNames(); for (FName& RowName : RowNames) { FCardStruct* TempCard = ItemDataTable->FindRow<FCardStruct>(RowName, "Context", false); if (TempCard) { if (TempCard->CardType == ECardType::ItemCard) { ItemCards.Add(*TempCard); } else if (TempCard->CardType == ECardType::HealCard) { HealCards.Add(*TempCard); } } } GameStateRef.Get()->OnCardChanged.AddDynamic(this, &ACardShop::RefreshCards); }
{
FCardStruct* TempCard = ItemDataTable.Get()->FindRow<FCardStruct>(CardName, "Context");
if (TempCard) {
int32 Index;
if (TempCard->CardType == ECardType::HealCard) {
if (bExpiration) {
bool bFound = HealCards.Find(*TempCard, Index);
if (bFound) {
HealCards.RemoveAt(Index);
}
}
else {
HealCards.Add(*TempCard);
}
}
else if (TempCard->CardType == ECardType::ItemCard) {
if (bExpiration) {
bool bFound = ItemCards.Find(*TempCard, Index);
if (bFound) {
ItemCards.RemoveAt(Index);
}
}
else {
ItemCards.Add(*TempCard);
}
}
}
}```
It should be repnotify -> update shops ?
if you have a lot of cards, maybe a FastArraySerializer
I already heard about it but I don't know really what it is. however, I have like max 25 cards. is FastArraySerializer needed in this case ?
Someone should really make a simple set a blueprint screenshots that shows the common multiplayer mistakes such as unnecessary RPCs and then have a corrected blueprint screenshot after.
So for example demonstrating how Player inputs should be setup to be replicated, Overlaps for the possessed pawn, Overlaps for a level actor, and looping through the Players array on GameState...etc
Then we can have that message pinned and just direct people to it.
Could even use https://blueprintue.com/ to show bad and good examples.
If you make an RPC with a default value for one of the argument, does the default value get serialized over the network, or nothing gets serialized and the receiving side creates the default value locally?
There is, effectively, zero difference.
All values are "created locally" by the client when receiving the serialised data.
However, if you use a default argument, I believe that argument is passed to the function, so it would be the same as providing the default argument manually.
I am mainly concerned about the bandwidth aspect rather than the serialization on the client
It's going to send that default value as well, yes.
Hmm, so based on that I would expect to pay bandwidth even if it's the default value, which would make sense
If you want less bandwidth, create 2 functions. One with and without the argument.
Yea thats what I have now and was hoping to unify 😄
I mean they both call the same internal function, so its about as unified as I can make it atm
Thanks for the info!
What's the recommended paradigm for having a multiplayer game that is very bullet-hell like with a lot of projectiles? Spawning that many replicated objects seems like it could choke the replication bandwidth
It would. You dont want to use replicated Actors for this.
Yeah, my current strategy is spawning non replicated projectiles on both client and server, and doing the authoritative stuff on the server side. This can result in desyncing though where a projectile appears to hit but doesn't, especially if there's a delay between them due to something like client prediction (for projectiles fired by the player)
So it makes me think I'm doing it "wrong", was curious what other paradigms people recommend