#multiplayer
1 messages · Page 219 of 1
why not just try typing stuff into the bp graph?
these are a pair of enums, they represent what the object individually is doing authority-wise
anything owned by the server (replicated) will have a local role of ROLE_Authority on the server
and a remote role of ROLE_Authority on everyone else
client owned objects like their controller can be ROLE_AutonomousProxy for them locally
Like this? This is when the client picked up the item
hmm, try printing the result of is locally controlled instead
This is working as expected... beginplay for replicated objects is indeed delayed until this is swapped I guess
the delay is before the cast to BP player
sorry, I mean that the object has the right roles here
i was talking about printing is locally controlled
First time seeing this, how did something print without the server / client prefix?
what context is it called in?
is it a uobject without a world?
So since a 1 frame delay fixes the problem...does that mean latency will make this a problem later on?
100%
delay not to be relied on
yeah if you MUST wait for something, do it in a way that you can check every frame until it's ready
with netcode stuff sometimes it's just something you can't gaurantee is all there in one frame atomically
but delaying once and praying is bad, if you must delay a bit and then try again if it's still not what you expect
I wonder if the controller is present both times
this worked correctly when I did multicast. I guess because it creates a unique instance for each player and doesn't require timing
I believe there is a setting to emulate latency. Let me try that and see if it causes a problem
Network Emulation?
there are presets for average/bad in advanced play settings
he entered latency so he can't see those
i found it
emulation target everyone?
Profile Bad
I tried it, it still works correctly
tho, things set to unrealiable will not trigger when there's a lot of lag
bad is insanely high loss and ping
with the 1 frame delay
but it's worth trying
I set the run on server as reliable
why 1 frame?
I honestly have no idea
scroll up
without the delay, the item doesn't get attached to the correct mesh based on isLocallyControlled
with 1 frame delay, it does
it will be more than 1 frame in real environment
You are addressing what is called race condition in Client side
hell nah, this is bad code
pretty sure there's a function to make sure the owner is always valid
it's not about the owner that is not valid
owner will always be valid
the remote role isn't set correctly on client yet
why?
Is he setting the role manually?
Because begin play is run before the server can set the role
In many many many casses, you don't really want to use begin play to run stuff in multiplayer context
you will be fighting a lot of race condition
an example would be possession
begin play is called on the server and client, it's a great place to do stuff
context needed, in many cases you don't really use begin play
I am not saying for everything but in most casses
Take a look at input binding
people do it on begin play and wonder why it doesn't work for clients
simply because the client doesn't have a valid pawn yet
All on BeginPlay:
Mapping Context Setup, HUD setup, Delegate Setup, GAS init setup...
Yeah not begin play
you are doing it wrong if you do
but you do you
Use OnAcknowledgePossession for Mapping context
How?
already explained above
race condition
You won't have valid actor yet in begin play or character as client
pretty sure unreal do not use mutex and these stuff (for race condition as you call them)
either way, I guess I should just leave the delay for the time being and move on? I spent hours trying to figure out how to get it to work
No, this is a code that is not production ready
a band aid that simply will not work
lets say you put 1 second delay, but the player have 200 ms
you will end up with the same error
lol, it does
1 frame delay still worked with network emulation set to bad
which is 100-200 ms
I just tried 300-500 ms latency and it still works with the 1 frame delay
Your player suddenly gets ton of packet loss and 2000 ms spike to latency
Your bandaid breaks
Never, ever, use delays for networked code
I'm trying to understand, so for the HUD, delegates and GAS init, what's wrong for those?
Use events, rep notifies, paired with begin play, wait for all relevant actors to be ready before executing your code
nothing wrong for HUD
really depend on what data you want it to display
OnAcknowledgePossession doesn't seems to exist
or if it needs to be ready
context needed
I can't speak for GAS, not much experience and too noob to understand most of it
trying to debug my GAS as we speak atm
maybe there's a mistake in the name you stated? because I can't find any function with this name
This is on the PlayerController?
then why the default unreal template comes with the mapping context within the Player Character BP class?
you can place it in places that make sense for your project
I think Lyra usses components to do the inputs, can't remember tho
Just keep in mind that multiplayer has a ton of race conditions
Actors aren't guaranteed to replicate in any order
Properties as well
there's AcknowledgePossession and ServerAcknowledgePossession
@twin juniper You can read the comments to find their usages
/** Called on the client to do local pawn setup after possession, before calling ServerAcknowledgePossession */
virtual void AcknowledgePossession(class APawn* P);
I don't know what else I could do. I add an item component on item pickup to spawn the item. It starts on beginplay, so without the 1 frame delay, the items don't attach correctly to first person and third person meshes depending on if they are locally controlled.
I'm using listen server, so that would work for all cases?
it's just an event that gets called when the pawn is possesed. This way on client, you can be sure that you already own / possess a pawn when that function is called.
1 more thing, do you call super before or after the mapping context setup?
I'd go with before
Character.h
FColor Color;
UFUNCTION()
void OnRep_Color();
GameMode.cpp in PostLogin
OnRep_Color is never called, is this expected ?
why are you using static cast on a UObject ?
use Cast<>()
also, you either use Replicated or ReplicatedUsing not both
and ofc you need to add the var using DOREPLIFETIME
uh
ah nah it is in GetLifetimeReplicatedProps already
gonna remove the duplicate and do a Cast
thanks
also if you are using a listen server, the OnRep wont get called
you need to manually call it on server
(OnRep is only for clients)
It is called nowhere actually
Is the replication already working in the PostLogin handler ?
if its a listen server you need t ocall it manually
um, property in character class, but you assign value in controller class? they're different properties from what it looks like
oh yes 😅
The server has to change the color value, or on_rep won't get called at all
sorry, it was in Controller.h my bad
color value is changed in the GameMode, so on server
did you add the DOREPLIFETIME in getreplicatedproperties?
yeah
are you using dedicated server mode ?
ListenServer
is this your first player joining the level ?
usually i have a setter that invokes onrep on authority if it is required
since onrep wont be invoked on listenserver if you just assign value on authority
Savez ou cest la discussion du code personnalisé en batle royale
Hey, please stick to English when asking and answering questions.
Help me, can you help me find the password for the personal key to play a private battle royale match
Please
🥺
Probably not. This Server is for Unreal Engine Development help. It doesn't cover Fortnite Battle Royal questions.
Ah
If you need help with Fortnite you might want to join a Fortnite related Discord Server.
Ok thank you
No worries
Very much
hello again, when replicating shooting a linetrace. isnt it enough to do the linetrace on the server only? like do I need to replicate it to all the clients?
It is in theory enough to do it on the Server only.
You may also do it on the owning Client to predict the shot for some FX.
And you will still need to replicate the result to other clients for the same FX.
E.g. shooting against a wall, you get a decal and a hit sound.
yes thats what Im asking, the line with hit result on server only and cast the outcome to the clients.
is there a way to have a TArray OnRep called when an item is changed in the array, but the array is not resized ?
FastArray stuff calls per property. Might be more what you need?
PushBased replication could also have you mark teh Array is dirty. Not sure if that skips the size stuff
Thanks for the keywords 🙂
Question about the simulated proxy. I'm aware that it is the server side version of me on another players screen. If I had a component on my pawn's controller that checks for the pawn's role being equal to Simulated Proxy will that fail? Or am I trippin? I guess the simple question is can the simulated proxy access the controller?
duh worse than that, my TArray content is NEVER replicated. Probably because I .Init it with null ptr, and only access it with [] operator
I'm actually trying to use it as a queue, do I have a better option ?
F me
all my issue were caused by the fact that my player pawns were 'setHiddenInGame'
which seems to affect replication
since the pawns are not visible in viewport, i did not notice it
The controller is only replicated to the owning client, so there would be no values there on the simulated proxy to check against
Also it's not the "server side" version on another player's screen. It's their own version of you which is necessarily desynced from both you and the server.
Performance-wise for Clients, yeah, turn off (or on) the Collision only on the Server.
If you don't want the code to run on Clients, also test in the OnBeginOverlap if you want.
If you don't want the code to even exist on Clients, wrap it with #if UE_SERVER or whatever it was.
@normal fulcrum
You didn't specify if it's Dedi or Listen
For ListenServer, turning off/on collision is enough
Cause anti-cheat isn't a topic anyway
Hm yeah, that's the sideeffect of the client being the host I guess
are there any good learning resources for setting up a dedicated server? so far 99% of the stuff im finding is just how to build the server executable, but basically nothing on how to actually host it so players can join it. i have around ~6months to learn before i need to actually start implementing it, but i want to start learning early and slowly, as from what ive read, its extremely difficult and underdocumented.
Hosting is as simple as running the server executable on a computer that is running the operating system the server executable was built for and once its running, players would technically be able to join into that server. if you're looking for more complicated solutions for hosting, like having servers spin up and down automatically based on load, that's a completely separate aspect and doesn't have much to do with Unreal specifically though with whatever solution you decide to go with, you will likely tailor your game to communicate with that solution. You may want to look into AWS Gamelift, Microsoft Azure, Playfab or searching for Backends As A Service (BaaS)
okay, thanks. but from what i saw online, its nowhere near that simple. the create/join session functions dont seem to work out of the gate and needs extensive setup, i read a really long forum discussion where someone couldnt get their server to be found by other players, and the replies on what still needed to be done was a clear indication that it seems i havent been able to find any good information (tho maybe thats just me and my bad googling skills). im still very new to multiplayer, and basically know nothing about server aside from the basics like ports and IP. what im searching for is some learning materials that would provide every bit of information required to host that server. i would start off by hosting myself on my old pc, only renting servers if i end up getting enough players. ofcourse im not expecting there to be a step by step tutorial for this, but where can i find EVERY bit of information relating to this? also apologies for this long paragraph, im just getting scared that i wont be able to learn this in time. my upcoming project after my current practice project is going to be a big undertaking, tho luckily im out of my "lets make a massive open world MMORPG" phase that i had 8 months ago. scale should be realistic, but the server would seem to be my biggest issue. other issues i know im able to conquer as they are more just a matter of practise, but for over a week now i have been trying to learn about servers but just cant find anything solid.
In general it is that easy though.
- Build server executable
- Make the default dedicated server map host a session
- Make a main menu that can search sessions
- Set up INI files correctly for your platform(Steam, EOS, etc), mostly just enabling and picking correct drivers, and in Steam's case setting the App ID.
- Launch server
- Launch client.
- Search sessions on client.
oh, then i dont know what i was reading. someone had a ton of problems, tho maybe its been streamlined since then, as it was in UE4. i just assumed it would be similar to UE5 in that regard. would you know where i can find more information about that "set up INI files correctly..." step?
Hosting is that easy. You start a server, it can technically allow incoming connections. There may be additional requirements to allow connections into that server, like port forwarding/firewall exceptions if you're going with connecting VIA IP address and port which again, isn't something strictly tied to Unreal itself, it's more general networking.
Sessions via #online-subsystems can mitigate the requirement to use IP addresses and ports and they can support NAT punch-through (effectively removing the firewall/port forwarding part) making it trivial to get players connected. Sessions are typically a means of communicating that there are servers available and allows clients to connect without having to share IP address and port information, and can circumvent the need for you to build your own solution for sharing the information with players so they can find active game servers to join.
Some BaaS solutions can have their own "sessions" though not necessarily exactly the same as sessions that are used by Unreal, but it works effectively the same - your game server would communicate to the BaaS when it starts up to indicate it's available and register the server. Your game client would communicate to the BaaS asking for a server list, the BaaS would let the client know what to connect to, you'd then have your game client connect to the desired server. The server may also have some form of authentication of the client joining with the BaaS. But again, this would all depend on the solution you'd want to go with.
I'm sure there's a guide somewhere that has a more comprehensive list. But for example this is all we're using atm on our latest project. You can ignore the beacon related lines if you don't intend to use them. But this INI allows us to test in editor using Null subsystem. And in any Standalone or cooked game using Steam. We're using using CommonUser plugin for easier handling of the session code.
[/Script/Engine.GameEngine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="BeaconNetDriver",DriverClassName="OnlineSubsystemSteam.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemSteam.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")
[/Script/UnrealEd.EditorEngine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="BeaconNetDriver",DriverClassName="OnlineSubsystemUtils.IpNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemUtils.IpNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")
[OnlineSubsystem]
DefaultPlatformService=Steam
NativePlatformService= Steam
[OnlineSubsystemNull]
bEnabled=True
[OnlineSubsystemSteam]
bEnabled=True
SteamDevAppId=YourSteamAppIDOr480Here
bInitServerOnClient=true
[/Script/OnlineSubsystemUtils.OnlineBeaconHost]
ListenPort=7787
BeaconConnectionInitialTimeout=48.0
BeaconConnectionTimeout=49.0```
oh okay, thank you very much. i was getting scared over nothing it seems.
oh okay, thank you.
One major note. It might be best to set stuff up as a Listenserver first if possible. It's much easier to test on and get stuff working. You still have a few things to work out with dedicates, like them not ticking animations and such without the override. But in general you can get a lot of your dev stuff done in Listenserver. After that a dedicated server should literally be as simple as setting up the server to host instead of having a player host.
Also if you don't want to set up a UI, do remember that you can connect using command lines. In Null you can connect via IP. In Steam you can I "think" both connect with IP and a user's Steam ID. Both are just "Open 127.0.0.1" for example.
But dedicated server testing time has a long phase. And it should only be used for things that specifically relate to it. If you can do it on a listenserver, do it, because it's a lot faster cycle times.
okay, so does listen server replication work functionally the exact same(for most of the game logic)? also i will be making an UI, but that shouldnt be too hard, i have made a listen server create/join server menus, tho with this i wouldnt have the create option.
At it's simplest. A Dedicated Server is literally just an instance of the game running that has no visual renderer. The entire render thread is turned off for example. And there is no local user. So essentially there is no hosting player. In 99% of net code this doesn't matter though. The engine handles everything for you like not spawning particle systems or sounds and such if it's on a dedicated server. I think the most major cases of implementation issues stem from people trying to move to Dedicates when relying on animations playing(default has no anims on the dedicated but you can turn this on), and things like using the renderthread to do complex things like a fog of war in a niagara system.
when you say relying on animations playing, you dont mean replicating just basic animations? in my case i would be replicating IK based animations (vr)
You don't replicate animations though. You replicate state which a client uses to drive animations. The case I'm referring to is that people think that they need server side animations so that they can line trace say an arm on the server based on data a client gave. This of course is still highly inaccurate due to timing issues of latency. I'm unsure if root motion anims work or not by default. But they may be another reason to enable dedicated server anims, so that the server authoritively moves something. I don't deal with those though so out of my area of expertise.
oh okay, but wouldnt i technically be replicating animations if i ofcourse run the ik animations for the client, but then send their controller positions as 3 floats to the server to basically be replicated on the other clients? or is that simply not defined as replicating the animation?
Perhaps. Though you're still replicating some basic state to drive the animation on another machine. You're not exactly replicating the entire animation. It's kind of the same idea as the AimOffsets. You don't really replicate the animation. You replicate Pitch and infer Yaw. And you use those two states to decide how to do your aim offset animations.
Like, you say "replicate the animation" and I immediately think you're trying to replicate every bone position and such. 😄 Rather than some simple state to recreate it.
Game name? O.o Doesn't that get inferred from the AppID?
External solutions will require whatever setup they require. Hosting a dedicated server from Unreal's perspective is literally just turning on that computer, starting up the dedicated server executable and then clients can theoretically connect to it. It's everything else leading a client to be able to find and connect to that server that varies and, yes, your game will need to be configured to whatever your solution needs.
The game mode has all the player's stats in an array for each player. Its multiplayer. however when referencing the game mode, only the server has the correct stats. Can anyone tell me what im doing wrong. The UI says gamemode not in scope but i used the refrence from the actual player.
The gamemode only exists on the server.
so how do I set the values so only the server has them and the client can read them
what do you mean "only the server has them" - if a client needs to see the info then the client also needs to have them.
Anyway, the game mode only exists on the server. The game state is replicated to everyone.
For example. if the player's stamina in on the Player blueprint. Is it still safe from outside interferince like through cheat engine or such. Security isnt a big deal but it helps to know if players can set thier stamina to 1000
that's not how this works
clients cannot set values on the server
replication is one direction: server to client. RPCs are the only way clients can send data to the server and those must be created by you intentionally.
Clients can modify values for themselves, but that does not affect the server's values or values for other clients.
I see. So if the default value for stamina on a player is 100. they cant change it because thats how the server sees it.
They can change it for themselves. It will not update the value on the server.
got it. thanks for the help.
can someone explain how, in a two player game, how the server manages the each players Game Instance? I have the logic to load a player's chosen username into the Game Instance. Then when the client connects to the host, both players can see each other's usernames. The text that displays each player's name is bound to a variable on the server.
The game instance is not replicated
Every machine gets their own
Does the server have access to both?
Well, I guess i'm doing an RPC to each player's controller and getting the game instance from that. and the sending the result to the server to store. But i'm still not getting the Client's name.
Game Mode only exists on the server.
You can store their chosen name in their game instance, and when connected to the server, send an RPC to the server with their chosen name - probably best to do this on Begin Play of the Player Controller and checking if the player controller is locally controlled. The server once it receives that RPC can then store the player's chosen name in the PlayerState. PlayerStates are replicated to everyone and are always relevant, so it's a good place to store general information about each player.
Then if those name variables are marked as replicated, they'll propagate to any other players. If you want the name of a player, you just need to get their player state which is accessible VIA their controlled pawn or player controller. The PlayerState's owner is the PlayerController, and the PlayerState also has a reference to the currently possessed pawn, but it may not be valid on clients as Pawns are usually not always relevant. An array of active PlayerStates are also stored in the GameState under the "Player Array" variable so there's no need to store joining player controllers since you have a list of PlayerStates which you can also use to retrieve their controllers from if need be.
How should you deal with something like a player getting a frag?
My idea - change the player state (keeps track of num frags). Have game mode listen to changes in the player states, and handle this appropriately based on game mode (e.g. if player has 50 frags, end match or whatever, depends on game mode logic).
Does this make sense? Or is it more sensible to use some different approach?
If your game mode relies on kill count of any single player, that would make sense. Each time a player gets a kill, you increment and store the kill count for that player on their playerstate making it accessible to everyone as well for use in a scoreboard. You can have that same event report to the Game Mode that the player received a kill, and your specific game mode that cares about how many kills a player has can then check if their kill count >= max kills for the round and if so, end the match etc.
@karmic rock ^
Awesome, thanks. I think I'm starting to get the whole UE multiplayer thing basics a little.
Has anyone else observed that, on the default Third Person Template, the Listen Server observes clients animating their run cycles at a lower speed?
The clients all see the server and each other animating at the correct playrate, but the animated speed of the run cycle is slower on the listen server.
I'll have to study up on RPC's again because i'm confused on how to implement it.
I thought I had an RPC that, onPostLogin, would call an event on each player controller that would return the saved username.
The prolem is that RPC on Post Login calls this RPC which would run on clients. Since the Game Mode doesn't exist on clients, the execution would stop at the first cast as Get Game Mode would return a null reference causing the cast to always fail.
guys, is there any good solution to make a text chat for multiplayer game? and voice chat as well? that can work on dedicated server
A simple global chat message system can be as simple as a player sending a server RPC with a string input of the message they want to send, and then having the server multicast on the gamestate, sending along the message and the playerstate of the player that is sending the message (to know who the message is from). If you want to ensure all messages are delivered, then you may want to send individual reliable client RPCs with the message to some client owned object. This can all be coded into a component that you can place on the player state or player controller.
Voice chat, I'm not sure of.
yea, it should be easy, but since I'm prototyping here, maybe I thought there's some industrial standard plugin 🙂
Hi everyone, quick question: does anyone know if it's possible for a client's player state to be instantiated and initial bunch sent before the game state is instantiated? I'm tracking an issue and this seems to be the most obvious explanation but want to rule out that possibility before I implement a fix.
Essentially, the player state has an OnRep function which is supposed to look at the game state and retrieve a widget class and display it (a welcome screen), but sometimes it doesn't appear for clients joining mid-game and the most obvious reason would be the game state is null on the client side when that OnRep is first called.
I can't say for sure if there's any guarantee or not that Game State is initialized before Player States (sounds like it isn't in a join-in-progress), however there's a few mitigations you could try so the guarantee isn't necessary.
- Try defer the Welcome setup to the next frame (there's a high likely hood that Player State and Game State come down in the same network update)
- Create a simple Welcome subsystem/logic that the player state calls, it then checks if game state exists and continues otherwise registeres a delegate to the World's GameState creation event
- Let the Player State logic bail if no Game State exists and then have Game State instantiation on the client iterate through existing Player States and try to run welcome any local controlled (though this could invert the expectation and run into a similar issue where it sees a Player State reference but it hasn't been fully initialized yet)
These solutions are obviously just variations on the same theme (mark that we want to do something but defer it until we know our state is correct) and slightly hacky feeling, but also common enough patterns that I'd not be too worried about using them.
how can I replicate my aimoffset
Think you have to create a replicated variable and update it on tick or someting. iirc ControlRotation isn't replicated
try base aim rotation
does attenutation not work when playing sound ques from sound anim notifies? It plays just as loud for everyone in the game even with the 'follow' setting checked
works for me. Try checking your settings
ok, I found one problem, I had the wave instead of the que selected. do you use any of the other settings as in like the LOD filtering etc?
LOD for audio? I kept everything default and just dump the attuneation setting that I want.
yup there's notify filtering by LOD, not going to mess with it for now
So im trying to play sounds when force >= x
How do you guys calculate force on physical objects? Do you use normal impulse as the force? Or do you get the mass * acceleration? If so, how do you determine the acceleration of that object on hit?
which one of these would actually be the better system for removing items ? as far as i know they would do the same thing, but curiuos if anyone has thoughts as to which would be a smarter decsiion
They aren't equivelent
top one will put a default Item struct in that element
ahh i see, if the default is blank , would they then be equivalent in result?
or would removing, like remove that entire index and shorten the array ?
It's the difference between:
1,2,3 -> 1,2,0
and
1,2,3 -> 1,2
makes sense, nice yea the top one works great, was just not sure what that was doing vs the other , but that clears it up
how would i go about replicating ik animations? here is my player pawn BP where i can control the location of the effector and then my two bone ik in the anim BP.
it is replicating to a client from the playing hosting a listen server, but not from the client
You don't have to replicate the IK positions afaik
Ah wait I see
You'd need to send the new position to the server so it can replicate to clients
Your code right now would work on the server because it would replicate to the clients, but clients can't replicate properties to other clients
You'd have to send the transform to the server using an RPC (and you'd likely want that RPC to be unreliable if you execute it often)
Then on the server you apply it to the replicated property which clients will get
@crisp copper
i think i just had that moment where it finally somewhat clicked. i didnt realize that variables are also replicated using the RPC, as the variables have the replication and repnotify options. thank you very much, it took 3 nodes and now its working.
any common reason why clients have 70+ fps but listen server has 15 ish ?
Profile your server with Unreal Insights
Listen servers are both the server and a player so it does take more resources
hmm aye profile it is
A very probable reason is you have many replicated actors in your world spawned. The server will always have all replicated actors that are spawned active and using CPU & GPU resources, where clients would only have actors that are currently relevant which is usually drastically less, and this is beside the additional overhead the server has with having to manage the replication of those actors. But yea, profiling should direct you to the answer.
hm possebly but what would be a recomended action for this ? or yeah profiling will narrow it down i suppose
Unreal Insights will tell you all you need to know
1 thing that the sever dose it spawn 100 "playable areas small platforms with alot of doodas thats all replicated" but after they are spawned i though the server wouldent "spend preformance on it"
How would you architect a space station city builder?
Like, if your view is far enough away, you'd see nothing but still know some state
but close up you'd see a lot of stuff
It feels like actor replication and relevence systems would maybe grind to a halt, might be simpler to have a simple synced sim and have all the actors etc be derived from it.
It still needs to consider them for replication. 100 isn't very many though, you need to profile and see where the time is being spent
Quick question guys, how do you replication geometry collection ?
Hi tips on how i can show the "HpBar" locally to the "target" only ?
this event is run on server from a npc
What's the context here, you want to show a hp bar for what situation?
who owns the hp bar
server
only npc
Right now do clients know that damage happened?
well yeah
oh right well, they spheretrace and on overlapp it sends damage, but this is on multiple actions so i cant really use that
is HP replicated and RepNotify?
replicated
just make it repnotify and show the bar there
OnRep_HP -> show bar Event
Show bar -> if bar not visible -> show it -> retriggerable delay -> hide it
quick and dirty and not perfect but that'll get you on your way
but i want it to only show for the "damaging player"
Might be simpler to just RPC then
Damage Code -> multicast "I just got hit by PlayerPawnX"
Multicast -> if LocalPlayer = PlayerThatJustHit -> show bar
I mean you probably want some sort of local prediction so just do the hits clientside too and show bar then
you don't want to wait for ping lag for everything
hmm
https://blueprintue.com/blueprint/eo1yyz4a/ i mean this is what your saying kinda right ?
the event is rpc
from NPC
when taking damage
you could still just do the repnotify but check who the damaging player is on the client
If I have a setup like this, what should I replicate to not have stuttery movement of the hinge?
I see that just replicating physics, desynces on client
Why do you need to replicate dangling toilet paper?
You'd probably miss a few
because skibidi toilet
I feel like I know the answer but I would still love opinion. In my mission system when I have timed objectives I want to display this time to the players. I have my UI setup and is updated with objectives name and info and all that when they start, but I was just unsure about displaying the timer to players.
On first thought, I just replicate the CountdownTime and ReplicatedUsing to update the UI. But then I was thinking I don't send the value and instead just fake it by starting a local timer on the client when the objective is started.
All functionality linked to the timer happens on the server so this is purely cosmetic, so I feel like I should just fake it. But is it even worth doing that vs just simply handling with the ReplicatedUsing haha?
I have to know what the toilet paper is for lol
its just a cube that moves around this cylinder
like player can bump into it
and move it
Its just me testing how physics work and constraints on single and multiplayer
yoyo, im making changes to a TArray but for some reason it's not being replicated. i'm not getting any OnRep_ calls. anyone know why this would be? i thought changing elements inside of a TArray would cause a replication event to occur
I feel you, just last night I gave my golfer a giant floppy dong to test out the physics hahaha
Can you share code?
Are the properties in the TArray Uproperties?
void UTitansAbilitySystemComponent::ClearAbilityInAbilityBar(int InSlot)
{
const auto [AbilityAsset, Handle] = AbilityBar[InSlot];
ClearAbility(Handle);
AbilityBar[InSlot] = FAbilityGrant{nullptr, FGameplayAbilitySpecHandle()};
}
// Replication
void UTitansAbilitySystemComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UTitansAbilitySystemComponent, AbilityBar);
}
UPROPERTY(Replicated, VisibleAnywhere, ReplicatedUsing = OnRep_AbilityBar)
TArray<FAbilityGrant> AbilityBar;
it replicates fine when i assign to it, just not when i make that change
AbilityBar[InSlot] = FAbilityGrant{nullptr, FGameplayAbilitySpecHandle()};
do i need to maybe tell the replication system that i need to broadcast a change? i figured just changing the array would cause a replication event
Share struct sorry
Is it possible that the slot wasn't actually changed?
oh interesting
like it might have occurred on the client but not the server
good catch, lemme see if that's the case
okay when i manually call OnRep_AbilityBar i get the UI changes i'm looking for. this points to it being a server problem. let me try making a server RPC call instead and see what happens
and in the end i'll likely end up doing a mix of the two so it looks responsive
one moment
yep, that's exactly what it was. thanks @kindred widget
Heya everyone, I hope you're good!
I officially hate multiplayer. Does Advanced Sessions actually implement everything that is needed to connect Steam P2P, or is it a load of extra C++ needed too?
I've tested with a couple friends and the create sessions can be seen, but joining them is "successful", but doesn't take the player anywhere.
I have also tried Event on Session Invite Accepted Execute Command "ClientTravel M_MapName" with no luck. Any help is more that appreciated. Or pointed to the right thread 😄
Very big necro, but did you ever find a solution to the Iris disallowed to write first packet message? I'm getting this too, along with a few actual errors.
I remember getting pass that error, just to get another bunch of errors down the way that reside somewhere in Iris core
If I recall correctly, that is some properties not get replicate at all
The error I'm getting is
LogIris: Error: OnErrorWithNetRefHandleReported: 1 from client ConnectionId:1 ViewTarget: GamePawn_C_1 Named: [UNetConnection] RemoteAddr: 127.0.0.1:49708, Name: ClusterNetConnection_2, Driver: Name:GameNetDriver Def:GameNetDriver ClusterNetDriver_2, IsServer: YES, PC: PlayerController_1, Owner: PlayerController_1, UniqueId: NULL:ITC23128-84DFDFB04A06131F4FF28796794A48FF. Problematic object was RootObject WorldSettings_1 (InternalIndex: 1) (NetRefHandle (Id=3):(RepSystemId=0))
Hmm interesting
So we just go back to the old replication system
I guess it's in beta for a reason
Iris needs some more documents. Until then just settle with push model
might try it with 5.5 🙏
is it worth generating hit events just for playing sounds on simulated objects?
seems like a pretty big preformance hit at scale
how big?
with ~300 simulated* objects its about 12 fps difference
Hey guys - anyone here got experience with GMCv2 ? Dont know if this is the right place to ask?
The right place to ask is their discord
Which is something behind the paywall 😉 just have 1-2 things I want to know before purchasing
How could anyone possibly know you don't have it based on your previous message? 😉
Also - the creator is still the right place to ask
And just ask your question as well
Never ask to ask
Just ask
Hardcore user here, what's up
First off, thanks for reaching out. My main questions currently prior to purchasing are regarding sustainability and compatability with other "native" UE systems. As I am coming from a different engine
as I understand the GAS topic has been adressed by a community built solution
GMAS yes, it's actively worked on and if you have issues they are generally fixed pretty fast - or you can fix them yourself and PR it I suppose
ah great that is reassuring
It isn't 1:1 with GAS yet, a notable issue is the lack of GameplayCues but they are next on the list. On the flip side, GMAS has support for things that GAS doesn't.
is there anything in your experience that "breaks" or becomes significantly more difficult ? (when commiting to GMC)
Such as server applied gameplay effects which don't break prediction of the client
Not really no, it's been battle tested in a game so far and they love it
Both GMC and GMAS
Not issue free but for the GMC the dev is active and replies pretty fast, and GMAS has its community (on the GMC discord as well, they have a few channels) that can answer questions
awesome to hear! I am reletavely new to UE and just want to head down the "right" in regard to learning from the start
Why do you need the GMC over UE's native solution?
because unlike you, I believe learning CSP / lag compensation is something I would rather "offload" to people that truely understand the subject matter
CSP?
Client side prediction* sorry
UE's native solutions offer that too, both CMC and GAS
Depends on what you want to do in your game tbf
Interesting, based off of my research the majority of people recommend GMC due to the robust replication / prediction etc
You can also do that in the CMC, but the GMC 100% supports Blueprints so BP devs can make custom movement with prediction etc
The GMC is also a lot easier to extend for your custom movement compared to the CMC so that's why I really love it
yea, and TBH the cost is not the issue for me. Paying sombody to create the same would be substantially more expensive than a 600 dollar Plugin
Oh definitely, that's multiple years of work
exactly - and since I am not able to truly "judge" the code behind in terms of netcode, I would rather trust something "battle tested"
So, in short - you recommend it and dont see any "dependency" topics I need to know about. (such as when using a custom build like with Angelscript etc)
Not as battle tested as the CMC but I have used it on a few work projects with little to no issues, and it's being used by an extraction shooter that's under playtests atm
Yeah it's a plugin, don't need anything else
Yea saw that, the response to the playtests have been positive aswell which is great!
My requirements are more in the direction of higher tickrates / competitive environments
You can definitely handle that, of course as with any game with such tight constraints you'll need a lot of tinkering but I'd wager the GMC can handle it
I've been using it to route shooting hitreg through it and it works fine
oh it can do that to?
It supports instanced structs in the movement data so you can pass anything you want into it
I thought it was specifically focused on character movement / character controller creation
Oh yeah that's the main focus, but you can use it for other things like shooting
There's a demo shooting project with it, and while GRIM won't really heavily modify the GMC for anything non-movement related, he did give us instanced struct support (and custom type support so you can add your own) and he does expose some data when it's requested by the community
With the amount of settings you can change, you can basically do shooting like Counter-Strike where it's part of the movement data, so the server sees your shot basically the same way you did when it executes your move.
Makes it super easy to wrap your head around.
With CMC I know exactly what its capable of, and its proven, and understood by most relevant devs
With GMC there are too many unknowns, including performance esp. given the BP capabilities (usually comes at a big cost)
I'd need to see serious games running GMC before I even look at it
You can disable BP events, they're all called with a macro
In the component you can untick a bool, or in C++ you can just overwrite the macro to expand to nothing
Up to you
Extraction shooter dev managed a stress test with 200 complex pawns, 19ms on the server (no rewinding of pawns because that's expensive)
Granted they had no players but the GMC itself stood well
Oh that one, I read about that yesterday. It was clear it's client authority
But yeah not too bad
I don't think so
But they did heavily optimize the server side, went from 77 to 19ms
Although idk if the pawns were moving
guys, what do you think it's the best way to make loading screen works using server travel?
Join request: /Game/Maps/Development/Entry/Entry?Name=DESKTOP-4C1FM7J-DF9A101F499272C3B50812A0D90299B8?SplitscreenCount=1
[2024.10.22-20.41.52:288][858]LogNet: Join succeeded: DESKTOP-4C1FM7J-DF9A
[2024.10.22-20.41.52:355][860]LogNet: UChannel::ReceivedSequencedBunch: Bunch.bClose == true. ChIndex == 0. Calling ConditionalCleanUp.
[2024.10.22-20.41.52:355][860]LogNet: UChannel::CleanUp: ChIndex == 0. Closing connection. [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr: 127.0.0.1:52309, Name: IpConnection_2147482361, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_2147482520, IsServer: YES, PC: Menu_PC_C_2147482355, Owner: Menu_PC_C_2147482355, UniqueId: NULL:DESKTOP-4C1FM7J-DF9A101F499272C3B50812A0D90299B8
[2024.10.22-20.41.52:356][860]LogNet: UNetConnection::Close: [UNetConnection] RemoteAddr: 127.0.0.1:52309, Name: IpConnection_2147482361, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_2147482520, IsServer: YES, PC: Menu_PC_C_2147482355, Owner: Menu_PC_C_2147482355, UniqueId: NULL:DESKTOP-4C1FM7J-DF9A101F499272C3B50812A0D90299B8, Channels: 10, Time: 2024.10.22-20.41.52
[2024.10.22-20.41.52:356][860]LogNet: UNetConnection::SendCloseReason:
[2024.10.22-20.41.52:357][860]LogNet: - Result=ControlChannelClose, ErrorContext="ControlChannelClose"
[2024.10.22-20.41.52:357][860]LogNet: UChannel::Close: Sending CloseBunch. ChIndex == 0. Name: [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr: 127.0.0.1:52309, Name: IpConnection_2147482361, Driver: Name:GameNetDriver Def:GameNetDriver IpNetDriver_2147482520, IsServer: YES, PC: Menu_PC_C_2147482355, Owner: Menu_PC_C_2147482355, UniqueId: NULL:DESKTOP-4C1FM7J-DF9A101F499272C3B50812A0D90299B8
Hello I've a problem with my dedicated server, the client connects for a second but then immediately gets kicked out.
Then it tries to reconnect over and over again, getting kicked every time.
I've tried with a new empty gamemode, pawn, player controller on an empty map. It's not anything blueprint related, the project does not have any C++ code.
I've no idea why the connection doesn't hold, please help.
CommonLoadingScreen plugin in Lyra.
that should be const FText& in both cases
i tried that
and...?
uh. well i had thought id tried it. but in classic fashion when i try it again it works fine
thanks
sometimes the world just likes to fuck with me
ive done a bit of looking around and i feel like im on the right track with storing chat messages in gamestate and playerstate/playercontroller, and using replication to get a chat message to be sent to everyone, but everyone uses blueprints and i wanna do it in C++ and it just seems impossible. i cant get a proper reference to my blueprintable UI widgets and everything i try just leads to crashes.
why is this so goddang hard!?!?! all i wanna do is make my UI code be in C++ because i find that easier, and more customizable, but i still want it to be able to move and fiddle with my widgets in the designer.
Your game code shouldn't be trying to get a reference to your widgets. Work the other way around - have your widgets listen for event dipatchers on actors or components the widget needs to care about.
i feel like i tried that first, but i was having trouble with delegates and shit. i can try again
i might have to just refactor all my code at this point. its getting so confusing and half of it i dont use, all just trying various things.
i think one of the problems was that delegates dont return things, unless its not a multicast, but im not sure i can use a singlecast for this. is it counted as only one "Add" if im adding something that is copied among many players?
i tried doing a delegate with params, into an RPC that can then send back information, but something about that went wrong too and i dont remember what
You wouldn't use a delegate through an RPC. RPCs are one way.
A simple chat system would be something like...
Player input & send RPC to server with desired message, probably through PlayerState or component on such.
Server can iterate over the Player Array in GameState, send reliable RPCs to each PlayerState the message that was received along with the sending PlayerState.
When clients receive the message, fire delegate.
Widgets bind to that delegate and then update UI with the message.
hi! I want to spawn to players and I'm starting a new window (PIE) with 2 players and as a listen server in the net mode. I have this two PlayerStart but when I play the game only in the server work (now it doesn't work well too :() and I see the player with the playerstart view correctly. anyone knows why I might be missing or doing wrong?
the thing i tried was, sending information from my Widget, to the GameState through a delegate, which then stores the information, and uses an RPC to send it to the server. and then i need some way to get information back
im not sure thats what i did, i dont remember honestly
You can only RPC to the server through a client owned replicated actor. GameState while replicated, wouldn't be client owned. In order to send information back out, you'd have to RPC it back.
Or use replicated variables, but that doesn't really apply in this situation.
i cant RPC it back though, because i dont have access to the widget
ok explain what you mean by that. how do i make it listen
You can have that delegate created in the GameState, and it can have the sender and the message as parameters.
So following my example I laid out...
The sender of the message sends a Server RPC through PlayerState with their message.
The server can then get the Player Array (list of PlayerStates) from the GameState and iterate through them sending Client RPCs to each client with the message & the sending PlayerState.
The client RPC can then trigger the delegate in the GameState indicating the sender of the message and the message itself.
You'd set up your UI to listen for that delegate in its construct event (as it's easy to get the gamestate), and since the widget is listening for that delegate, it can do whatever logic you want it to do with the received message & playerstate that sent the message.
The delegate itself will only ever be triggered locally. It doesn't do anything over the network itself.
that sounds feasible. in line with some of the stuff ive been bandying around with, but this looks like it might actually work.
ill give it a shot after lunch!!!! thanks for this
i think i can revert some of the stuff ive been doing. i actually had the messages working perfectly when it was clientside, and then ive fucked everything up by trying to move stuff around to make it work with the server. i think i can pretty easily implement that change to extend the working parts i had
all the videos I see people only duplicate the player start and it works for them, idk why mine’s not
Solved it.
It was because of my dumbass calling the join function on the same level blueprint the server was hosted on.
The client recursively joined and loaded that map, leading to another join request and so on.
And now I have an ActorChannelFailure...
neat.
theres no way this worked first try right...
i need to find a way to test a second player
nothing EVER works first try
you can withint the editor
well it usually do for me 😆
get outa here. lies
ok how do i spawn a new guy
if you never did that, how could you know it works with multiple players?
well thats why im doubting if it worked or not
can i just drag a new default pawn class into the game?
its in the main frame, in the middle
im feeling pretty dumb right now. i cant find what that is
ah!
ok great. it did not work!!
only one client sees it
honestly kind of a relief. the world makes sense again.
although, they dont seem to be sharing the same world
so that might be the issue
it spawns different gamestates probably, one for each PIE
i need multiple players in one world
oh i had to play as a client
so....it looks like it works?
the world doesnt make sense
ok thats weird, the second client cant send messages
the first client never sent one ig
what do you mean
can you send a video of the client sending the message?because its impossible that one client can but not the other
maybe its the server
sure
weird that the hint text is there even if there is other text inside the editable box
and yes, i do have 2 player states
only one hud interestingly
and that spawns the widgets right?
so maybe they are sharing the HUD, and the second client is lying to me
you are porbably disabeling the button or something
well when i press the button, it does the "Button pressed" log, it seems my cast to the player state is not working for the second client
its not doing the chat submitted
im casting it here in native construct
so potentially, because i only have 1 hud generated, its only calling native construct for the first client
probably because im using the same machine, which has the same UniqueID
so i need to spoof a new machine somehow?
normally, there's 1 for each clients
normal never works for me
i also only have one player controller. maybe thats the issue.
maybe i need this to be on
so that didnt work. im noticing that im getting 3 sets of logs printed, from my Widget's NativeConstruct(), which means i should have 3 sets of the UI. im not sure whats happening
that's for testing with ping enabled
im also getting a standalone proc of it, idk why
and this is a good sign. the loop is working properly, it finds both clients and sends the message to both through the delegate. so im not seeing only one player's widget i think
i just cant post from both
if your game is using listen server, try with a server
im not sure what a listen server is, or if im using it
go learn more about multiplayer then, this is pretty basic https://cedric-neukirchen.net/docs/category/multiplayer-network-compendium/
alright
so i understand what it is, how do i know if im using it
.
maybe my issue is this. im doing my code through the PlayerState, but it seems like those dont have individual clients. i need to use the player controller i guess
or...both cleints have access to both player states? nvm idk. i read this chart wrong
i forgot how venn diagrams worked for a second
playerstate are replicated but values should alweays be changed on the server still
well. i still dont get what the problem is. i tried the listening server option and there was no difference
no matter what im only spawning one hud and player controller
the second client never has access to its playerstate
show hud initialization
how do i do that?
well how do you initialize it?
oh i just tried 3 clients. still one hud, one player controller, but the first and second clients can both send a message
idk its just set as default
does it automatically
third client can not send a message
my widget is added to the viewport through the character graph
im casting it up here. is the problem the index?
where is that running?
this is inside my default pawn
i read some of it
its a bit messy, sorry
was fiddling with inputs
i dont think this is the issue though. im just not getting access to the player state for some reason in one of the clients
and im only generating one controller
what's the function for the server call for sending the message to everyone?
you mean the RPC to send the message to the server, or the one that actually sends the message?
both?
the first is in my playerstate, the second is in my gamestate
you are looping through the player array? this isn't the way to do it
Why not.
I would use a RepNotify
I wouldn't for a chat msg that can be dropped
Show what the AddNewMessage do
^ i wanted to create a persistent log
then you use Rep_Always
it does a local broadcast
and the widget that is bound to it fires, and posts the message
local? you are on the server
this is inside a client rpc
What's the actual issue?
client rpc = only 1 client, there's your issue
thus why you should be using a RepNotify to call it on all clients
no but each playerstate is doing it
Client rpc just mean execute the function on the client copy
its looping over the playerstates, and calling an RPC on each one
compendium -> client rpc is called on owning actors
Yeah, what's that got to do with 1 client
again, this isnt even the problem. my messages are showing up properly
all of this code works already
What's the actual issue
Describe not showing up properly
I just told you, it's done for only 1 client, then others can't
so you are telling me that it's better to loop through all the playerstate, call a function, call a client rpc, and that's better than a RepNotify? I think otherwise
i only have 1 hud and player controller
that's fine
shouldnt i have 3 huds and controllers?
Each instance would have their own hud
Every machine run their own world and script
oooh. ok so i just cant see them in that client, and the other clients dont show their object lists
That window will only show what exist on the server
ok then what about the third client not being able to send messages?
Yea you can log them tho, if you want
Well what happend when the button is pressed? What logic is being run and where
I would imagine you do be running server rpc at button press
there is a problem with the OwningPlayerState, it cannot find it
which is up here
Btw does server rpc even work in player state
It's probably owned by the server by default
But I haven't really check
Replicated actor doesn't mean you can call rpc on it
my log is being called too many times
To call server rpc as client, the client need to own the actor
well, it seems to work in my code
I would suggest to move your send chat msg logic to player controller
Actually player state seems to be owned by the player nvm
yeah
player state is also unique to each joining player supposedly, while player controllers are assigned randomly, so i wanted to use playerstate
so each player always has the same log
Btw instead of logging, print string comes with the server client prefix. Maybe that can paint a better picture so you know who's calling what.
correct
is that the KismetLibrary one?
Yeah , you can just grab the code and see how it obtain server client prefix if you still want to use the normal logger
what the heck. just crashed after doing a livecode. idk what i changed lol
corrupted?
oh i accidentally commented out a line in my header
printstring was a good idea
so im getting a lot of client calls for this, and 2 server calls
im not sure whats going on
and now only 1 of the 3 clients works when i hit the button
the second time i hit play in the same editor session, 2 of the clients works
and now im stuck at 2
idk guys, im at a loss
at least i know that the message sending/recieving is working
thats the important bit
until i can actually test multiplayer somehow and figure out if this is a real issue
i will have to ignore it
Btw I gotta thank you mate. I had all of parts, I just had to get the flow correct, and you really helped me get my brain in order.
You can change what it shows in its settings btw
Never know that, I will look it up ty
Yeah there is a cogwheel at the top right of it
At the bottom of the menu you can select the world it is viewing
you can choose them here and see appropriate objects
good to know, thank you both
One issue I see going on here is that the Character Begin Play will fire on all clients when a new character comes into existence.... Get Player Controller 0 will usually return the local controller which will be valid and isn't necessarily what you want at all as if you have 3 players, that means its executing the logic 9 times in total, excluding the server's own execution (which would also be doing this for each character as well), but each time it's executing using the local controller, resulting in the enhanced input bindings and everything else you're doing there executing when it probably shouldn't be.
Generally speaking, you want to avoid using Begin Play for a lot of multiplayer type stuff as it may not be the correct point since it does execute on all clients whenever a Character comes into existence, including from when it Begins Play because it became network relevant on a client. You also want to avoid using the standard "Get Player X" type of getters in multiplayer as they won't always return exactly what you think they are supposed to return, especially when executing on the server.
So what is likely happening here, is that your UI is being created multiple times on each client, and there may be some kind of conflict in their visuals that prevents them from displaying right. From what I can tell, your RPCs and delegate are set up correctly otherwise.
what should i use instead of begin play to do my initializations and setup?
It depends on what it is you're trying to set up.
UI isn't really something that should be happening on Begin Play of a character for example. UI can just use the HUD class and that begin play will only fire on the local computer and only once since it only gets created locally and only by the player controller.
If you need to know when the controller possesses a pawn, you'd need to use the appropriate events to know when that possession happens -- there's several events within the PlayerController and the Pawn itself that are triggered when possession occurs , and usually at that point you'd want to set up your input bindings. Which one to use is based on whether you need the server to react or you also need the client to react to it..... If I remember right, there's Acknowledge Pawn or something like that on the controller which triggers on the owning client's Player Controller.
oh so this is a problem with my blueprint code i guess.
Seems like. Disconnect the begin play stuff on your character --- leave it there, but just disconnect it. Move the widget creation and addition to the screen to your HUD class. See if your messaging still works by "Playing as Client" and for 2 players, and see if both screens can post a message.
right ok.
im doing some other calculations on the begin play, i can probably just move the create widget part right?
You can for now, but again, part of the problem there is that you're using "Get Player Controller 0" and casting, which will always be valid as Player Controller 0 will always be the local player controller on clients, and then you're executing that additional logic on characters that doesn't really need to be done there.
same amount of calls doing that. nothing rly changed except i feel like the widget is darker than it was before
ok ill try disconnecting all of that
this...didnt rly work? its being called once on the server and once on the client now, but i dont have 3 instances working. only the first works
i just have this in my hud
How is OwningPlayerState populated in your widget?
Ok, rather than populating that in a variable, can you just get the value each time? One of the issues may be that you're populating with a null value as the playerstate may not have replicated to the player controller by the time the nativeconstruct event happens.
Like, basically make a function that returns your playerstate or something
right makes sense, i can try that
no wayyyyy that works!!!
dude. youre a genius
ach. im so happy
youve helped me out big-time twice today!
today was a damn good day
Glad it's working 🙂
Hey everyone, I'm having an issue when initializing multiple players with a controller each. In my gamemode, I use GetAllConnectedInputDevices to grab all controllers and then loop through them to create LocalPlayers for the ones that don't have one yet, and then add the mappingcontext for input.
My problem is that, when I have a keyboard and three controllers plugged in, the GetAllConnectedInputDevices node only returns three input devices. The last controller seems to not be recognized as its own device, but it's input DOES affect a player, namely the player that the second-to-last controller is mapped to. So the result is this:
Keyboard -> Controls Player 0
Gamepad 1 -> Controls Player 1
Gamepad 2 -> Controls Player 2
Gamepad 3 -> Controls Player 2
the above is with "Skip Assigning Gamepad ToPlayer 1" enabled
if I disable that setting, the result is the following:
Keyboard -> Controls Player 0
Gamepad 1 -> Controls Player 0
Gamepad 2 -> Controls Player 1
Gamepad 3 -> Controls Player 2
Can anyone explain why not all my controllers are recognized as their own input devices?
If I plug in the controllers, I see the "An Input Device has been connected" message in the bottom right, and the last two controllers both get the Platform User ID: 2, and Device ID: 2
so ive made this blueprint that allows a second controller to be used with player 2 and it works perfectly fine. However, when i reload the level(if the player wants to go back to main menu) and i start again my second player is not being set to my second player controller. Anybody have a clue why this is?
This is the error i get
I started a project with the third person template and made a function but I’m getting the no owner so won’t be processed error. I’m really new to replication and don’t know where I set the owner the function is on the third person character and the function effects the characters self. Do I set that on character spawn somewhere all examples I see online where for effect other objects so I’m lost
Gonna need some more details here. What's the function do?
Have you connected a reference to self to the proper nodes?
I haven't touched the gamemodebase functions of finding a player start and the choosing player start, but idk why sometimes it works correctly and some pawns get each one one player start but other times they get the same and it makes my other pawn to not start correctly
anyone knows why it might be happening?
the function moves the character left and right on the ledge. the server works but the client gets the error.
Are you sending an RPC to the client telling it to move?
Hey! Have anyone tried to do seamless travel on Lyra's Example? I'm experiencing the issue which sometimes doesn't spawn client's pawn due to 0 amount of PlayerStarts in the world. As I see, Epics fixed the problem when clients load before host, but all the evidence are pointing to this issue still exists. Btw I have PlayerStarts in the Persistent level. Maybe it's some sort of connection partially lost somewhere while the travel?
Actually it looks like the client model isn't moving at all on the server side.
All player information is saved on the server, and updates the client every tick with the "true" state.
It seems like you're not telling the server that your character is moving, so the server resets your client back to where it was. Make sure you have your properties set to be replicated to the server
What's a good way to handle inventory as a FFastArraySerializer when the item count goes to 0? I'm broadcasting a delegate on the PostAdd and PostChanged, but in the PreRemove if I try and broadcast a delegate with the item to be removed or if I try and broadcast just before I delete the item and mark the whole array dirty, then it doesn't broadcast out to BP the 0 value item hmmm
nvm I got it
How can I make the movement of a replicated actor with a projectile component smooth on clients? The movement by default seems to be choppy
@dark edge hey man
regardin the floating hp bar that only shows for the client thats attackign the npc
it works for the client but when the listen server dose it it shows for all'
since its rpc´d
what do u suggest :/ ?
anyone else got time to look at it :/ ?
What are you actually rpcing
what does the rpc mean
You are telling everyone "Hey everyone, X just happened"
Assuming ShowHealthBar is your RPC< don't call it that
yeah well
the Npc (serverside) take damage
then that runms an event that rpcs checking if the damaging player is equal to local player
Name it better, name it Multicast Took Damage From or whatever
You can do the sound in there too
that's your "Hey everyone, Jim just hit me" message
Then they run it, play the sound, ask "Is the local player Jim?", show hp bar if so.
true,
You'll want a separate event for Show HP Bar which locally shows the bar and starts a retriggerable timer to hide it
yeah but it works for clients it only shows for the client when attacking
but when the server is attacking its showing for everyone
oh
and taht event should be on the player right
no
nothing is on the player's pawn
don't say "on the player", that can mean their pawn, playerstate, playercontroller, connection, many things
gotcha more specific,
The ThingBeingHit wants to check if the ThingHittingThem is the local pawn
yeah
The code looks fine to me, put print strings and breakpoints and figure out where it's busting
oooooooooooooohhhh
your replication
that should be multicast
not to owning client
all this code is on the npc or whatever is being hit right?
yeah
Goblin42 says "Hey everyone, Jim hit me"
if you wanted to use run on client rpc it'd be within the hitting pawn and it'd be "I just hit Goblin42, make it show its hp bar"
either approach is valid really
telling everyone the ID of hitter vs telling hitter the ID of the hit thing
whats the best option for preformance ?
probably neither, just do the hits clientside too but it it all depends on your setup
you need to know about the hit to play sound anyway so it's 12 of one and a dozen of the other, just stick with what you got for now
Everyone needs to know about the hit anyway so that's the simplest
ok well if i change it to multicast (thats what i had before so idnno why run on owning client was set)
yeah, but when the listen server actor hits it shows for everyone thats the same issue
print strings
make sure things are what you expect them to be
print the ID of hitter
ok well when the client is hitting then its prinint as "client" when listen server is hitting its prining on "server" so the clients arent even doing the multicast
ok well so i solved it...
was stupid
the HpBar (Componnet) was replicated... so when the server set it to visible it became visible for everyone...
thanks for the help tho!
If I spawn an actor from the game mode for generating something on the server and clients, what is the safest way to notify the game mode when every client has finished executing the blueprint code from the actor? Sorry if this is a basic question!
Like is the best way to update a value on the client, send that to game state and then send that to game mode? Or is there something more straightforward?
You wouldnt send anything to the GameState.
The PlayerController would need to be the one to send an RPC to the Server.
You may as well just make a function call on the GameMode after that.
No need to involve the GameState.
But yes, thats pretty much your only choice.
Awesome info. I set all of my current multiplayer stuff up like a year ago and forgot some of the basics for communication lol
Thanks for the help!
I have one more question, sorry if this is also basic.
Not sure if I should ask this in PCG or Multiplayer channel but here feels better. If I want to spawn PCG from the server for all clients, is it best to spawn the PCG on all clients and pass the seed from the server or to spawn it from the server as replicated? Doing it all from server sounds more secure but would be more on the network right? And doing it all from clients would be faster but easier for someone to modify the generation?
I am going to be setting up dedicated servers soon so would like to make everything as cost efficient as I can, but I don't want to do anything that makes the game more vulnerable either
If you do it via a seed, then there is typically less replication required saving on bandwidth vs. replicating a ton of actors all with replicated properties. While it may be spawned locally, the server is still considered the authority, so if you're using something like the character movement component that allows for client predicted movement, and you had the server spawn a tree at a certain location through your PCG, the server would know that players cannot move into that position with the tree being there, so even if the client themselves modify their copy so that the tree isn't there, they can't modify the server's copy, therefore, the server would still send the client a correction and move the character to an appropriate location.
That makes sense. So sending the seed is probably the best option overall then. Thank you both this is very helpful 😄
if you want interaction with PCG spawned actors then there is still a means to link them across the network as well without having the server replicate the entire actor and its details by making them "net addressable", so a client can reference a specific actor and it can associate to an actor that exists on the server's end even if it wasn't originally marked for replication..
Good to know! We'll be needing stuff like that a bit later on. Thank you
Read the pinned material on this channel dozens of time. Practice, fail , read again then repeat.
Exi compendium and wizard mp tips and trick are both good starting point
Free? I found a plugin by Dry Eel and it’s 5$
most likely free, since Lyra is epics example game
Any good tutorials on how to implement it? And does it work with seamless travel?
I want to kill the person standing in front of me by drawing a linetrace, but the linetrace does not move with my aimoffset. line traces do not go where I look.
they keep going straight in front of you even if you move your camera up and down ?
Yes. Lyra is entirely free. You just copy the plugin from a lyra sample project's plugins to your own project and set up some stuff in your project settings.
It is also very easy to implement yourself to be honest.
I’ll try and let you guys know
when I shoot, the line trace is always drawn down at the same rate. only the server sees the linetrace correctly. there is no problem with aim offset, everyone looks where they are looking.
Thank you I’ll check them out and continue to read up on it I kinda moved forward because I was so stuck it felt like I was wasting time and when I learn more multiplayer stuff I’m thinking along that way I’ll figure out what’s going on with this problem.
Been banging my head against the wall on something that I'm sure is a very stupid fix.
Trying to spawn in 2 players on load (for a 1v1 fighter)
Depending on RPC, player controller is possessing either on the listen server or the remote client, but not both. Have tried several iterations of the below, with multicasting and authority checks // is local player bools. Nothing seems to want to play nice.
Please help? 😮
Github Branch: https://github.com/a-banoub/Mortality/tree/Rep_4
Yeah that's al ot of pretty random code
What exactly do you want to happen?
Also that branch you linked is a 404 on my end at least
Oh shit probably not public-
Yeah, I've started from scratch multiple times in a debug attempt.
Very simply right now, spawn a pawn and assign it to a controller
When should it do that
Right now on "G" key press. Just trying to get it working in some capacity before having it on play
Right, anything stopping you from using the GameModes DefaultPawn class and similar to do this?
In theory, all you'd need to is call a ServerRPC inside your PlayerController and calls "RestartPlayer" on it.
If you have a proper DefaultPawnClass (or even something dynamic via the Function overrides of the GameMode) set up, it should simply spawn it.
Well and possess even
If you don't want to use UE's built in stuff, then the ServerRPC would need to Spawn the Character and then possess it, but that's kinda all there is to it.
There is no need for a Multicast or anything like that.
Yeah that's how it should work in theory, not sure why the game mode isn't spawning correctly for defaults. Let me back up to "Main branch" github should be public now
G -> ServerRPC -> SpawnCharacter -> PossessCharacter
Im facing a problem with a multiplayer lobby. Testing in PIE, I have 2 standalone versions (net mode) running and both instances are Listen server, so either one can join the other.
When OnPostLogin on the game mode fires after the client has connected to the host's lobby, im executing a Run on Client event on the "client's" player controller from the game mode.
At that node im setting the player controller to view from a camera located inside the Level, by calling SetViewTargetWithBlend (im also doing the exact same thing when each player is in their lobbies).
The problem is that this fires "too fast" apparently and the Client has a Default pawn camera (like the spectator). I came to this result because adding 1 second delay to before that "fixes" the issue.
Im wondering if there is a proper way to know when is the correct time to start doing those things on the client without eye balling it with delay.
Thanks
So for one, you are better off just making your own APlayerCameraManager, assigning that in your APlayerController class and then in there define via overriding UpdateCamera (or whatever it is called) what the actual Camera view should be.
And then, what you witness is probably the Controller automatically changing viewtarget, which is a boolean on the PlayerController.
AutoDetermineActiveCameraTarget or something like that
I imagine it's Auto manage active camera target?
Damn ok ill give that a shot
But yeah, better would be the CameraManager
That is local and doesn't need the extra RPC
Also I haven't messed with camera managers I'll look into it as well
Alright sounds good
So backing up and having a start with no added code, pawns and controllers set to default and do spawn but do not possess correctly. Here, only the clients pawns are correctly registering. It looks like the listen server's controlled pawn gets overwritten. As opposed to the previous code I sent which does the opposite.
That fixed it 🥲 Spent so many hours and it was just a boolean
Yeah I've been there :P Quite some years ago by now though
You are using a GameModeBase? Not that this could break anything, but you should use GameMode and GameState, not the Base versions and also not mixing them.
The base versions are more for simpler singleplayer games fwiw
Yeah as said, use the normal ones, not base
Despite that, even if only one of the players spawns, shouldn't the other one see them at least?
Ah that's not visible in your screenshots
Looks more like only one see a character
Do you have enough spawn point in your level? Anything in the logs talking about failing to spawn the pawn?
You can try going into the settings of your pawn and changing the SpawnActor behavior to AlwaysSpawn
By default it can fail if it intersects collision
Understood. Right now they are spawnning but on top of each other, this wasn't always the case, I have the multiple spawn points setup in the logic but was running into the controller issue and wanted to attack that first (I've branched off of Main like 4 times with different approaches).
So they're all spawning and being recognized in editor and on respective clients, but just not controlled. Once the controllers are properly assigning will fix location
There is 0 reason for the controllers not possessing them
The GameMode will spawn the Pawns per COntroller and possess them.
If you can't control them even after they are spawned, then you are doing the Input stuff wrong maybe.
Here's a better look
Why is it 3 windows viewports? Wasn't it just 2 players?
Yeah, more debug attempt trying to figure out if it was indeed a listen server issue
Same thing w just 2 windows
I want to kill the person standing in front of me by drawing a linetrace, but the linetrace does not move with my aimoffset. line traces do not go where I look.
when I shoot, the line trace is always drawn down at the same rate. only the server sees the linetrace correctly. there is no problem with aim offset, everyone looks where they are looking.
Again, anything in the logs?
There should be no reason for it to not just spawn and possess, unless something is failing that I can't see
That Screenshot is too small
And you have way too many RPCs in your viewport.
If you already Multicast, why again an RPC to the Server?
And you probably can't use the Camera's Rotation for this, as that is usually ControlRotation, and that doesn't exist on SimProxies.
Use GetBaseAimRotation
That uses a replicated Pitch value.
I'm gonna head to the couch now though :<
In the video I watched, it said that I should replicate events in this way.
Yeah this is why I'm banging my head against the wall lol. Nothing I can see in logs but let me clean them up a little bit because there's a tick setting them off. One sec
Something to do with actor replication maybe??
Any idea why a for loop going through all actors of class: third person character only returns one forward vector?
Trying to make a weeping angels character but in multiplayer.
If you're calling a return in a loop, the return will immediately end the function preventing further iterations of the loop from executing. If not, show some code as to how you're attempting to retrieve the vectors of the characters.
That's redundant. GetBaseAimRotation should already take care of this in theory.
@slow holly Where do all your capslock prints and accessed none errors actually come from?
I’ll get some screenshots! One moment.
Character blueprint on tick trying to find opponent (Finding parent class of char and != self)
Think I'm onto something here, though, this seems to be assigning properly
You aren't doing a RELIABLE Server RPC on Tick... are you?
Just wondering, cause that could indeed cause things to stop replicating properly
Also the GameMode doesn't need a ServerRPC
Chaining them doesn't add anything to this
GameMode only exists on the Server to begin with
But yeah, that looks okay, despite the duplicated RPC
I am not nah but still running into issues.
I'm gonna play around for a bit and report back
There's something to do with the RPC and specifically controller possession here. It's consuming the listen server controller
@sinful tree
The 1st image shows that the loop runs on Event Tick and calls Move to Player which runs on Server.
THAT loop grabs the closest ThirdpersonCharacter to the Clown, and moves towards them. This part works.
(I originally had just the one loop but after the dot product stuff wasnt working i seperated them to make sure the data was fresh.
The 2nd Image shows the 2nd loop which is supposed to get the Forward vectors of all of the characters, and the location of the clown, then create the dot product. If the dot product is greater than .5 then multicast event is called to stop the clown. If it is less than .5 then the multicast event is called for the clown to walk. These are pictured in the 3rd image.
The main issue im having is that the code works well for ONE character, even when i run as TWO client players.
The secondary issue is that the dot product seems to think that the clowns location stays in one spot, because when I face the clown from the East side for example, he will stop when being looked at. But if i move my character to the clowns West side and face him the code is opposite. (I checked with a print string node, having inserted the clowns location and it does update every tick).
Should i have this code run in my character blueprint instead of the clowns? And then have it cast to the clown for the events? Is the location of the code causing an issue?
Sorry i know its alot! Just wnted to get some background information
I would highly suggest you try this in a project where you didn't already add stuff to. I'm relatively sure it's related to something you haven't actually shown yet.
The log printing and the delayed spawning is strange,.
Why is that an RPC on Tick with a GetAllActorsOfClass o.o
Why are there so many RPCs...
Tick is already called on every instance, if you want that to be called only on the Server, plug an IsServer or a SwitchHasAuthority there.
ServerRPCs aren't meant to filter
And GetAllActorsOfClass, while not that bad once in a while, should def not be called on tick
How would I update every frame then, or atleast so that when the person looks at the clown they will stop moving with no reasonable delay?
And the nyou go from a MULTICAST to an OnRep boolean, why the Multicast if you have an OnRep boolean to begin with?
Followed by another OnRep boolean in the AnimInstance? that thing doesn't even replicate
I feel like there are some tutorials out there that jus tell people to plug everything full of RPCs
The onrep was for something else I actaully need to move it back to a regular bool
The OnRep is actually better than the Multicast fwiw
Looking at the Clown is in theory a State
That should be communicated with an OnRep
There definitely are! Unfortunately theres no help for multiplayer weeping Angel, so ChatGPT is my only friend
Yeah okay, ChatGPT is the biggest horseshit you can use to learn
Did you read the Network Compendium yet?
yea, I would no depend on ChatGPT for any sort of specialized advice
You're also dragging wires across execution paths. The blue wire here coming in from off screen shouldn't be used like this.
GPT is good for copy pasting code that is too long but basic to write
GPT is good if you already know how this all works and you can fully filter all the shit it tells you
Tick already calls on everyone, if you want to check if someone is looking at it and then change something in the animBP, you can just use Tick without any RPCs and OnRep
The whole replication setup is redundant in that case
And for the GetAllActorsOfClass you should learn how to create simple Managers with an Array of what it should manage, and then use BeginPlay and EndPlay to register instances of that to the array.
Why? Just so i know the reasoning.
Should it be set as a variable and then that variable can later be plugged into the target for AI Move to?
E.g. an ActorComponent on the GameState can be the Manager with an Array of Characters.
And your CharacterBP can the get the GameState, get the Manager, and add itself to the Array.
Because you don't know what value you're pulling from. It could be cached, there may not be a value there at all.
The nyou can easily get the GameState and the Manager and its array to loop over
It's especially bad to do in multiplayer since data isn't conveyed across RPCs like this.
So while you may have a value set on the client for example, dragging it across into a server RPC wouldn't mean that value was transferred to the server.
I understand were critiquing the code here, and that there is a lot to fix, but the main issue im having is that the forward vector of only one character is being taken into account.
The actual move to code works fine, even if not performant
That makes sense^^
Sure, but you can't expect us to fully ignore the mess and add to it ):
It's more than that.... If it's not set up correctly to begin with, then trying to troubleshoot it is basically pointless as you'll continue to run into bugs.
So while it may appear to be "working correctly" it's not set up to actually work correctly.
I'm trying to understand the code
You loop over all Players, and try to find the closest.
I would be 100% happy to restart, and try again, but I can only find single player tutorials on the weeping angel.
So then i would run into the issue of needing to make it dependant on if any of the players are looking!
If you found the Closest (for that single frame), you save it and then loop over all.. players or so again?
And then you do some wrong Vector Math I think
ForwardVector minus Actor Location is nothing that makes much sense
Yes thats what it does right now. And i agree I didnt love the idea of the loop running every single frame, I just wasnt sure on how to check for the closest player frequently
If think what you want to do is checking if it looks towards it with a Dot Product
Yes i do!
I just want to see if the Thirdperson character is looking in the direction of the Clown
You need to use ACTOR LOCATION minus ACTOR LOCATION; normalize that and then dot product with the result and a DIRECTION (e.g. forward vector)
Something like this
DIRECTION minus LOCATION doesn't make sense here
what's the best way in a multiplication manner to spawn skeletalmesh components?
multiplication manner?
well in a multiplayer context*
currently, I'm spawning the component on the server.. (no replication at all are done by default)
In theory the same as any other Component. You'd need to ensure it's spawned on everyone and that it's stably named
Otherwise you won't be able to send it via RPCs. It doesn't need to be marked as replicated for that as long as it's stably named
tho, I'm already on the server, no RPC are needed I think..
maybe NetMulticast would be the way to go..
Destroy All Humans 2 released using GetAllActorsOfClass on tick - was fine! I STAND BY IT
Do you need to refer to it across the network?
I don't think Components naturally replicate when getting created
nop, it's like a particle effect but it's 3d and simulating physics that do not need to be really synced since it's just for visuals
Isn't that a bit better now with some sort of map lookup or does it iterate over everything?
It has always been a hashed bucket
If by "now", you mean like version 4.14
But I think it's better to learn a design pattern of sorts that makes it redundant
(for few years)
When is it created?
random moments during gameplay
I agree. But I don't think we should be hammering it as often as people like to.
Then it's probably enough to send a Multicast, yeah
If you need all of a certain actor - it is the obvious choice.
What I'm getting at is what is the minimum amount of state needed to know whether or not the thing should be there?
No, but when I see it in a noodle pile like those images, I will comment on it
Is this just cosmetics for some debuff?
Get stunned -> have stars spinning around your head
If you show me a "FindPlayerStart" code that uses it once to get all PlayerStarts, I won't say a thing.
it's just some satisfying fancy 3d effects (bone detachment)
Oh - I'm not even getting involved in that debacle 😅. A lot to untangle. I'm just "anti-anti-GetAllActorsOfClass" 🤣
what about GetActorOfClass? (for 1 instance)
So just replicate that fact. Replicate "this bone got destroyed" or "This skelmesh took a hard hit to this bone" or something to that extent
It literally does the same thing but returns the first instance if I recall.
by replicating it, do you mean that NetMulticast would work?
Depends on if it's meant to be stateful and super reliable or is just some short lived thing
I feel like all of those functions are called replicating something
think of it as a bone that ragdolls to the ground
Does it matter if dudes arm is missing 30 seconds later?
im honestly just going to remove it all and retry. Thanks for the help! @sinful tree @thin stratus
I think I'm just very anti-GAAOC when it comes to beginners that might learn a lot by avoiding it instead of relying on it.
I know how the node works, so I'm not anti using it.
well, he probably got hit.. this is what the player should think
If the dudes arm missing is a State Change, then it should not be a Multicast fwiw
People that connect late or come into relevancy range won't get the multicast again
So they won't see the change
That's what OnRep variables are for.
the state itself is handled correctly, but for the ragdoll effect of the visual bone.. that's different
base that on the state
what state are you syncing right now?
ListOfBonesDestroyed?
Let's say it's a simpler system, dudes head can either be missing or not. You could represent that with a single bool bHeadIsMissing(replicated, repnotify)
In the onrep for bHeadIsMissing, you'd look at the bool, and make sure the head is hidden/disconnected or shown/connected based on that bool.
A late joiner or someone coming into relevency range would see the state correctly.
wdym by what state are you syncing?
this
the character itself (3d skeletal full structure) is handled correctlty, the bone that is ragdoll (3d effect that is just a SkeletalMeshComponent) is a visual thing that happens when the full skeleton structure of the character has updated and should have a visual effect going on which is spawning that skeletal mesh component
So you have no replicated variables right now that deal with this?
for the character itself, yes
show them
UPROPERTY(ReplicatedUsing = ClientMergeMesh, EditAnywhere, BlueprintReadWrite, Category = "Bone")
FSkeletalMeshMergeParams SkeletalMeshMerging;
UFUNCTION()
void ClientMergeMesh();
Right now, how does everyone know that an arm should be chopped off?
is it a change in the FSkeletalMeshMergeParams?
as you told me earlier this month:
Server Hit -> Update SkeletalMeshMerging -> Client Update
wasn't me
no, you told me about how to handle Hits and a stat component for those
Anyway, assuming that's an onrep and it correctly replicates and has enough info to know what bones to disconnect, just do it through the onrep
I'm dumb, trying that rn
you shoot it?
the bone health is < 0
and is that a replicated variable?
GAS replicated, yes
Dunno much about GAS but assuming there's an OnRep or the equivelent, you'd do it there
Bone health got updated yall -> is it under 0? -> yes -> chop chop spray blood
Later you'll want to know how long ago that was so you don't walk into range of some beat up dude and watch his limbs explode off of him
my system is more complex so I'm basically doing
GAS (handles < 0) -> Component on Character (Update the character skeleton) -> GlobalActorManager (Spawn Component in the world -> visuals)
that's server only
You can't do things everywhere in response to attribute changes?
you can but why would you do so?
so everyone sees the arm chopped off
the base state that matters is that the bone hp is 0
that's all everyone needs to know
everything derived from that can be local
so then SkeletalMeshMerging would need to be replicate to access values on the client?
Keep mind that you need some kind of difference between the EndState and how you get there.
The EndState (arm invisible/gone) is the OnRep.
If you want the arm to fly off, you probably need an RPC alongside
Cause you don't want late joiners to see the arm fly away.
but that would be funny
Same as a barrel exploding vs it bring destroyed
Late joiners see the broken barrel but not hte explosion
'The EndState (arm invisible/gone) is the OnRep.', that's what I'm currently doing tho
Barrel Visuals -> OnRep
Barrel Explosion -> Multicast
At least as a very simple example that is
I think in GAS terms the transient effect can be a cue
are you dropping the arm off or disappearing it and spawning an arm that drops?
For the State part if it's attribute bound they can just listen to the Attribute on everyone
That runs through an OnRep already
The RPC part can be the Cue, yes.
Yeah it could be something like this
Listen to bone HP -> its zero -> disappear bones below it
Cue -> spray gibs everywhere -> drop a copy of the limb
You can of course also additionally hide the bone in the Cue to have it line up fwiw
but how is it different if you handle it using the OnRep GAS function or the OnRep function for SkeletalMeshMerging? at the end of the day, these 2 are OnReps so they would happen at the same moment or so and it's just better encapsulation
Whatever you do, I would avoid redundancy
In terms of multiplayer, it's all the same
if it's a 1:1 mapping of state to state, just derive the 2nd from the 1st
Where you do it is more about how your code is structured fwiw
don't replicate 2 parallel states that say the same thing
how do you make the bone disappearing is the hard part because skeletal mesh components are complex and do not handle multiple meshes by default