#multiplayer
1 messages · Page 284 of 1
I drop the slot in the area and it onDrop from the chracter a server RPC on this item to call OnServerItemAddedToInventory
That makes no sense to me.
You shouldn't Add and Item to an Inventory if it results in that Item being dropped.
Also if AddItem can lead to Case 2, then you are calling DropItem before calling Items.Add(..)
if (GetEquippedItems().Contains(EEquippableSlot::E_Helmet))
{
if (UEquippable* TargetSlotToUnequip = *GetEquippedItems().Find(EEquippableSlot::E_Helmet))
{
TargetSlotToUnequip->SetEquipped(false);
}
}
Still makes no sense to me :D
The condition for an Item to be added to an Inventory's Slot should be fully met before doing any Add calls.
Player's shouldn't be able to drag&drop items onto slots if the item can't be placed into the slot.
Case 1 is reasonable if you want the equipment that is in the slot already to be dropped to make space for the new item.
But Case 2 seems strange.
I will fix it now maybe this is the culprit that we are struggling with 😄
thanks for pointing this out
I assume you can add items in two ways:
- Pick them up from the floor.
- Via Inventory UI.
If 1. leads to the Equippable being automatically equipped, then dropping the item inside the Slot (if there is one) seems reasonable. If there is a condition for this to even be possible (e.g. can only equip if item is higher level or slot is empty), then the Pickup interaction should be disabled with a warning that tells that to the player.
And for 2., if a condition exists that can prevent equipping an item via UI (e.g. drag&drop, rightclick, etc.), then that UI interaction should also be disabled or at least not yield anything. If I try to drag&drop something onto a slot it can only do one of two things: 1. Equip the Item or 2. Not equip the Item. And since it's a UI action, I would assume that 1. would lead to the item that is potentially in that slot to be swapped out with the one I pulled into the slot. If that doesn't work, due to inventory not having space for it, then 1. should never be called and the condition originally should have failed.
If your inventory doesn't work like this, then you'd need to clarify.
Exception for the UI equip would be if you forcefully drop the item that is in the slot if the inventory can't hold it but the new item is otherwise valid to be equipped.
But none of all those cases would/should lead to an AddItem being initiated and then lead to the new item being dropped. Then you should have dropped the item in the first place.
Inventory UI is working like in Super People
list of ground items
list of backpack items
slots of equipped items
if from ground I drop an equipable on the equip slot, it adds the item to inventory and equips successfully and drops the old item if exist
if I drop equip slot in backpack or ground list it should unequip and drop the item
I am calling OnServerItemAddedToInventory in both operations from owning client to server
the first operation works perfectly
second operation works also if I don't drop the item
Yeah, that sounds all reasonable, but Case 2 is still weird.
Dropping an item from Ground to Equip Slot is what I explained in case 2. with the result being 1. (equip the item)
And then the old item optionally being dropped to the floor.
case 2 is reached if this item want only to be unequipped and dropped
But why does that happen in "OnServerItemAddedToInventory"?
case 2 will have a dedicated function
its temporary to make it at least work
If I equip an item in your game, does it get moved from the backback to the equip slot or will it exist in both ?
from backpack to the equip slot if this is equipable
backpack, helmet, cloths, weapon not showing in backpack list
Right, so that means that the action of "Equip Item", is internally just "Move Item from SourceInventory and SourceSlot to TargetInventory and TargetSlot."
And the same goes for "Unequip Item", just that Source and Target are swapped.
And an Item counts as equipped if it's in an EquipSlot.
Which means the UEquippableItem doesn't even have a reason for bEquipped to exist.
Cause you already know it's equipped if its in said slot.
Yeah, I have that bEquipped just to replicated its state
void UEquippable::SetEquipped(bool bNewEquipped)
{
bEquipped = bNewEquipped;
OnRep_bEquipped();
MarkDirtyForReplication();
}
Sure, but all Players have access to the Slots and can see that it's equipped or not?
And when the Inventory changes and replicates to Clients, one can easily call a function on the Item to say "Hey, you got moved, update yourself if needed." which replaces the need for OnRep_bEquipped to exist.
every player can see only their own slots in UI, and visual meshes are ofcourse replicated to everyone
Either way, the original thing with the Case 2 for me means that you should be handling this outside the item at an earlier stage already.
Moving an Item from SourceInv + SourceSlot to TargetInv + TargetSlot, no matter if it's equipping or unequipping, should always follow these two steps:
- Remove Item from SourceInv + SourceSlot
- Add Item to TargetInv + TargetSlot
If you can't move the Item to TargetInv + TargetSlot, then you should never enter this logic to begin with.
It will still be handled by a multicast or onrep and drop by server to spawn pickup and remove from inventory
Sure, my point is that any call to AddItem(ItemA) should not lead to ItemA being dropped, unless it magically makes sense in some edge case.
If AddItem(ItemA) leads to DropItem(ItemA), then you should have called DropItem(ItemA) to begin with.
AddItem(ItemA) can lead to DropItem(ItemB). That's totally fine.
That's you case 1
But case 2 is weird.
I am checking for if this item isvalid before starting to drag, which is is valid and when its dropped on a backpack or ground list to unequip/drop... its gets dropped and the slot remains unclear + the item is garbage for like 5sec
Cause you ask the Server to drop and the Client then has to wait for that to actually get back to them?
case 2 is just this item is unequipping self, and telling the outer to drop me
Then why not just call DropItem(ItemA) for it? Why does this happen inside a function that handles adding items?
Yes because only server can drop item, and I am telling the server in the same frame to first UnEqup and then drop
I will have this dedicated function later ofcourse
What is the proper way to teleport and rotate a player a short distance while being compliant with CMC ?
Predictively?
I don't think the CMC has a builtin Teleport functionality that can be predicted. If you set the Location in sync with the CMC RPC on the Server and locally, you wouldn't get a correction.
Rotation is usually ControlRotation driven, at least in most games, so that one you just do locally.
The problem is that you can't really send the Teleport request through the CMC RPC, cause then the player can cheat.
Was there a RootMotionSource node that allows teleportation? Can't recall.
Yeah, but GAS is not in sync with the CMC in theory.
They use two different, completely cut apart prediction systems.
You need to picture it like this. The CMC performs locally Move 1000, then sends an RPC to the Server so the Server can perform Move 1000.
If your GA changes the Location of the Character locally and Move 1000 takes that into account, but the RPC for activating the GA on the Server happens when the Server performs Move 999 or 1001, you will have a correction.
Partially depends on where your ASC sits. If it sits on the Character, you might be lucky and the two RPCs executed in the same Frame will arrive in the same Frame. But I'm not sure if that is a given at all times.
oh right
Order is also a thing. The RPC for the Move will instantly execute the Move.
If the Tick Order of the CMC and the ASC locally cause the ASC to activate the Ability, change the Location, and then have the CMC perform Move 1000 with the new Location, it would need to do the same on the Server.
But if the RPC, for whatever reason, arrives in opposite order on the Server, it would first Move and then adjust the Location.
I did a new experiment:
calling drop item before SetEquipped it behaves same as before
Character->DropItem(this, Quantity);
SetEquipped(false);
this means setequipped was skipped for clients
I mean in previous experiments, not in this new one
does it matter for client? I mean those function run within the same frame.
maybe I need to try without checking for isvalid
yes, both by server RPC
trying without isvalid will at least skip the grabage collector check
Now compiling this, its just an idea to explicitly unequip on client before server will even have chance to make it garbage collected
void AArmaCharacter::DirectUnEqupDropEquippable(UEquippable* Equippable)
{
if (!HasAuthority() && IsValid(Equippable))
{
// Client explicitly unequip
Equippable->SetEquipped(false);
ServerDirectUnEqupDropEquippable(Equippable);
return;
}
/**Check if Item exists in servers inventory*/
if (GetInventoryManager() && !GetInventoryManager()->FindItem(Equippable))
{
return;
}
Equippable->SetEquipped(false);
DropItem(Equippable, Equippable->GetQuantity());
}
void AArmaCharacter::ServerDirectUnEqupDropEquippable_Implementation(UEquippable* Equippable)
{
if (!IsValid(Equippable))
return;
DirectUnEqupDropEquippable(Equippable);
}
bool AArmaCharacter::ServerDirectUnEqupDropEquippable_Validate(UEquippable* Equippable)
{
return true;
}
this works but only for Server/owning client
i'm setting chaosvehicle throttle input to 0 on the server when i dismount a vehicle, but if i hold w and dismount the vehicle keeps accellerating despite that. any ideas?
the print 0.0 from server is the throttle input value of the vehicle
it happens if the server is driving it too
i've tried putting on handbrakes in that part of the code too but that also does nothing, despite having the requires controller for input option disabled in the vehicle movement component
it does the same thing even if i have the requires controller option checked
hello guys, I have a small question.
my friend is making multiplier game on urneal engine and have lag issues. is there resource that I can send to him?
I am not an expert on multipler really
This could be anything without more details and it would be better if your friend was the one asking for help because proxying it is not going to be fun
this vehicle thing is breaking my brain
tim sweeney certified hack
cant set input values despite the nice checkbox saying you should be able to
never change, unreal
yeah definitely
I just know that problem is related to ping and that's it
tim sweeney certified hack didnt fully work, my quadbike still drives to the sunset if i grab it, but only on the client
nvm, just 1 small change
thanks for being rubber ducks
that's your fault, leaving the vehicle with non 0 throttle
i set it to 0 throttle before i unpossessed, after i unpossessed and 2 seconds after i unpossessed, on the server and the client, and it kept doing it
the only thing that fixed the issue was to reset the vehicle
which is why im still confused, but at least i got it fixed.
that was the problem all along. why does it not stop if i set it to 0 throttle, even when the server prints the throttle at 0
yet it keeps going
spawn a temporary AI controller and make it possess the vehicle and than tell it to set the throttle to 0, and then check when vehicle velocity == 0, unpossess AI controller
I'm having an issue. I create a projectile both locally & on the server (Although I call the server RPC from my locally predicted branch since I'm passing the local "Aim Point" since Server can't get players camera location/rotation to know where the player is looking at). The issue I'm having is that, when the LOCAL projectile hits a player, for some reason it HAS AUTHORITY. So I decided to create a branch where I get the remote role to ensure that the non authority Projectile doesn't get to be the "source of truth" for applying damage on server or it would allow cheating really easily.
But the issue is that the SERVER Projectile DOES NOT HAVE AUTHORITY for some reason. So when I branch it by "remote role authority" the apply damage doesn't work, I assume because it's out of the prediction key so "send gameplay event to actor" fails? But I have no clue how to fix this.
the local projectile does have authority
becaues it's locally spawned
Are you trying to predict the hit locally or just the firing and let the hit do nothing?
why not just... mark the project with some simple flag after it is spawned that says it's locally predicted?
or better yet in the defaults of the thing that spawns it (deferred spawn etc so its there before beginplay)
Firing and play vfx but not let it deal damage since server projectile should be the one deciding that
I can do that but it doesnt matter because the issue is that the send gsmeplay event doesnt work on apply damage
what would the remote role be from the actual server?
Its authority
Why not use the actual net mode of the world here?
The issue is as I mentioned, the locally predicted projectile has authority (but not remote role authority since its not the server) so it goes to the client vfx (as it should)
But the server projectile Does NOT have authority even though the remote role is authority. Send gameplay event fails because no local authority
you said "Does NOT have authority" but your picture is not has authority, your picture is if the REMOTE has authority
Look at what HasAuthority does
Because its spawned projectiles. Locally predicted projectile has authority over its world despite not being made on server
net mode of... the world
the projectile spawning on the client does not change to a different world
How do i check the net mode of the world
the server will always have the server netmode (listen/dedicated) and the client will always have NM_Client
In bps
but regardless, it won't matter, the issue is not that im getting the wrong projectile to go the right or the wrong way
this node basically just asks if you AREN'T in NM_client
The issue is that the server projectile doesn't have authority locally
so send gameplay event doenst work
local and remote authority are different things
remote authority is not local authority
remote means "what's the status of this thing on the other side?"
hmm yea so none of the projectiles are hitting on the server I guess since true branch never prints. Which is kinda weird considering I 100% make a projectile on the server
debug
use chaos visual debugger
record state
scrub through (it will show all worlds at the same time)
I need to learn that thing
does it cover all the stuff like movement components or just tick setting position?
it's a bit tedious to make it render meshes but you only need simple collision here in most cases
it records literally everything that happens for any query and any physics body
it is not just a list of scene queries... it records every particle's state and every query and every hit result
thats nuckin futs
the only thing it might miss is maybe direct particle writes over time? not sure if those are all a new "thing"
the main reason it's useful here is that it shows the server and client together when recorded from the editor (at least by default)
so you can see the actual state of a dedicated server visually for example
💀 I have no clue how to use this
great news, there is documentation
I've been fighting over making this projectile stuff work on server but shit is not cooking
I did that yea but dont see anything other than the normal logs
I can't see anything either as luck would have it
show what you are looking at...
which version is this? it might be a bit weirder in 5.4 etc
the CVD isnt even on my world map or if it is its not loading anything visually (dunno if thats how its meant to be)
do you have any simple collision in here?
also it seems you didn't actually do what you said you did... record a live session and them do stuff then stop
you have no frames...
I did I just closed it and reopen
hit this, also just in case make sure you enable scene queries and evolutionstart etc
The worst phyiscs asset of all time (I just hit auto generate on it) 💔
yea I have all that but nothing shows on CVD still kinda weird
did you hit "record live session" and then simulate some game frames by playing?
also not sure what version you are actually on
I'm 5.5, I'll try changing map
weird still same issue
I'll have to look into the documentation tomorrow and see if im doing something wrong
But yea i really have no clue what could be wrong. The projectile is created on the server, it has authority and is the right netmode, when applying stats it's the same. But then the event bindings just says otherwise its so damn weird >.<
Wdym by its world.
Locally predicted projectile == firing client spawned projectile. It will only exist in that client alone.
So the firing client have authority over it, but it doesn't mean jack because that projectile only exist in that client. So the auth check for the locally spawned one is useless.
How i do mine, i spawn locally for the firing client then tell the server that I fire.
Server created a projectile then replicate it to everyone.
Everyone eventually gets a copy including the firing client. So there are 2 projectiles in the firing client. I simply hide the one that come from the server on the firing client.
when you RPC the server to spawn the projectile, set the owner on it, and do not replicate it back to the owner
there is no reason to have a 2nd projectile on firing client
My reasoning would be that I want to interpolate to server version for the firing client. Isn't that how unreal tournament does it?
Yes, UT does have Client side prediction for Projectiles.
Yea I believed most game would implement client side projectile.
No body wants to see a bullet appearing 0.2 second after they fire.
Im just checking if I should interpolate to thr server version as the firing client or not as the person above says theres no reason to replicate back to the owning client.
Thats debatable.
I dont have testers yet and interpolating is still in my to do list so I can't see any result yet.
you definitely do not need 2 projectile actors
Players care if it "feels" responsive.
It doesnt have to actually be responsive.
Its not uncommon for things like grenade projectiles to not be predicted for example.
Animations can easily cover the latency
Those would be predicted
Players hardly notice the difference
never use actors for bullets from the first place
Just use fvx? Well my is a fireball atm.
just use physics based structs
if not (the most annoying one to answer) you would use niagara or pooled ISM for the visual part
they can have velocity, drops, speed, damage etc
entirely avoiding actors for this without having context for the needs of thier project is not very productive (unless they need hundreds of these it really won't matter)
Yeah agree, and I personally avoid using actors for bullets cause bullets are temporary stuff, they spawn and destroyed in a short time period assigned
I am sure bullets will not exists for 5sec in any game people make
so spawning an entire actor for only 5 seconds just to fly to target and hits it and make damage is not a good idea to me
yep, and you save a ton on spawning them (adding a new element being very cheap here I assume, could even re-use the array too)
spawning actor spawns 2 actor for clients instead of 1, works fine on server. any reason why?
do the cleints get this RPC called alongside the server spawning a replicated version?
debug it or add a simple print string to see who it gets called on and when
is the floor actor replicated from the server?
if it is, you probably only want to spawn it on the server unless the client having a fake one locally is useful
Thats exactly what I do but the thing is my projectile needs to send a gameplay event and for some reason it doesnt work with the server projectile (only reason why i can think of is due to lack of authority) when I check 'Has Authority' server projectile doesnt have authority and the send gsmeplay event doesnt work
Which projectile? If you are talking about the one that client spawn then it obviously can't send any data or rpc from it self since it only exist in the client side.
There shouldn't be "lack of authority".
For client spawn projectile, that client will be auth.
For server spawned one, the server will be the auth.
Im talking about the server projectile. When checking 'On Component Hit' 'has authority' the server projectile never has authority
Whos checking?
In the client, that server projectile. That client will not have authority.
In server, the server will have the auth.
when you say "has authority" is it still the node you had earlier that checks remote authority? there are two authority variables
generally people are going to assume you mean local authority 99% of the time when you don't specify
Im just using has authority. If i use 'is server'it never triggers which is weird
I have logs everywhere checking authority and net mode, during projectile creation, during stats initialization, on tick while its travelling, etc... But "Is Server" never triggers on hit and when using "Has Authority" node, the local player projectile shows authority and the non client projectile doesn't its so fucking weird I can't figure out what oculd possible be wrong here. I've been trying to debug this for 2 days, I'm gonna learn about the CVD like you said yesterday to see if it helps just woke up
It depends who's running the code.
Say im the server and you are the client.
And I spawn a replicated actor. And have the code that print auth on authority and remote on client upon overlap.
breakpoints are a lot easier to use than reading a log file
If the overlap code run on me, authority will print.
If the overlap code run on your computer, remote will print.
logs are still very useful here but you want to see the exact state of the entire object right when something happens in a way you don't expect... just using print strings is going to take a while
BP debugging is fairly straightforward but you will need to enable the callstack window in the window dropdown (which doesn't show itself for some reason, who knows)
Is there any plugin for multiplayer which is giving character movement controller for pawns and actors to be smoothly replicated in MP games?
My current solution is choppy af
I'm doing a mix of bps and c++ but yea, creating the server projectile is in c++ while most everything else is in bps besides things like playing VFX and sounds
this doesn't change what I said
breakpoint -> look at screen to see what the object is doing at the point where you want to decide to do one thing or the other
there are plugins that do this but you should be able to get decent results with the cmc
it has multiple network smoothing modes
also if you are on a listen server you may need to manually enable network smoothing/interpolation on it
however you did not share any context so I am guessing
the thing is like I dont even know what to breakpoint, everything seems fine up until it starts moving, and the moving code is literally just initializing the stats and then I just deal with the on hit event
Something seems to be breaking between the moment it begins to move and the hit
Peak youtube multiplayer tutorial
If the actor meant to be in sync, don't use multicast.
Set to replicate and let sever spawn. Everyone will get a copy.
you might be improperly messing with the MaxWalkSpeed on the CMC
that can cause serious desync and choppiness if you aren't handling speed changes properly
how are you applying the damage on the server bolt in your example? Do you send gameplay event to trigger a damage ability or how you doing it?
Not via game play event.
But with gameplay effect
On component overlap -> apply GE damage
Not sure if I want to use game play event here.
Why the reroute, i just call the damage gameplay effect. Straight to the modifier.
So I kinda figured out the issue, at least I got to work I mean. I was trying to send the gameplay event from the projectile directly, even if I set it as reliable server the server projectile wasn't working. I changed it to my weapon that's owned by the player character and now it works properly. Will try applying the gameplay effect directly though maybe ti works even better
Just remember that the only way for a client to communicate to server is via server rpc from actor that it owns.
By default its the player controller and character.
Maybe player state from what I recall.
yea that was what was causing the issue
Calling rpc on non owned object will not reach the server and you should see warning on the logs.
I wasnt getting any unfortunately its why I took so long to figure out >.<
@frosty harbor not sure why u are sending tag here though.
maybe if i did it in c++
You pretty much let the client have a say in dealing damage.
Without verification they can just kill anyone they want ( cheat )
Wouldn't be different in this context.
At most client send data about its projectile, direction and time stamp.
Server replays the data and check if its close enough to be tolerated then decide to apply the damage or not.
I'm checking local role authority, the server projectile doesn't have local authority so that's the one I'm allowing to apply damage, is that not the right way to do it? If I use "Is Server" it's never true
Not really, I forgot you have to handle the version on the client. My bad
Yea
Can't remember how I handle mine. Been ages since I touch my combat system.
But pretty much on my end. I have the server apply gameplay effect to apply the damage on overlap.
I mean this works since the non authority one is always the server projectile but I wonder if doing it this way allows cheating somehow
Depends on what your apply ranged damage does
yea its what im doing pretty much
If it doesn't do any check whatsoever then yea client can just say hey I hit this person with 9999 damage.
But i'm gonna switch this to apply the gameplay effect directly probably
Hmm but it shouldn't be an rpc in theory
without it being an rpc it's being sent by the owning client so it doens't have server authority >.<
So you want the client to have a say?
What i have is not combat tested but i let server have full auth on the matter.
Meaning that. I only check the overlap in server and apply the damage on server.
The only thing the client have a say is. Hey I cast a fire ball spell on this direction.
No but that's the problem, I can't get the server projectile to start all of this itself. The "On Hit" event is returning the server projectile as not having authority and the local predicted bolt as having authority
Server say OK and spawn a fireball then replicate it to everyone.
The firing client fireball is but a cosmetic. It doesn't have a say if it hit something.
If you spawn the projectile on server. 100% server have authority over it.
You need to check which machine / player is hitting the event.
It does but "On Component Hit" is always returning otherwise
On who? Client or server?
It says client has authority and server projectile doesn't
Come again.
When you doing on hit event. Is that the locally predicted one or the server projectile?
Locally spawned projectile will only spawn on the firing client.
It doesn't exist on anyone else computer.
So in this instance the firing client is the authority.
Now if you spawn a projectile on server. The server will be the auth of that projectile.
I know, its hard to explain but like the On Component Hit event simply never has the server authority
You most likely observe the wrong instance
I never have that issue on my end
Hit and overlap work as intended.
I mean I print string and both prints show from both projectiles, one has authority the other doesn't, if I send the non authority one (sever projectile) to my weapon base "Apply Ranged Damage" it still doesn't work without my turning it into a server rpc >.<
This is what im doing to ensure the initial projectile is local only
Then I create a projectile on server (Server Fire Ranged Shot)
Then I'm checking when they hit on component hit
Btw speaking of GAS i don't think rpc inside GA is a good idea. But not deep enough my self to think im correct.
Normally you would send a target data.
I benefit from certain tutorial. If you want to look at.
Not free though.
send me please 🙂
But he does show how to make multilayer fps project and a rogue lite with gas (networked)
And it even cover certain networking concepts like、client prediction, server reconciliation, network clock, etc.
@frosty harbor check Stephen ulbardi in udemy
I have an actor spawned from class, How do I set that actor into the owner so I can use settings like owner no see or see correctly?
Its particularly a Skeletal mesh I have in my actor class that I want to make sure owner no see and do see work
so do something like this? Server = Owner no see Client = Owner see?
for FPS arms for example
I'm just pointing at the node to set the owner of an actor
oh
You can play around with the bool. I don't use them my self.
Set the owner first. Say you spawn FPweapon for player 3. Make player 3 the owner of the weapon via set owner mode.
I did that for my Blueprint Weapon actor, but for owner see hides the skeletal mesh for both FPweapon and 3rdPersonWeapon
So I think its not set correctly to the character
Oh nevermind I see what you mean
it worked but now its spawning a 3rd skeletal mesh into the world where i am standing at and it stays there when i move away
Gtg , share your code and setup here for others to see.
Got the wait target data working properly but yea still have same issue, On Component Hit is still showing that the predicted projectile has authority and server one doesn't, and the "ApplyRangedDamage" still only works if i make it a server rpc >.<
I still can't tell which instance you are talking about.
"Predicted projectile has authority and server one doesnt" don't make much sense to me.
I can only say for predicted projectile, the client will have authority over it but it will only exist in that client alone. This actor is unreachable by anyone else, the server or other clients.
You need to bring more context, such as which machine runs the on component hit at the time you are checking the authority.
At this point on component hit may run in many instances.
On the firing client, it will end up with 2 projectile. One predicted one, one from the server. Both will fire on hit event.
On server. The server spawned projectile will also run the on hit component when it hit something.
On other client the replicated server projectile will also run the on hit event.
So without more info, can't say anything else.
what do you mean which machine runs the on component hit, I'm just using the "On Component Hit" from my projectilebase class and checking the authority of the projectiles that trigger a component hit event. How do I check the specific instance it's running on? But if I had to guess it's running on client since its detecting client projectile as authority
log it
It returns simulated proxy for server projectile if thats what u want me to log
And for the local prediction projectile it returns authority
I gave the scenario above. Every players is running their own code. Every player have the copy of the replicated projectile with the firing client have an extra projectile that it spawn locally.
The on hit will trigger when it hit something on respective machine.
With 3 players scenario and if the projectile hit something at the same time (disregard lag for now). Then you will trigger 3 on hit event.
show code, how you are logging it
the component is a bullet? and it is fired on server?
the component is a sphere collision component (but the mesh is a bolt/arrow). And it is fired on the server and locally as well for instant feedback
(and it has travel time, not hit scan)
so you are getting hits for only server and other clients? but the bullet is fired on local client for instant hit and on server for all other clients?
I'm getting hit triggers from the locally predicted bolt & from the server bolt yes, other clients only get the server bolt hit
client 1 only saw the simulated proxy bolt
(which is the server bolt)
show code how you are spawning bullet
Nevermind, I found out why its doing that. It was spawning both meshes from client and server, so I set the 3rdperson weapon hidden in Client and FPweapon hidden in Server. I dunno if they will affect performance.
I don't see issue in this code, but no sure why you have this issue
maybe check if the actor set to not load on client in replication
😭 been fighting this for so long
I had that enabled yes so I couldn't see the replicated projecitle, I disabled it to debug some stuff but yea nothing changes
and its like
In C++ when I do the Init From Weapon part I literally log the netmode and everything
[2026.01.03-15.22.37:386][761]LogTemp: Warning: [InitFromWeapon] NetMode=1 HasAuth=1 Role=3
[2026.01.03-15.22.37:386][761]LogTemp: Warning: [AfterActivate] NetMode=1 Auth=1 Vel=X=2260.622 Y=-1067.161 Z=27.467 Speed=2500.000000 IsActive=1
So it is properly spawned and moving on server
[2026.01.03-15.22.38:302][837]LogTemp: Warning: [SERVER HandleImpact] BP_Bolt_C_0 Auth=0 NetMode=3 HitActor=BP_PlayerCharacter_C_0
[2026.01.03-15.22.38:303][837]LogTemp: Warning: [SERVER HandleImpact] BP_Bolt_C_1 Auth=0 NetMode=3 HitActor=BP_PlayerCharacter_C_1
Suddenly its always NetMode 3

(I call that in the on hit component)
check each component in the actor if they are set to replicated, turn it off
only replicate the actor itself
it will auto replicate sub objects in most cases
everythings off besides the actor
the others are all off
forgot to turn off the always relevant but yea
maybe check the shooter game weapon class, they are doing similiar things as you and their system works fine
I do replicate the Init Data though could that be the issue?
void APV_CombatProjectile::InitFromWeapon(APV_WeaponBase* InWeapon, const FVector& InShootDir)
{
SourceWeapon = InWeapon;
if (InWeapon)
{
const FPV_RangedWeaponStats& Stats = InWeapon->GetRangedStats();
InitData.Speed = Stats.ProjectileSpeed;
InitData.GravityScale = Stats.ProjectileGravityScale;
InitData.LifeSeconds = Stats.ProjectileLifeSeconds;
InitData.BaseDamage = Stats.BaseDamage;
InitData.DamageEffectClass = Stats.DamageEffectClass;
}
InitData.ShootDir = InShootDir.GetSafeNormal();
ApplyInitData_LocalSim();
}
void APV_CombatProjectile::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(APV_CombatProjectile, InitData, COND_InitialOnly);
}
void APV_CombatProjectile::OnRep_InitData()
{
ApplyInitData_LocalSim();
}
void APV_CombatProjectile::ApplyInitData_LocalSim()
{
if (!MoveComp)
{
return;
}
MoveComp->ProjectileGravityScale = InitData.GravityScale;
MoveComp->InitialSpeed = InitData.Speed;
MoveComp->MaxSpeed = InitData.Speed;
MoveComp->Velocity = FVector(InitData.ShootDir) * InitData.Speed;
MoveComp->Activate(true);
MoveComp->UpdateComponentVelocity();
if (InitData.LifeSeconds > 0.f)
{
SetLifeSpan(InitData.LifeSeconds);
}
if (AActor* Inst = GetInstigator())
{
CollisionComp->IgnoreActorWhenMoving(Inst, true);
}
}
Init Data replication should not be the issue, since its a struct and support replication
🤔 then got no clue
try to shoot a bullet on server and replicated the shot using onrep with conditions to skipowner
and than instant hit locally
i mean if I play as listen server then its always authority
you can use a replicated int as a bullet counter
running listen server , host is always authority
the second client will be client
is that from a default ue5 project?
I'm not sure if they updated it, I checked it once long time ago in ue4
dont have it in the ue5 projects
its on the github
the game samples I see is only lyra starter game
is that the one?
dunno if they have locally predicted shooting in that one
Hey people, anyone got any suggestion or resource how to dynamically filter out certain actors from some connections?
I'm using Iris (and building an MMO-lite game) and I'm currently tackling stealth. I'm already using their spatial grid dynamic filter and want to intercept the filter list and filter it further (stealth check) but I can't wrap my head around the mess of indirection, internal object indices, net ref handles and the whole lot of bit mask magic. I can't quite convert the object index into a net handle and then resolve it to a UObject because it seems that this is exactly what they want you to avoid doing (I'm assuming for decoupling/performance/GC issues).
Interestingly enough, I can get the ConnectionId, Controller and Pawn easily inside the Filter function (UNetObjectGridWorldLocFilter::Filter(FNetObjectFilteringParams& Params), but the filtered out objects that are stored in the bitarray part of the params that I'm supposed to filter against are unresolvable as far as I can tell.
use the bridge... it's 2 lines of code to convert it to a uobject
Are you sure? Unless I'm missing something it doesn't seem to have a function to get anything from a uint32 object index.
Let me see... You should be able to ask the replication system about the internal index to net ref handle
All I could find were some hidden/non-exported functions for internal use inside the net ref handler class.
How would you suggest to deal with reloads? Right now I'm adding a loose gameplay tag when shooting (IE: NeedsReload)
And I can only reload if I have that tag active.
Reloading triggers GA_Reload which plays a montage & at the end of the ability (when montage ends), I remove the loose gameplay tag.
However since it's a locally predicted GA, I both, add & remove the loose gameplay tag before the server does, which means that in that period between the client removing the tag & the server still being mid montage I can Spam "R" to reload & it will begin a second reload on the client. How do you reckon I fix this?
Only allow the server to end the ability.
yea figured it out ty
Yeah... this is surpingly locked down... I am wondering if you have to make your own mapping of the external info from the bridge
Of course going to the uoubject from the bridge is indirection but it's not like it will matter much for small counts
ah, I think I found something (NetRefHandleManager is stored in the filter, you can use that to get the net ref handle and then the brige to get the uobject, I will make a simple example soon)
Lyra seems to be hitscan though no?
Not with travel time / on hit component / on component overlap
@covert marten
void UBattlementNetObjectGridWorldLocFilter::OnInit(const FNetObjectFilterInitParams& NetObjectFilterInitParams) {
Super::OnInit(NetObjectFilterInitParams);
// cache the engine bridge in here as a member pointer to a UEngineReplicationBridge. Not sure if this is the only way though but it seems easier
EngineBridge = NetObjectFilterInitParams.ReplicationSystem->GetReplicationBridgeAs<UEngineReplicationBridge>();
}
void UBattlementNetObjectGridWorldLocFilter::Filter(FNetObjectFilteringParams& NetObjectFilteringParams) {
Super::Filter(NetObjectFilteringParams);
// Here iterate over the bit array view set earlier... I would suggest checking the size of the view first though just in case as it might assert otherwise
NetObjectFilteringParams.OutAllowedObjects.ForAllSetBits([this](uint32 InObjectIndex) {
// NetRefHandleManager lets us get net ref handles from internal index
UE::Net::FNetRefHandle NetRefHandle = NetRefHandleManager->GetNetRefHandleFromInternalIndex(InObjectIndex); // This is not exported so this won't work, darn
if (UObject* Object = EngineBridge->GetReplicatedObject(NetRefHandle)) {
// etc..
}
});
}
ah ffs, this might not be exported
simple enough to edit the engine to export or expose a getter in the replicationsystem
but you should not have to imo
whats not exported?
nothing in the NetRefHandleManager is exported at all
let me see what i did
I'm sure I missed something here
i did const UE::Net::FNetRefHandle RegionPointRefHandle = ReplicationBridge->GetReplicatedRefHandle
this works to get the handle
UReplicationSystem* const ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(Region);
if (ReplicationSystem)
{
const UEngineReplicationBridge* const ReplicationBridge = UE::Net::FReplicationSystemUtil::GetActorReplicationBridge(Region);
const UE::Net::FNetRefHandle RegionPointRefHandle = ReplicationBridge->GetReplicatedRefHandle(Region);
UE::Net::FNetObjectGroupHandle Handle = ReplicationSystem->FindGroup("XXXNetworkedActors");
ReplicationSystem->AddToGroup(Handle, RegionPointRefHandle);
}```
we are starting with ONLY an internal index
yes, you can manually modify groups from user code
that might be easier than using filters as intended
looking at UNetObjectConnectionFilter
seems theres ways to do it without needing the manager handle
they seem to do it in bool UNetObjectConnectionFilter::AddObject(uint32 ObjectIndex, FNetObjectFilterAddObjectParams& Params)
to keep a local array of objects
those are all FInternalNetRefIndex
look at what actually calls that
so yeah doing stuff like AddInclusionFilterGroup and others externally will be much easier
So I did some further debugging and apparently if I hide the server projectile (by skipping the owner through net relevancy), the "On Component Hit" doesn't even register a hit at all for the server projectile 💀
Funny thing is if I force both the locally predicted and the server projectile to be spawned on server, not a single one of them comes with authority so none trigger hits
god Im going insane
you could look how UT did predicted projectile
not sure if its the greated example
but we dont predict projectiles
just the vfx to make it feel like its instant, etc
Yea I mean I can do that its not the problem
The problem is why cant the On Component Hit detect server projectiles >.<
🤷
if you want help show what you are actually doing to check authority
last time you showed using remote role which is probably not what you want
and my advice from earlier still stands: just see what the state of the actor is by debugging
it will save a lot of time in the future to not have to guess
I tried the CVD went over the documentation but jsut couldnt get it to show the map so I could properly debug but yea. I've tried debugging things a million different ways, it always comes down to server projectiles never having authority. Here's a clear example of what I mean:
I added "Has Authority" check in my GA_Shoot to ensure that ONLY server projectiles get spawned (in this case it'll only be 1 since no locally predicted projectile will be spawned since no authority).
Then in the On Component Hit, I check both the Local Role & the "Has Authority" switch and it ALWAYS returns: "Simulated Proxy" and "No Authority". My train of thought was like, okay if we know it's reversed, server projectiles have no authority, then fuck it, lets jsut make those be the ones sending the gameplay event, but yea, turns out you can't send the gameplay event if you don't have authority, even if I literally call a server RPC 💀 its just so weird this whole thing
it checks if the author has authority
the owner of this graph, yeah
authority is defined by who owns the actor ultimately, if its local spawned, not replicated, then client is the authority over the actor
Authority != Server
I know that
But I can't get the hit results of the server projectile properly is the issue
so you want IsServer check here to ensure only server runs that code
like I know the locally predicted projecitle has authority in its own instance
Yes I've tried, IsServer, IsDedicated but neither worked, never went past true (or at least never prints anything when trying to debug)
then your server projectile is not hitting where you think it is
so nothing triggers
so which one is it, the server projectile never colliding in 3d space or the check to consider if they should fire the event not doing what you want on the server?
i am thinking his projectile is never colliding
which makes me think its not where he thinks it is
we don't even know if it's dedicated or listen server either
on a dedicated server you have to remember that it doesn't care about rendering things... for this reason it might not think it needs to update skeletal mesh positions
i have seen people do dedi server stuff and forget that skeletal mesh positions are not the same on server
I thought about that as well, maybe the server projectile wasn't going where i wanted but I can see the server projectile being replicated just fine on the 2nd client
and going where i point it to
so they fire the gun from the same spot, and its miles off
is this a listen server or a dedicated server
right, there is no reason server wont overlap/collide with stuff where client does
unless you never turned on collisions on the projectile
aslo chaos visual debugger makes this trivial to debug as it instantly shows where the object is on the dedicated server... some debug drawing actually tries to render from dedicated to clients as well but visual logger does as well
(server side)
Its just the default ue5 editor server dunno which mode it uses, I'm playing as client to emulate a normal player behavior
thats dedi server
since they are on 5.5 last I checked it might be an earlier version of chaos visual debugger but afaik it should work fine
yeah... you might want to read the faq
when i make systems (especially if im going to do prediction)
i always validate it works before doing prediction stuff
https://cedric-neukirchen.net/docs/multiplayer-compendium/dedicated-vs-listen-server this is super super important to understand
ie i will just spawn the server only projectile
and not even fire a client side projectile
running before walking
I know the difference listen server is p2p hosting, the server is (one) of the players
its not p2p
no...
common misconception 😛
you said "dunno which mode it uses"
you need to know which mode it uses
"client" will spawn a dedicated server in that doesn't render as a viewport
i honestly think you should just fire the server projectile (remove the client side projectile)
and do some debugging
its what I did here
without seeing your code, setup, etc
we can't really help
like we don't know how your projectile is setup
listen server will make the first PIE viewport the server and a player, but you still need to be aware of them potentially not updating meshes they can't see if they need to simulate them
record a video of it? breakpoint in the projectile code if you have c++ (ProjectileMovementComponent)
I would STRONGLY suggest not using a dedicated server setup if you don't need to
unless you plan to host dedi servers for your game, most indie games will be listen server
Well it's the goal haha, for melee combat it was significantly easier to get it right compared to ranged combat >.<
it requires a lot more work and consideration just to make it possible for players to use it or connect to it
i find melee combat harder than guns/bows 🙁
especially for performance/correct hits
you know the dual wield guns in fortnite
i heard they are just a single gun
but act like 2, with a single combined skeletal mesh
the idea of "an item" and "what you show in your hands" are two completely different problems generally
yeah
when i did turret for our tank, it was a single gun
but alternates the barrels it fires from
even if they fired different things
I think a really common not-so-great idea is when projects use an entire separate actor as a weapon because it just creates a lot of complexity for timing
i use seperate actor for weapons :/
as long as you don't have like, the internal weapon state coming in at a weird time it's fine
the weapon actor does all the timing/state stuff
if it only has things that aren't the actual prediction etc on it or sim proxy info it's probably not going to matter
like our weapon actor did everything for the weapon but it was very integrated into the character/controller :/
bit like UT4
my new system is very modular/seperated
as long as the replicated state comes in in a way that makes sure it doesn't constantly race condition that's maybe fine
like you can add attachments, adjust weapons, change everything so easily all with "Weapon Modification" data asset
my #1 concern is always complexity from network replication and what happens after that does not matter to me... you can separate the replicating struct from how it works visually entirely and use as many actors as you want for visuals/behaviour etc
and this is mainly for faster paced games (for something slower it won't matter nearly as much)
yeah i mean for replicating the weapon replicates when the owning actor replicates
never on its own (this was with repgraph though)
and ideally is filtered underneath them etc
so it will effectively be a replicating component more or less
not done/tried this with Iris yet
Iris can make dependencies too
but yeah it was also more for like if you cant see the pawn, you dont need the weapon
(from replication point of things)
on the clients
anything that is something you need to know about that isn't related to the raw location on sim proxies is generally going to be on the playerstate
but it's a bit hard to draw the line there lol
yeah or we have TeamInfo actors for team related stuff (just cause those are global team stuff)
sometimes having stuff on the playerstate that represents the pawn in a way is insanely frustrating if you aren't perfect about cleaning it up (for example, if they respawn and the playerstate needs to be aware of that but still has data from the previous "life")
but we have private/public team info actors (similar to what lyra did but they never actually implemented the private one..)
that's a good idea
though i have the ASC on the playerstate for players
separate private actor can replicate only to one team which is smart
but this is crucial cause some stuff is "player wide" not "pawn specific"
ASC on playerstate is fine... it would be on a separate object anyways from the movement comp
so we have to clear up/reinit on pawn changes
but a lot of people put it on the pawn, cause... to them it feels easier. but you loose the "player wide" stuff
yeah but it's mostly as simple as just caching the last known pawn to compare to decide when to clear it out when it changes (for a playerstate driven asc)
might have gone a bit mad with the Modular Gameframework plugin..
i am a big fan of that, it really helps avoid race conditions when multiple components exist on the say the pawn
it's actually arguably better in some ways to have it on the playerstate for perf because it doesn't need to be recreated between respawns but I don't know how much it really costs
ie a component wont do its work, if its pre-reqs are not ready
you just have to be careful you dont deadlock yourself :p
init states are insanely useful for networking
but I think the implementation is a bit confusing
ie if a comp is waiting for X and another is waiting for X
and Y is waiting for both but one of the X needs Y
boom, deadlocked
yeah generally speaking it's easier if one place directs the check instead of mutually waiting
you just want a chain of if statements
i think that framework could be a bit easier to grasp
or simplified
but i hardly ever use UActorComponent directly anymore
the one people forget a lot is not just "the actor is present" but also the actor is KNOWN AND ACTUALLY SET on everything that has something like GetPlayerState
if your code ignores this things will randomly return null because you assume a pointer is set in the scame scope as beginplay
its all mainly UGameframeworkComponent
the way replacing components works is super confusing
also it not adding them as instanced components is just dreadful in the editor lol
i mean i dont know why the stuff in UGameframeworkComponent is not in UActorComponent, having them seperated is weird
cause InitState stuff should be possible on all components
It's fine to not have it on everything
90% of actor components in your game are not init states
they are scene components
yeah that is true
i do love UPlayerStateComponent, just those convenience accessors etc. and forcing it to be where it should be
people know this is for playerstate only
no ambiguityh
i hated when i made components in 4.27 or w/e and people slapped them on things they were not designed for. i had to write my own stuff in OnRegister to throw a wobbly lol
https://www.youtube.com/watch?v=Wj5QqYte_9I bit longer than expected but yea showed the whole setup. Can skip the end if u want since its just showing the debug prints (Spoielr: Is server / is dedicated server is always false)
@frosty harbor hmm
what spawn actor node
you using?
the default engine one?
yeah you are hmm
Just regular default engine spawn actor, I also ahd all of this done in c++ previously using spawn actor deferred but was running into the exact same issue which is why i moved to blueprint to debug faster but yea still same issue
socket transform on a dedicated server... (only do that if you are sure it's actually updating as you intend on the dedicated if this is from a skeletal mesh)
also that weapon get can silently fail 🙁
at the start of the video you can see it, but basically what it does is I run a get muzzle transofrm WS function
FTransform APV_WeaponBase::GetMuzzleTransformWS() const
{
if (CombatMesh && CombatMesh->DoesSocketExist(MuzzleSocketName))
{
return CombatMesh->GetSocketTransform(MuzzleSocketName, RTS_World);
}
return CombatMesh ? CombatMesh->GetComponentTransform() : GetActorTransform();
}
gotcha ill remove that
wait
leave that
but just to prove the issue
go to the skelmesh
and allow bone updates on server
should be Optimization->Visibility Based Anim Tick Option = Always Tick pose and refresh bones
which skeleton is this from?
yea
whatever that is
also the dedicated must have the anim instance you expect as well
if you set that dynamically
you know
theres a much easier way to do this
is for your client to tell the server its loc
low key its been so long I dont even remember how im setting them lol ill have to double check
which avoids the insanely complicated problem of praying the character is where they are on both sides
of the projectile itself?
the RPC that activates the ability
but you should also be passing the other loc
instead of this, you send this to the server
oh i see
but you would probably need to make your own targeting class to send extra data
or use a server rpc
I mean can't I just quickly debug this by simply removing the spawn transform location to the player view point location instead of the muzzle?
ah wait no
it also doesnt get retrieved on server
when I say debug I think I mean actually using a breakpoint to see the current state or using dedicated visualizing tools
cause this is instant
i would not even use WaitTargetData, the issue with this is actually spawns an actor
which seems bad for a instant thing
did you look at how lyra does it?
is that async tracing or waiting on a net sync?
cause you can use that same concept but fire a projectile
instead of hitscan
if you look here
they get all the data needed
send it as replicated target data to server
yea I did but would have to change the whole setup and I was scared of just running into the exact same issue afterwards with the on component hit but i'll try
and server uses that data to do the line trace
but you can literally make it fire a projectile instead
you can produce a specific target data
send to server
then consume that for the server side projectile firing
the key is this const bool bShouldNotifyServer = CurrentActorInfo->IsLocallyControlled() && !CurrentActorInfo->IsNetAuthority(); if (bShouldNotifyServer) { MyAbilityComponent->CallServerSetReplicatedTargetData(CurrentSpecHandle, CurrentActivationInfo.GetActivationPredictionKey(), LocalTargetDataHandle, ApplicationTag, MyAbilityComponent->ScopedPredictionKey); }
I will try that tomorrow, although I don't think the muzzle location is the issue because when I shoot I can see the "server" projectile coming out frmo the muzzle socket location and hitting the floor but yes I will also try doing it the way lyra is doing for sure since I just cant seem to fix it with the mehtod i was trying to do
yea the local cleint doesnt see it
if I have both windows open from 2 clients you can see from the other client
I hide the server projectile from local client
yeah but why doesnt local client see it?
shoukld have disabled that
so you can actually see it
because I was initially trying to get it to work with the locally predicted projectile as well so thats the one local players should see but yea i guess its better to have it on for debugging
ty will be trying this tomorrow then, will try to remake the whole thing from 0 again and see if I can get it to work the way lyra did
i mean
lyra is a bit complicated
cause it does hitscan, etc
you can really simplify it
yeah it's a great example of how to do things but Lyra is 10x more complex than any normal game needs... it is designed to change form based on data but most games never need that
Lyra supports shotguns etc as well I think
I forget how they did that but I already nuked all lyra content in my project
iirc this one takes in target data
ah wait
yeah this never got finished
to support spanwing an actor predicted
ignore :p
Shouldn't be too hard to add in
Can someone plesae help me understand why the interface I'm calling on is only receiving the Character and Location variables properly
It makes no sense to me. All variables are valid when calling, but when received by called BP its losing them somehow
what is "target"
if it is not a network stable object like an asset or a runtime replicating object, it will never be able to be serialized in an rpc
It's a properly replicated object spawned at runtime
Again I've got 2 variables transmitting their data properly; but for some reason the bool and int are not
you did not include if the target was replicating in your original description
Yeah my bad, it is
"only receiving the Character and Location variables properly" is two things
@frosty harbor
/**
*
*/
UCLASS(Abstract)
class SHOOTERGAME_API UMyProjectileFiringAbility : public UGameplayAbility
{
GENERATED_BODY()
public:
UShooterGameplayAbility_RangedWeapon(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
virtual bool CanActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayTagContainer* SourceTags = nullptr, const FGameplayTagContainer* TargetTags = nullptr,
OUT FGameplayTagContainer* OptionalRelevantTags = nullptr) const override;
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override;
protected:
virtual FTransform GetTargetingTransform(APawn* SourcePawn, EShooterTargetingSource Source) const override;
void OnTargetDataReadyCallback(const FGameplayAbilityTargetDataHandle& InData, FGameplayTag ApplicationTag);
UFUNCTION(BlueprintCallable)
void DoWeaponTargeting();
// Called when target data is ready (Client and Server)
UFUNCTION(BlueprintImplementableEvent)
void K2_OnRangedWeaponTargetDataReady(const FGameplayAbilityTargetDataHandle& TargetData);
private:
FDelegateHandle OnTargetDataReadyCallbackDelegateHandle;
};
this is probably the simplest example
ofc it wont compile, but it gives a very simple idea
I am unsure why a replicated variable is being sent in an rpc here if it's already replicated, but since it's a boolean it's trivial to send as it's just 1 bit
the integer though should work fine here.. what value is ACTUALLY appearing on the other side? there is no such thing as an invalid integer value unless you think negative 1 is invalid here? (is that the default for the events input params?)
The only thing appearing on other side is Character and Location vars
this node converts a boolean and an integer? I did not even know you could do this... does this print twice?
my message says "what value is ACTUALLY appearing on the other side"
I am asking what the value is
a boolean can be either true or false
i see a bad mix of replicated vars and multicast here
oh, oof
this is why i always make seperate things
cause you cant trust bp users
i make explicit overridable stuff
plz esplain
its a bit hard on BP only projects
yeah I'm not sure if you can enforce this in any way in a bp event
can it just be non-public?
still waiting for epic to make the way GAS overrides work just a simple template
(they check internally if there even is a BP override before calling any bp events, in theory I think this avoids a ton of processevent overhead)
yeah
i did some of that manually for our stuff
to reduce some costs
back on Red Solstice 2
{
auto ImplementedInBlueprint = [](const UFunction* Func) -> bool
{
return Func && ensure(Func->GetOuter())
&& (Func->GetOuter()->IsA(UBlueprintGeneratedClass::StaticClass()) || Func->GetOuter()->IsA(UDynamicClass::StaticClass()));
};
static FName FuncName = FName(TEXT("ReceiveTick"));
const UFunction* TickNodeFunction = GetClass()->FindFunctionByName(FuncName);
bHasBlueprintTickNode = ImplementedInBlueprint(TickNodeFunction);
}```
we did things like this
to disable an actor ticking if bp never implemented the tick node
we couldnt enforce it to always be off
nor expect designers to flip the bool
this was a way to reduce some costs
I was actually a Senior Tech Audio Designer for a Star Wars game; then after moving to a different project at Take-2 our studio got shut down; now I'm just renegade with a few other devs who've been laid off and we're working on a goofy multiplayer dinosaur game
I love learning, and I feel really good being able to make things work in blueprint, but every programmer with a good head on their shoulders who looks at our project is like 'oooh geeez'
I'm implementing really basic performance optimizations like distance / render based tick adjustments, distance culling etc..; it's a stylized game with lower poly stuff so it's not too bad. I'm just ruing the day we gotta have a real programmer rebuild all our systems
Huh?
Your bp multiplayer project is cooked and you are looking for programmer?
Try #hire-a-freelancer or #hire-a-studio
is there any logical state check missing?
bool UWeaponManager::srv_PickupNewWeapon(AWeapon* NewWeapon)
{
if (!NewWeapon)
{
return false;
}
uint8 Slot = FindPreferredSlot(NewWeapon->GetType());
if (Slot >= MAX_SLOTS)
{
return false;
}
EWeaponEqupState NewState = EWeaponEqupState::Holstered;
AWeapon* OldWeapon = GetWeapon(Slot);
if (OldWeapon)
{
NewState = OldWeapon->GetWeaponState();
DropReplacementWeapon_Internal(OldWeapon);
}
else if (!GetEquippedWeapon())
{
NewState = EWeaponEqupState::Equipped;
}
NewWeapon->SetSlot(Slot);
NewWeapon->SetWeaponState(NewState);
SetWeaponBySlot(Slot, NewWeapon);
if (NewWeapon->IsEquipped())
{
CachedEquippedSlot = Slot;
if (OwningCharacter)
{
OwningCharacter->SetPlayMode(EPlayMode::Armed);
}
}
return true;
}
I have an inventory component within my player character. When they disconnect I want them to drop their items, would EndPlay (RemovedFromWorld) suffice for this to happen? Or could I run into a situation where the component is already destroyed before I can spawn the items?
try override PlayerController->PawnLeavingGame()
do what ever you need to do, then call Super
@meager spade Thanks for looking into it, both of you. I think I'll just simplify my logic for now and get back to this later.
Groups won't work well here because there's too many combinations, each character that's stealthed should be checked against any other character that's relevantly close. The idea was to leverage the prefiltered per-connection from the grid filter and just strip out stealthed characters that aren't revealed as an additional filtering step (or leaving them in if revealed), but I guess I might have to rethink this due to Iris' structure. Thanks in any case!
Honestly I think this is a huge pain point about Iris that should not be this annoying... Ideally we just use bags of integers in iris internals but it's frustrating that Iris classes can get the ref handle whenever they want but user code is forced to do this stuff
Might honestly be worth bringing up in feedback somehow while Iris is not actually finished
Yeah, I didn't really understand the point in hiding this sort of thing while internally their example filters outright use it directly. 🤔
@covert marten What you wrote initially about not being able to get the UObject is by design, as you already suspected
As soon as you start accessing the UObjects, you throw Iris out of the window.
One of the main performance gains of Iris comes from iterating over stuff that sits very close together in memory, so that the caches can work as well as possible.
Accessing UObjects, which are stored "somewhere" in memory, will slow this down tremendously.
Iirc, adding/removing Actors from Groups very often is also not really wanted.
I'm well aware of cache misses, but I lack the knowledge how to pass in some data for filtering. The filters come with 8 bytes of data (which the world loc grid filter uses all of) but I can't find a way to inject a few bytes more to do some game logic.
I looked at Iris a couple weeks/months ago to learn how one would tackle a mechanic found in some MOBA games.
Characters within a brush would be invisible to the other team, unless a teammate is inside the same brush or any actor that grants vision is within the same brush.
That turned out to be more of a headache than wanted.
well... not really
they access things to get net ref handles from the internal object index all of the time
The annoying thing is that specifically for the Locations, Iris caches those upfront and never actually touches the Actors that those Locations belong to directly.
the "idea" is to generally prefer inline arrays and integers, sure but it's not fair to go "you are holding it wrong" when it's something they do hundreds of times in their own filters...
I would say it's worth trying to not NEED to do but it's insanely tedious to work around this restriction when it matters
Getting a Handle from an Object is not the same as actively accessing the Object.
What I mean is that one should not start casting to custom classes to access custom properties and methods for filtering.
I assume the proper way for that kind of stuff is to either handle it from outside, via the Groups, as long as that isn't done too often.
Or to check how Epic handles the Locations.
Collect the data upfront like they do and then use it within the filtering to avoid accessing the Objects directly.
But I doubt that's possible without Engine changes, cause the Locations stuff looked pretty "hardcoded".
the way Epic handles it is entirely inside of a bridge that is not going to be replaced by user code ever
Yeah, when I looked at it I felt like it's missing some form of user-code hook for this stuff.
it is possible for users to add new net object factories but is absurdly advanced to do so (maybe could just extend an existing one but I doubt it)
Yeah, it's a bit of a headache. The docs explain rather highlevel filtering and prioritization, but fail to offer guidance on more complicated setups.
yeah I'm definitely of the mindset that a filter should IDEALLY not be going "hmm.. what class is this so I can cast to it?" but when a new object is added to it you don't even get a net ref handle...
BUT... the internals do!!
which they use to get info from the factory
see FReplicationFiltering::SetFilter
I think to me the nice thing would be including the net ref handle with the UNetObjectFilter::AddObject, that way users only really have to do typical Cast<T> spaghetti once and can store a faster lookup mapping
The type of filtering that my MOBA example and maybe @covert marten 's problem would benefit from is the Dynamic one I assume.
But that is instantly flagged with "You shouldn't use this if possible." and has the limitations of an Actor only being able to be part of one dynamic filter at a time.
yeah... I'm more familiar with the client part of iris more so than the filtering/prio parts
Owner: Object replicates to the same connections as its owner. Connection: Object replicates to specified, allowed connections and does not replicate to specified, disallowed connections. Group: Object replicates to the same connections as all other objects in its group. Dynamic: Object replicates based on custom, dynamic filtering.
I think it has a series of priorities for filters it mentions but I have 0 clue how they work
is that from docs based on old replication?
ah, net conditions
no Replay conditions 😔
There are inclusion and exclusion groups. The Group description is totally misleading.
It's totally possible to do Stealth by using Exclusion Groups.
But at the same time Epic warns for using Groups that way if one moves Actors in and out of Groups very often.
Without specifying what "very often" means.
FReplicationConditionals::GetLifetimeConditionals is one nice place all flags get set
Group
Iris includes an API for creating groups and managing the objects those groups contain. You can also use groups as a filtering mechanism. This is a flexible way of changing which connections a set of objects can replicate to without requiring you to manually keep track of which objects belong to which groups. Example use cases include filtering based on:
Team Squad Streaming LevelAn object can belong to more than one group. You must add groups to the filtering system for it to consider them for replication. Once you add them, you can modify which connections members of the group are allowed to replicate. You can set groups as allowed or disallowed for replication to:
A single connection A set of connections All connections
Like, it's easy enough to write some Stealth Manager for the game that handles Actors being placed into Exclusion Groups based on Stealth and Team.
And I would probably start with that and then check if that's really a performance impact.
so you would need a unique group for almost every team... that's probably fine
Yeah, depends on the game of course.
In a 100 player free for all, you'd have 100 groups.
And WoW PvP you'd probably have 2.
I'm going to say these changing should be sparodic enough to not matter unless it does something insane like force polling them all again
Yeah, going in and out of Stealth is probably not happening that often. I was worried about it in my example, cause entering and exiting a brush can happen pretty often.
In non-Iris, this is actually really annoying to resolve.
Cause Epic added a random cooldown for NetRelevancy changes.
yeah this is kind of where Iris starts to actually matter
And with "random" I mean actually random.
Relevancy issues are the bane of my fucking existence and whenever I debug them I literally just bonk things to be culldistance of like ~100m and just run back and forth until I see what's wrong
Took me a bit to turn almost everything off that they added, so that Characters in said MOBA game would stop replicating the second they enter the damn brush.
I would say any larger game should consider making relevancy part of their "test the game" flow somehow even if it's literally just you checking your work every so often
relevancy pop-in can cause a lot of crazy situations that normally never happen
Yeah, it's a bit of a different story here as it wasn't about relevancy bugs.
yeah, just me bitching about relevancy lol
There are some config variables for how much time has to pass between 2 relevancy changes, before UE even accepts the next one.
I can kind of see why because flip/flopping would be expensive
And that makes sense in general, and battles actors that are right on the edge.
but that is frustrating
Yeah, but if you set those to 0.0 via config, then there is another randomized delay they add.
Hardcoded of course.
Something between 0.0 and 0.5 seconds or so.
If you turn that one off too, you start bricking replication, cause then things like the GameState start flicking back and forth.
So I ultimately had to add the delay by default to Actors and then set it to 0.0 on the Pawns.
Never do I want to iterate on changes that involve changing Actor.h again.
My wife did a lot of Iris work the last couple months. Idk what she all added, but I think one thing was the ability to replicate properties based on NetRole.
I think the need for that came with NPP, that allows serializing properties based on target NetRole. But since moving to Iris nuked the NetSerializers, we wanted that feature back.
There is, after all, a lot of stuff in Mover Sync/AuxStates, that is really not needed on specific Proxies.
What can be the best way to have multi skel comps in a single character class?
default mesh; //leaderpose
UPROPERTY(VisibleAnywhere) USkeletalMeshComponent* SKM_Backpack;
UPROPERTY(VisibleAnywhere) USkeletalMeshComponent* SKM_Armor;
UPROPERTY(VisibleAnywhere) USkeletalMeshComponent* SKM_Helmet;
UPROPERTY(VisibleAnywhere) USkeletalMeshComponent* SKM_Feets;
UPROPERTY(VisibleAnywhere) USkeletalMeshComponent* SKM_Legs;
UPROPERTY(VisibleAnywhere) USkeletalMeshComponent* SKM_Body;
UPROPERTY(VisibleAnywhere) USkeletalMeshComponent* SKM_Hair;
I mean each skel comp is 4512bytes with alignment of 16 bytes
ofcourse I don't want them to occupy
size 36,096bytes
alignment 18bytes
since used for only visual representation of a mesh using leaderpose from main mesh
Having just one, for example.
Mutable, ignoring whatever mess it can be, sort of aims to fix that.
That said, not sure what the bytes matter tbh. Replicating a pointer to it shouldn't invoke the full path more than once anyway.
But given you are not using TObjectPtr for your UObjects, you probably are still stuck with UE4, sooooo guess you gotta live with that.
I was trying to do it on runtime, when the player equips a backpack, create a holder for it on runtime , register it
or merging multiple meshes into one will be a trouble to handle I think
private:
UPROPERTY()
TMap<FName, USkeletalMeshComponent*> VisualComponents;
public:
USkeletalMeshComponent* GetVisualComponent(const FName& ComponentName)
{
if (USkeletalMeshComponent** Found = VisualComponents.Find(ComponentName))
{
return *Found;
}
USkeletalMeshComponent* NewComponent = NewObject<USkeletalMeshComponent>(
this,
*FString::Printf(TEXT("Visual_%s"), *ComponentName.ToString()));
NewComponent->RegisterComponent();
NewComponent->SetupAttachment(GetMesh());
NewComponent->SetLeaderPoseComponent(GetMesh());
NewComponent->SetHiddenInGame(true);
VisualComponents.Add(ComponentName, NewComponent);
return NewComponent;
}
void RemoveVisualComponent(const FName& ComponentName)
{
if (USkeletalMeshComponent* Component = VisualComponents.FindRef(ComponentName))
{
Component->DestroyComponent();
VisualComponents.Remove(ComponentName);
}
}
Mutable constructs a single transient SkeletalMesh Asset based on design time assets and runtime values. So basically what you would like to do/have.
If you can't use Mutable, cause you aren't using UE5 (...), then you will probably have to continue creating a SkelMeshComp per Asset.
I did something similar but again, when binding a on hit delegate this is what i get
[2026.01.04-13.08.04:012][183]LogTemp: Warning: [Projectile BeginPlay] BP_ProjectileBase_C_1 NetMode=1 Auth=1 Role=3 ShotId=0 Replicates=1 SkipOwner=0
[2026.01.04-13.08.04:012][183]LogTemp: Warning: [InitFromShotData] BP_ProjectileBase_C_1 NetMode=1 HasAuth=1 Role=3 ShotId=1 SkipOwner=1
[2026.01.04-13.08.04:012][183]LogTemp: Warning: [AfterActivate] BP_ProjectileBase_C_1 NetMode=1 Auth=1 Role=3 ShotId=1 Vel=X=2270.444 Y=-1046.449 Z=-5.345 Speed=2500.000000 IsActive=1
[2026.01.04-13.08.04:068][189]LogTemp: Warning: [SERVER HandleImpact] BP_ProjectileBase_C_0 Auth=1 NetMode=3 ShotId=1 HitActor=BP_PlayerCharacter_C_1
[2026.01.04-13.08.04:069][189]LogTemp: Warning: [SERVER HandleImpact] BP_ProjectileBase_C_1 Auth=1 NetMode=3 ShotId=1 HitActor=BP_PlayerCharacter_C_1
Netmode of the projectile changes somehow, still have the exact same problem as before
use GetDebugStringForWorld
that way it has a nice client/server/listen server string for these
@frosty harbor do you have parsec or teamviewer?
might be easier to actually see whats happening
im still old school
namespace DominanceLoggingHelpers
{
const TCHAR* RoleToShortString(ENetRole Role);
FString GetRoleString(const AActor* Actor);
FString GetNetModeString(const UObject* Obj);
FString GetRoleString(const AActor* Actor);
FString GetLogContext(const UObject* Obj);
}
#define UE_LOG_DOM(Category, Verbosity, Object, Format, ...) \
UE_LOG(Category, Verbosity, TEXT("%s " Format), \
*DominanceLoggingHelpers::GetLogContext(Object), ##__VA_ARGS__)
#define UE_LOG_DOMFMT(Category, Verbosity, Object, Format, ...) \
UE_LOGFMT( Category, Verbosity, "{Context} " Format, \
DominanceLoggingHelpers::GetLogContext(Object) \
__VA_OPT__(,) __VA_ARGS__ \
)
namespace DominanceLoggingHelpers
{
FString GetNetModeString(const UObject* Obj)
{
if (!Obj) return TEXT("NULL");
if (const UWorld* World = Obj->GetWorld())
{
switch (World->GetNetMode())
{
case NM_Standalone: return TEXT("STA");
case NM_ListenServer: return TEXT("LIS");
case NM_DedicatedServer: return TEXT("DED");
case NM_Client: return FString::Printf(TEXT("CLI"));
}
}
return TEXT("Unknown");
}
const TCHAR* RoleToShortString(ENetRole Role)
{
switch (Role)
{
case ROLE_Authority: return TEXT("Auth");
case ROLE_AutonomousProxy: return TEXT("Auto");
case ROLE_SimulatedProxy: return TEXT("Sim");
case ROLE_None: return TEXT("None");
default: return TEXT("?");
}
}
FString GetRoleString(const AActor* Actor)
{
if (!Actor) return TEXT("NA");
return FString::Printf(TEXT("L:%s R:%s"),
RoleToShortString(Actor->GetLocalRole()),
RoleToShortString(Actor->GetRemoteRole()));
}
FString GetLogContext(const UObject* Obj)
{
if (!Obj) return TEXT("[NULL]");
if (const AActor* Actor = Cast<AActor>(Obj))
{
return FString::Printf(TEXT("[%s][Net:%s][Role:%s]"),
*Actor->GetName(),
*GetNetModeString(Actor),
*GetRoleString(Actor));
}
if (const UActorComponent* Comp = Cast<UActorComponent>(Obj))
{
const AActor* Owner = Comp->GetOwner();
return FString::Printf(TEXT("[%s O:%s][Net:%s][Role:%s]"),
*Comp->GetName(),
Owner ? *Owner->GetName() : TEXT("None"),
*GetNetModeString(Comp),
Owner ? *GetRoleString(Owner) : TEXT("NoOwner"));
}
return FString::Printf(TEXT("[%s][Net:%s]"),
*Obj->GetName(),
*GetNetModeString(Obj));
}
}``` lmfao
UE_LOG_DOMFMT(LogBlah, Log, this, "FiredShot: {ShotIndex}", ShotIndex);
got teamviewer ye give me a min implementing the debug stuff u sent me
Sent on dms
[BP_ProjectileBase_C_0][Net:DED][Role:L:Auth R:Sim] [Begin Play Projectile] World=LobbyMap NetMode=1 Auth=1 LocalRole=3 RemoteRole=1 Name=BP_ProjectileBase_C_0
[2026.01.04-15.18.06:382][676]LogTemp: Warning: [GA_Shoot2_C_0][Net:DED] Shot Fired
[2026.01.04-15.18.06:382][676]LogTemp: Warning: [InitFromShotData] BP_ProjectileBase_C_0 NetMode=1 HasAuth=1 Role=3 ShotId=1 SkipOwner=1
[2026.01.04-15.18.07:269][781]LogTemp: Warning: [BP_ProjectileBase_C_0][Net:CLI][Role:L:Sim R:Auth] OnProjectileHit ENTER Other=BP_PlayerCharacter_C_0 WorldNetMode=3 HasAuth=0 LRole=1 RRole=3
Funny stuff ig
There was a couple things he found to fix but the main issue that I would never have figured out was Movement Comp had an option ticked "Update only if rendered" and since dedi server doesn't render it then it was never moving
which is why component hit was detecting only client bolts and never server bolts
I had never even considered that, neat
Yea I dont think I would ever get there alone 💀
Does anyone know how much lag compensation FPS games tend to give?
I'm guessing a lot
Thats not really a question you can answer directly. Depends a lot on your game and what your tolerance for the tradeoffs is.
it can vary wildly but some fps games give you detailed stats
super situational... some games give you warnings when they force things to be delayed in the corner of the screen
for exampe battlefield games are pretty nice about that
In this 2011 GDC session, Bungie's David Aldridge discusses the programming that drove Halo: Reach's online networking.
Register for GDC: http://ubm.io/2gk5KTU
Join the GDC mailing list: http://www.gdconf.com/subscribe
Follow GDC on Twitter: https://twitter.com/Official_GDC
GDC talks cover a range of developmental topics including game des...
This is an older talk, but a good one.
I vaugely remember Dice doing one to, but cant remember what it was.
Yea I guess for FPS it makes more sense to have a much greater lag ocmpensation
up to a certain point ofc
since you kinda want pin point accuracy / instant feedback on it otherwise game feels bad + people die in 1-2 hits
I'm doing more of a melee game with bows and crossbows and stuff so I'm also thinking of adding some lag compensation so people don't get as often hits from local prediction that aren't actually dealing damage
Again, it depends on your game. A Coop game where you play against AI enemies you probably wont bother with lag compensation, because its not that importnat.
yea of course, but since I'm doing one with pvp involved I'm thinking of adding some
Average player ping should be between 50-80 so thinking of adding a cap on lag compensation up to 50ms
Yes, if its PVP then you will want it.
But even then, depending on what restrictions on regions and other factors will determine how aggressive it is.
There are many tradeoffs you have to make
Lag compensation isnt something you just add and it magically makes your game amazing.
One thing I haven't tackled yet but
I assume you don't BUT, do you also do local prediction for things like death? I assume not right? Of course damage is always validated on server, I'm just thinking how weird it would look if you shot someone and he only dies after 100-200 ms based on ur ping
Ideally, you predict as few things as you can get away with to make the game feel snappy and responsive.
A good place to start is anything that the Player has control over.
Like inputs that result in an action
Death is a consequence of actions, not the an action itself.
So you killing someone else, that death would not be something you would try and predict.
Watch that video I posted.
It literally covers prediction on death (from memory, i could be wrong).
For a specific case
But the insights are useful for considering.
As the final solution might surprise you.
Will do thanks!
It's not weird. Thats quiet common actually. Think about how many fps game where you die after hiding behind a wall?
On the other hand, I don't know anyone that predicted death. It do be weird to raise up from the dead when you don't actually die.
This is one of those tradeoffs you have to consider. Can you afford the visual inconsistencies of having to rollback a mis-prediction.
Especially in this usecase.
Enemy takes damage, you consider them dead, they start their death sequence, but the Server rejects that killing blow.
All of a sudden they pop back up and run away or worse, you die as a consequence.
100ms is a blink of an eye too, most people wouldnt even notice a player died 100ms after their bullet hit instead of instantly except for certain situations
in CharacterMovementComponent, it's not a must to include flags in CompressedFlag right?
8 bits isn't enough for my use case.
Since they swapped to the container data, you don't need to use that and can add your own
is it true if you want a game / round timer, it's better to replicate when did the timer start as opposed to everytime the timer changes?
If you can get away with just the time it started (and the client knows the duration)
or just replicating the time at which the round is assumed to end
i have previously mentioned i've made a bullet subsystem with the help of some advice from some peeps in here and im curious if when doing machine gun (automatic) logic, would it make sense to add this to my subsystem and handle the starting and stopping of the bullets?
in theory id add a new function with similar inputs but add a bool to start and stop the bullets from firing
I wouldn't personally make input the responsibility of the subsystem. Subsystem's job is data management. It allows registers and internally handles it's stuff from there.
Gun or the ability acting as the gun should be able to register each bullet same as it'd normally spawn one as an actor.
yea i do feel you on that, i thoguht about it more after writing that and did not want to adapt the subsystem at all, as it does it's job and that would complicate it for me
i am just using a timer by event and using a counter for how many bullets are fired (firing a bullet from the subsystem each time) and then updating ammo upon start/stop of firing, but updating client fake ammo amount in a local timer doing same thing, but this gets overriden after firing stops
thinking of a way to only do vfx/sfx at certian points for higher rate of fire guns, but not sure best method. coul djust use concurrecy for audio and maybe effect types for burst / flash / hit vfx?
--
I have a replicated float on my player state. It is replicated using RepNotify. The rep notify is hooked up to an event dispatcher. I am using a listen server model.
I wish to bind to the event dispatcher on my character BP on the local client, including if this is the host, but I'm not sure where in order to account for both clients and the host. Player State is not valid on begin play for clients - Possessed only gets called by the server. Restart sometimes doesn't match the timing. This needs to happen on simulated proxies as well.
What is the appropriate place to do this in blueprints? I don't want to use a polling method, which is how I have solved the issue in the past.
Pls @ me
I don't think this is possible within blueprints alone. There is an OnRep_PlayerState() which is not exposed to blueprints in the PlayerController. When you receive that OnRep on the owning player, you'd be able to properly get reference to the playerstate and bind to its onreps.
PlayerState is created with the PlayerController
So you can just handle this in the BeginPlay of your PlayerState subclass
There's a client version of the possessed event.
What you can do is use beginplay on both the character and the player state.
This wasn't working for me, I tried to set on the player from the playerstate but still had order issues
In both events, check if the other object exists and, if it does, do the thing.
thats a good idea, ill try that
yeah frankly 99% of networking issues where you have a or b are literally just a set of if statements called from 2 places lol... I think init states make it much nicer but ultimately it is the same thing
be aware though that just because something has begun play doesn't mean everything has actually set their cached pointer to it depending on the stack
for example calling GetPlayerState on something that doesn't set the playerstate until right after the PS begins play
It's never a great feeling but a one-frame delay is not the end of the world if there is not a nice override or event for something you know is set after IN THE SAME CALLSTACK every time
This is not yes or no answer, at the end of the day the system that you go for may need unique approach.
It's kinda easy to decide what to go with though.
If you just need to replicate the time once and let client simulate on their own (counting down them self) then you can just replicate it once.
If you need to have the time updated often due to things like the ability to increment or decrement the time by players then you can just have it as replicated and call it a day.
There are time when you want to sync the time too by accounting with the delay. You can achieve this by accounting the round trip time.
In general, the client timer is just for visual imo.
Event such as completed or restart time should be handled by server alone.
Think of simple day and night system. In most cases server just need to tell the client once on what time it is.
Client can then count down on their own when they get the time from the server.
Literally just use the game state's server world time seconds
Is there a way to disable movement prediction on the controlled character? The context is that I'm making a melee knockback based game and with prediction it's just impossible. I'd rather have everything delayed but in sync than simulated proxies lagging vs controlled character predicted
hello, i’m trying to stop the default behavior of the monster actor, but it’s not working for some reason. i want to disable its ticks and timers from another actor, without editing the main actor, and have this work on the server side only.
set actor not working
the playercontroller enables the tick in OnPossess
i can give a picture for the minotaur actor nodes if someone need to understand it but i dont want to edti it becasue that will make the mod client side and the players need to download it which is i dont want
unless you set start with tick enabled to false
you could probably just disable the tick after possession
i cant
well you right its enable the tick on possess i just test it now and remove the possess and the tick removed but still i need to possess
well you could set "start with tick enabled" to false and instead of disabling tick, enable it when you need it
wait i didnt try to test it sorry
that works, but not as expected. i only want to remove the attacking abilities, but doing this breaks the movement.
after that actor didnt move normaly
For TFastArrays, when you have arrays that are larger the maximum bunch size (65536) and new players join, how do you get past the array not getting properly initialized for clients?
This is what I’m using underneath now haha, I was building out a round timer and it works well
Did you know somthing to solve this ? idk coould i inject the character to the actor after disable the tick ?
You can have the type not replicate the delta, and send the bunch over multiple frames with an RPC, usually that just takes in a tagged buffer. Rebuild the array locally on the other side
Use NetMaxConstructedPartialBunchSizeBytes to subdivide the chunks into N RPCs
I just found this out lol.
I had to make my function take in a player state as a reference, because even after a 1 frame delay on begin play for the player state, it still wasn't set appropriately on the character.
So in the Player Character, I have
On Begin Play
On Restart
tied to InitializeFromPlayerState
and then in the Player State I call the InitializeFromPlayerState function, but pass in the player state itself. I then do some checks for the validity of the passed in pointer + the cached pointer on the character.
So annoying, definitely feel like it was a mistake to not just have OnRep_PlayerState be exposed to BP by default in the player controller
Doesn't lyra use delay till next tick and make it loop to get around that in bp
It's usually thrown around that if you're going to be making a multiplayer game, you're likely going to be delving into C++ to do it as there are many means of optimization and settings that aren't exposed to blueprint. Creating an event that gets called when that OnRep triggers is something relatively simple to dip your toes into making some C++.
I think perhaps an alternative would be to do something like this:
I get that, I'm not unfamiliar with C++ or anything, just looking for blueprint answers for this particular job
appreciate that!
Hi, the host player of a listen server wont experience any ping latency because they're the host but does that also mean they wont experience any packet loss either?
They won't experience it locally. But they could with packets coming from the client or sending to the client.
Would be weird otherwise
Yeah locally is what I meant, I'm having an issue with my interaction widget sometimes not being removed when it should but its only happening on the client, I can't seem to get it to happen on the server player at all and even when its on the client its only happening sometimes which leads me to believe its possible packet loss related maybe, no events to do with the interaction widgets being displayed/removed are marked as reliable atm
Also playing it in a packaged build not in the editor
Just a hobbyist here but sending client rpc to tell the client to remove or display widget sounds like a terrible design issue.
The data can be replicated. Showing or removing should be handled on each machine locally.
Your machine should show and remove what ever it knows on its world.
You don't want to have server say, hey player 2, remove your interaction widget.
Server simply set the replicated variable and client will eventually have the replicated value.
My interaction system is finished. I have 0 client rpc.
The only rpc is a server rpc from client requesting to interact with an entity.
Yeah so far mine is set up without using any RPC's as well, so when the player overlaps with an interactable actor it'll display a widget 'interaction indicator' to show that an actor can be interacted with and is then removed when the player ends the overlap with that actor so everything should be created, displayed and removed locally only
However i'm now getting this issue on the client only where it is able to keep the widget on-screen despite leaving the overlap and the 'remove indicator' function getting called
I can't see the image on my phone. If no one comes along maybe I will check it when I get home.
If you add and remove the widget on overlap, packet lost wouldn't matter
This was playing in a packaged build through steam so I am gonna try and see if I can get it to happen playing it in the editor as the client as well but so far its never happened when playing in editor as a client
why's that?
Cuz that will have nothing to do with networking
The machine just display widget when the overlap happend and remove it when the overlap ends
It doesnt talk to any other machine to execute those logic
@blazing spruce perhaps you have issue with widget not being removed when the server replicate the change?
Ans Not with the end overlap right?
My interaction component check for changes on tick.
If the data is no longer valid, and there's the widget. I simply remove it.
3 scenario to address.
- Show data when begin overlap.
- Update data when there are changes. E.g removed interaction data.
- Remove widget on end overlap.
Not sure what you mean cause none of the widget stuff itself is replicated? Although I think the issue might actually possibly stem from some of the workaround shit I had to do..
My widget fades in and out using an animation on the widget blueprint itself, but because of this it has this issue where if the widget is off-screen (but still there) and the player left the overlap without looking at the widget, it wouldn't actually play the fading out animation until the player turned back to where the actor was so its onscreen again and then it would fade out.. 'Tick When Offscreen' doesn't work because the widget is displayed in screen space and apparently that only works for world space widgets so to get around it I run a function that is supposed to detect whether the widget is onscreen at the time its told to be removed, if it is onscreen then it'll fade out playing the animation but if its not onscreen then the render opacity is just set to 0 straight away before being removed
I wanted to avoid using timelines to do the fading because they were causing me other problems and I also kinda wanted the widget blueprint to handle widget stuff and widgets cant use timelines and neither can components so I would have to use the components owning pawn/controller to do it which just seems stupid lol
Now, I think it might have something to do with this function I just mentioned because this issue is only happening when the widget is offscreen
Widget only exist locally, ofc you don't replicate that.
What you need to do is have the local machine update the widget when the state changes.
My locally controlled player interaction component just scans every tick. Get all the intractable components within interaction range.
If the data doesnt match with the UI. Update the UI.
@blazing spruce i have no issue playing fade out and fade in.
On overlap play animation forward.
On end overlap play animation reversed.
You might have to go through this with me when you're back at your computer if you don't mind 😂 I'm reading what you're saying its just not translating into how I would write that with my current set up, I can also show you the video of what was happening when I fade in/out the animation while its offscreen before I added the function to check if its offscreen - https://drive.google.com/file/d/1taYnwZEF77ELQNblhQMF-Zw9Sp7stihT/view?usp=sharing
In that video you'll see the widgets fade in and out just fine when im looking at them but when I enter, widget displays, I turn around so its offscreen, leave the overlap, then turn back around and you can see it fade out.. I then run through a load of door actors where the widget will be offscreen when its told to fade out and none of them actually do fade out until I turn back around to face them and then they all fade out all at once
I 'fixed' that by adding the function to detect if they're onscreen or not but I'll share screenshots properly when you can see them
I will do the same test when I got on the pc
Can you see the video already or do you need to be on PC to see it as well?
Okay good, yeah I wasn't sure either but apparently its because those animations don't play when they're called while the widget is offscreen until they're back onscreen again.. so at the start of the vid I'm looking straight at them and they behave correctly, but when I leave the overlaps while the widget is offscreen it wouldn't fade out until they came back onscreen
I would watch the functions all get called including the one to play the animation but it wouldn't actually play the animation until it was back onscreen, if I used the 'Play Animation with Finished Event' instead you would see the animation get called when leaving the overlap but the finished pin wouldn't fire until it was back onscreen and then it would fade out
what's the best way to travel between maps in multiplayer
i tried using both the console command 'servertravel' as well as the node and it always fails
How does it fail?
well it just kicks all players back to the main menu
Then you need to enable Seamless Travel on your GameMode.
Sorry I was never aware that existed lol, will repackage and check now
Please use #1054845120236757103 for feedback on projects.
Thank you Matthew, it all works now :)
Awesome
Any way to not have onrep be called on the server?
It was my intention this shouldn't happen, but blueprint defined RepNotify variables seem to call the OnRep function upon first loading or something like that
You'll have to gate it in BP, just branch on HasAuthority or IsServer depending on the context. Probably HasAuthority.
What are you actually doing where the server running the OnRep breaks it?
Incredibly, incredibly annoying lol yeesh
The value starts at 0, and then the server sets it to some non zero value, and when it gets back to zero I do some 'clean up' via the on rep function for clients.
But the clean up is happening right away on the server because onrep happens immediately with a value of zero, so the server is also getting this 'clean up' logic even though it was only meant for clients
What's the actual mechanic? What are you counting here
Sounds like you need an RPC...
Or better yet, to use C++ lol
counting through waypoints hit for racing-like system
does it actually matter? lol
this is fine for my purposes, everyone needs to know state, and the client is always synced positionally with server so the overlaps with the waypoint will happen just fine
Just do a client check, when cleaning up?
yeah, that's what I ended up doing, like I said I didn't know how onrep worked in BP
yeah I'm honestly not sure what a BP only project can do to get around this besides having each individual object's beginplay do a 1 framer delay to gather the infinity stones for the init flow
it's honestly hard to imagine not having the delegates for the playerstate being updated
Yeah I came to this conclusion that the initial data needs sending since its a large array. Is there a way to mark TFastArrays not to initially replicate on client join, and only when it's changed and marked as dirty?
There isn't
You would need to modify the delta serializer to do that
You can split it into multiple fast array properties, or otherwise, increase the bunch size
Any reading material on modifying the delta serializer?
no, just need to study it and basically make your own version of fast array
Separate question on TFastArrays. Is order guaranteed?