#multiplayer

1 messages · Page 284 of 1

thin stratus
#

If the slot is occupied, you should never ever even get to any AddItem and OnItemAdded calls?!

nocturne quail
#

I drop the slot in the area and it onDrop from the chracter a server RPC on this item to call OnServerItemAddedToInventory

thin stratus
#

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(..)

nocturne quail
thin stratus
#

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.

nocturne quail
#

thanks for pointing this out

thin stratus
#

I assume you can add items in two ways:

  1. Pick them up from the floor.
  2. 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.

nocturne quail
# thin stratus I assume you can add items in two ways: 1. Pick them up from the floor. 2. Via...

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

thin stratus
#

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.

nocturne quail
#

case 2 is reached if this item want only to be unequipped and dropped

thin stratus
#

But why does that happen in "OnServerItemAddedToInventory"?

nocturne quail
#

its temporary to make it at least work

thin stratus
#

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 ?

nocturne quail
#

from backpack to the equip slot if this is equipable

#

backpack, helmet, cloths, weapon not showing in backpack list

thin stratus
#

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.

nocturne quail
#

Yeah, I have that bEquipped just to replicated its state

#
void UEquippable::SetEquipped(bool bNewEquipped)
{
    bEquipped = bNewEquipped;
    OnRep_bEquipped();
    MarkDirtyForReplication();
}
thin stratus
#

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.

nocturne quail
thin stratus
#

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.

nocturne quail
thin stratus
#

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.

nocturne quail
thin stratus
#

Cause you ask the Server to drop and the Client then has to wait for that to actually get back to them?

nocturne quail
thin stratus
#

Then why not just call DropItem(ItemA) for it? Why does this happen inside a function that handles adding items?

nocturne quail
nocturne quail
strong junco
#

What is the proper way to teleport and rotate a player a short distance while being compliant with CMC ?

strong junco
#

yes

#

I'm doing it in a gameplay ability

thin stratus
#

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.

strong junco
#

it's initiated by a gameplay ability so it should be safe.

#

oki I'll check that

thin stratus
#

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.

strong junco
#

oh right

thin stratus
#

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.

nocturne quail
#

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

dark parcel
#

does it matter for client? I mean those function run within the same frame.

nocturne quail
#

maybe I need to try without checking for isvalid

nocturne quail
#

trying without isvalid will at least skip the grabage collector check

nocturne quail
# thin stratus If AddItem(ItemA) leads to DropItem(ItemA), then you should have called DropItem...

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

light obsidian
#

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

twin juniper
#

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

lost inlet
light obsidian
#

this vehicle thing is breaking my brain

light obsidian
#

tim sweeney certified hack

#

cant set input values despite the nice checkbox saying you should be able to

#

never change, unreal

twin juniper
#

I just know that problem is related to ping and that's it

light obsidian
#

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

nocturne quail
light obsidian
#

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

nocturne quail
# light obsidian 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

frosty harbor
#

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.

dark edge
#

becaues it's locally spawned

#

Are you trying to predict the hit locally or just the firing and let the hit do nothing?

nova wasp
#

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)

frosty harbor
nova wasp
frosty harbor
nova wasp
#

what would the remote role be from the actual server?

frosty harbor
nova wasp
#

Why not use the actual net mode of the world here?

frosty harbor
#

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

nova wasp
#

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

frosty harbor
nova wasp
#

the projectile spawning on the client does not change to a different world

frosty harbor
#

How do i check the net mode of the world

nova wasp
#

the server will always have the server netmode (listen/dedicated) and the client will always have NM_Client

frosty harbor
#

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

nova wasp
#

this node basically just asks if you AREN'T in NM_client

frosty harbor
#

The issue is that the server projectile doesn't have authority locally

#

so send gameplay event doenst work

nova wasp
#

local and remote authority are different things

#

remote authority is not local authority

dark edge
#

remote means "what's the status of this thing on the other side?"

frosty harbor
nova wasp
#

debug

#

use chaos visual debugger

#

record state

#

scrub through (it will show all worlds at the same time)

dark edge
#

does it cover all the stuff like movement components or just tick setting position?

nova wasp
#

it's a bit tedious to make it render meshes but you only need simple collision here in most cases

nova wasp
#

it is not just a list of scene queries... it records every particle's state and every query and every hit result

dark edge
#

thats nuckin futs

nova wasp
#

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

frosty harbor
#

💀 I have no clue how to use this

nova wasp
#

great news, there is documentation

frosty harbor
#

I've been fighting over making this projectile stuff work on server but shit is not cooking

nova wasp
#

all you need to do is click this, shoot a projectile, then click it again to stop

frosty harbor
#

I did that yea but dont see anything other than the normal logs

nova wasp
#

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

frosty harbor
#

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)

nova wasp
#

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...

frosty harbor
nova wasp
#

hit this, also just in case make sure you enable scene queries and evolutionstart etc

frosty harbor
nova wasp
#

did you hit "record live session" and then simulate some game frames by playing?

#

also not sure what version you are actually on

frosty harbor
#

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 >.<

dark parcel
#

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.

winged badger
#

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

dark parcel
fossil spoke
dark parcel
# fossil spoke 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.

dark parcel
#

I dont have testers yet and interpolating is still in my to do list so I can't see any result yet.

winged badger
#

you definitely do not need 2 projectile actors

fossil spoke
#

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

nocturne quail
dark parcel
lament flax
#

depends

#

if its an instant shot or not

nocturne quail
lament flax
#

if not (the most annoying one to answer) you would use niagara or pooled ISM for the visual part

nocturne quail
#

they can have velocity, drops, speed, damage etc

nova wasp
nocturne quail
#

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

nova wasp
#

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)

lusty timber
nova wasp
#

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

frosty harbor
dark parcel
#

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.

frosty harbor
dark parcel
#

Whos checking?

#

In the client, that server projectile. That client will not have authority.

In server, the server will have the auth.

nova wasp
#

generally people are going to assume you mean local authority 99% of the time when you don't specify

frosty harbor
nova wasp
#

breakpoint it

#

show callstack

frosty harbor
#

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

dark parcel
#

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.

nova wasp
dark parcel
#

If the overlap code run on me, authority will print.

If the overlap code run on your computer, remote will print.

nova wasp
#

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)

real ridge
#

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

frosty harbor
#

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

nova wasp
#

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

nova wasp
#

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

frosty harbor
#

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

dark parcel
#

If the actor meant to be in sync, don't use multicast.

#

Set to replicate and let sever spawn. Everyone will get a copy.

spark radish
#

that can cause serious desync and choppiness if you aren't handling speed changes properly

frosty harbor
dark parcel
#

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.

frosty harbor
# dark parcel Not via game play event.

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

dark parcel
#

By default its the player controller and character.

#

Maybe player state from what I recall.

frosty harbor
#

yea that was what was causing the issue

dark parcel
#

Calling rpc on non owned object will not reach the server and you should see warning on the logs.

frosty harbor
dark parcel
#

@frosty harbor not sure why u are sending tag here though.

frosty harbor
#

maybe if i did it in c++

dark parcel
#

You pretty much let the client have a say in dealing damage.

Without verification they can just kill anyone they want ( cheat )

dark parcel
#

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.

frosty harbor
dark parcel
#

I never use that node

#

Always the switch has authority one

frosty harbor
#

but local projectile has authority though

#

and server one doesn't

dark parcel
#

Right

#

Well that local projectile only exist in that firing client alone.

frosty harbor
#

is this what ur saying is what I should be doing?

dark parcel
#

Not really, I forgot you have to handle the version on the client. My bad

frosty harbor
#

Yea

dark parcel
#

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.

frosty harbor
#

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

dark parcel
#

Depends on what your apply ranged damage does

frosty harbor
dark parcel
#

If it doesn't do any check whatsoever then yea client can just say hey I hit this person with 9999 damage.

frosty harbor
#

But i'm gonna switch this to apply the gameplay effect directly probably

dark parcel
#

Hmm but it shouldn't be an rpc in theory

frosty harbor
#

without it being an rpc it's being sent by the owning client so it doens't have server authority >.<

dark parcel
#

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.

frosty harbor
# dark parcel So you want the client to have a say?

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

dark parcel
#

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.

frosty harbor
#

It does but "On Component Hit" is always returning otherwise

dark parcel
frosty harbor
#

It says client has authority and server projectile doesn't

dark parcel
#

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.

frosty harbor
#

I know, its hard to explain but like the On Component Hit event simply never has the server authority

dark parcel
#

You most likely observe the wrong instance

#

I never have that issue on my end

#

Hit and overlap work as intended.

frosty harbor
#

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

dark parcel
#

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.

frosty harbor
#

send me please 🙂

dark parcel
#

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

cobalt inlet
#

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

dark parcel
#

@cobalt inlet there is set owner node

#

But the server must be the one executing it

cobalt inlet
#

so do something like this? Server = Owner no see Client = Owner see?

#

for FPS arms for example

dark parcel
#

I'm just pointing at the node to set the owner of an actor

cobalt inlet
#

oh

dark parcel
#

You can play around with the bool. I don't use them my self.

cobalt inlet
#

set owner has a bool? I think I am using the wrong set owner?

#

Oh the no see part

dark parcel
#

Set the owner first. Say you spawn FPweapon for player 3. Make player 3 the owner of the weapon via set owner mode.

cobalt inlet
#

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

cobalt inlet
dark parcel
#

Gtg , share your code and setup here for others to see.

frosty harbor
# dark parcel Normally you would send a target data.

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 >.<

dark parcel
# frosty harbor Got the wait target data working properly but yea still have same issue, On Comp...

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.

frosty harbor
#

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

frosty harbor
#

And for the local prediction projectile it returns authority

dark parcel
#

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.

nocturne quail
#

show code, how you are logging it

frosty harbor
#

I'm just doing get local role

nocturne quail
#

the component is a bullet? and it is fired on server?

frosty harbor
#

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)

nocturne quail
#

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?

frosty harbor
#

client 1 only saw the simulated proxy bolt

#

(which is the server bolt)

nocturne quail
#

show code how you are spawning bullet

frosty harbor
cobalt inlet
nocturne quail
# frosty harbor

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

frosty harbor
frosty harbor
#

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)

nocturne quail
#

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

frosty harbor
#

everythings off besides the actor

#

the others are all off

#

forgot to turn off the always relevant but yea

nocturne quail
#

maybe check the shooter game weapon class, they are doing similiar things as you and their system works fine

frosty harbor
#

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);
    }

}
nocturne quail
#

Init Data replication should not be the issue, since its a struct and support replication

frosty harbor
#

🤔 then got no clue

nocturne quail
#

and than instant hit locally

frosty harbor
#

i mean if I play as listen server then its always authority

nocturne quail
#

you can use a replicated int as a bullet counter

nocturne quail
#

the second client will be client

frosty harbor
nocturne quail
#

I'm not sure if they updated it, I checked it once long time ago in ue4

frosty harbor
#

dont have it in the ue5 projects

nocturne quail
#

its on the github

frosty harbor
#

I dont see it

meager spade
#

its not on the github (shooter game)

#

epic launcher has a way to getit

frosty harbor
#

the game samples I see is only lyra starter game

#

is that the one?

#

dunno if they have locally predicted shooting in that one

meager spade
#

they do

#

in lyra

covert marten
#

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.

nova wasp
covert marten
nova wasp
#

Let me see... You should be able to ask the replication system about the internal index to net ref handle

covert marten
frosty harbor
#

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?

sinful tree
frosty harbor
#

yea figured it out ty

nova wasp
#

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)

frosty harbor
#

Lyra seems to be hitscan though no?

#

Not with travel time / on hit component / on component overlap

nova wasp
#

@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

meager spade
#

whats not exported?

nova wasp
#

nothing in the NetRefHandleManager is exported at all

meager spade
#

let me see what i did

nova wasp
#

I'm sure I missed something here

meager spade
#

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);
            }```
nova wasp
#

we are starting with ONLY an internal index

meager spade
#

oh

#

whats it for ?

#

this is how i filtered actors for certain connections though

nova wasp
#

yes, you can manually modify groups from user code

#

that might be easier than using filters as intended

meager spade
#

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

nova wasp
#

those are all FInternalNetRefIndex

#

look at what actually calls that

#

so yeah doing stuff like AddInclusionFilterGroup and others externally will be much easier

frosty harbor
#

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

meager spade
#

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

frosty harbor
#

Yea I mean I can do that its not the problem

#

The problem is why cant the On Component Hit detect server projectiles >.<

meager spade
#

🤷

nova wasp
#

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

frosty harbor
# nova wasp and my advice from earlier still stands: just see what the state of the actor is...

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

nova wasp
#

look at what this actually does please

#

double click on it

frosty harbor
#

it checks if the author has authority

nova wasp
#

the owner of this graph, yeah

meager spade
#

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

frosty harbor
#

I know that

#

But I can't get the hit results of the server projectile properly is the issue

meager spade
#

so you want IsServer check here to ensure only server runs that code

frosty harbor
#

like I know the locally predicted projecitle has authority in its own instance

frosty harbor
meager spade
#

then your server projectile is not hitting where you think it is

#

so nothing triggers

nova wasp
#

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?

meager spade
#

i am thinking his projectile is never colliding

#

which makes me think its not where he thinks it is

nova wasp
#

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

meager spade
#

i have seen people do dedi server stuff and forget that skeletal mesh positions are not the same on server

frosty harbor
#

and going where i point it to

meager spade
#

so they fire the gun from the same spot, and its miles off

nova wasp
#

is this a listen server or a dedicated server

meager spade
#

right, there is no reason server wont overlap/collide with stuff where client does

#

unless you never turned on collisions on the projectile

nova wasp
#

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

meager spade
#

(server side)

frosty harbor
#

Its just the default ue5 editor server dunno which mode it uses, I'm playing as client to emulate a normal player behavior

meager spade
#

thats dedi server

nova wasp
#

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

nova wasp
meager spade
#

when i make systems (especially if im going to do prediction)

#

i always validate it works before doing prediction stuff

nova wasp
meager spade
#

ie i will just spawn the server only projectile

#

and not even fire a client side projectile

#

running before walking

frosty harbor
meager spade
#

its not p2p

nova wasp
#

no...

meager spade
#

common misconception 😛

nova wasp
#

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

meager spade
#

i honestly think you should just fire the server projectile (remove the client side projectile)

#

and do some debugging

meager spade
#

without seeing your code, setup, etc

#

we can't really help

#

like we don't know how your projectile is setup

nova wasp
#

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

meager spade
#

record a video of it? breakpoint in the projectile code if you have c++ (ProjectileMovementComponent)

nova wasp
#

I would STRONGLY suggest not using a dedicated server setup if you don't need to

meager spade
#

unless you plan to host dedi servers for your game, most indie games will be listen server

frosty harbor
nova wasp
#

it requires a lot more work and consideration just to make it possible for players to use it or connect to it

meager spade
#

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

nova wasp
#

the idea of "an item" and "what you show in your hands" are two completely different problems generally

meager spade
#

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

nova wasp
#

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

meager spade
#

i use seperate actor for weapons :/

nova wasp
#

as long as you don't have like, the internal weapon state coming in at a weird time it's fine

meager spade
#

the weapon actor does all the timing/state stuff

nova wasp
#

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

meager spade
#

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

nova wasp
#

as long as the replicated state comes in in a way that makes sure it doesn't constantly race condition that's maybe fine

meager spade
#

like you can add attachments, adjust weapons, change everything so easily all with "Weapon Modification" data asset

nova wasp
#

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)

meager spade
#

yeah i mean for replicating the weapon replicates when the owning actor replicates

#

never on its own (this was with repgraph though)

nova wasp
#

and ideally is filtered underneath them etc

#

so it will effectively be a replicating component more or less

meager spade
#

not done/tried this with Iris yet

nova wasp
#

Iris can make dependencies too

meager spade
#

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

nova wasp
#

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

meager spade
#

yeah or we have TeamInfo actors for team related stuff (just cause those are global team stuff)

nova wasp
#

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")

meager spade
#

but we have private/public team info actors (similar to what lyra did but they never actually implemented the private one..)

nova wasp
#

that's a good idea

meager spade
#

though i have the ASC on the playerstate for players

nova wasp
#

separate private actor can replicate only to one team which is smart

meager spade
#

but this is crucial cause some stuff is "player wide" not "pawn specific"

nova wasp
#

ASC on playerstate is fine... it would be on a separate object anyways from the movement comp

meager spade
#

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

nova wasp
#

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)

meager spade
#

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

nova wasp
#

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

meager spade
#

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

nova wasp
#

init states are insanely useful for networking

#

but I think the implementation is a bit confusing

meager spade
#

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

nova wasp
#

yeah generally speaking it's easier if one place directs the check instead of mutually waiting

#

you just want a chain of if statements

meager spade
#

i think that framework could be a bit easier to grasp

#

or simplified

#

but i hardly ever use UActorComponent directly anymore

nova wasp
#

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

meager spade
#

its all mainly UGameframeworkComponent

nova wasp
#

the way replacing components works is super confusing

#

also it not adding them as instanced components is just dreadful in the editor lol

meager spade
#

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

nova wasp
#

It's fine to not have it on everything

#

90% of actor components in your game are not init states

#

they are scene components

meager spade
#

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

frosty harbor
meager spade
#

@frosty harbor hmm

#

what spawn actor node

#

you using?

#

the default engine one?

#

yeah you are hmm

frosty harbor
#

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

meager spade
#

i think i see an issue

#

this property

#

when is it set

#

cause i feel this is off

nova wasp
#

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)

meager spade
#

cause your doing this

#

but dedi servers dont update bones

#

so this will be off

nova wasp
#

also that weapon get can silently fail 🙁

frosty harbor
#

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();

}

meager spade
#

yes exactly!

#

right for quick debug

#

but dont keep this on

frosty harbor
#

gotcha ill remove that

meager spade
#

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

frosty harbor
#

yea I had that on already

#

on the player character right?

nova wasp
#

which skeleton is this from?

meager spade
#

you sure its on?

#

CombatMesh should have it on

frosty harbor
meager spade
#

whatever that is

nova wasp
#

also the dedicated must have the anim instance you expect as well

#

if you set that dynamically

meager spade
#

you know

#

theres a much easier way to do this

#

is for your client to tell the server its loc

frosty harbor
nova wasp
#

which avoids the insanely complicated problem of praying the character is where they are on both sides

frosty harbor
nova wasp
#

the RPC that activates the ability

meager spade
#

well your passing this

#

which is fine

nova wasp
#

passes this info in

#

get this info on the other side, use it to spawn stuff

meager spade
#

but you should also be passing the other loc

#

instead of this, you send this to the server

frosty harbor
#

oh i see

meager spade
#

but you would probably need to make your own targeting class to send extra data

#

or use a server rpc

frosty harbor
#

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

nova wasp
#

when I say debug I think I mean actually using a breakpoint to see the current state or using dedicated visualizing tools

meager spade
#

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?

nova wasp
#

is that async tracing or waiting on a net sync?

meager spade
#

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

frosty harbor
meager spade
#

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); }

frosty harbor
#

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

meager spade
#

i didnt even see it in that video

#

the projectile

frosty harbor
#

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

meager spade
#

yeah but why doesnt local client see it?

#

shoukld have disabled that

#

so you can actually see it

frosty harbor
#

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

frosty harbor
meager spade
#

i mean

#

lyra is a bit complicated

#

cause it does hitscan, etc

#

you can really simplify it

nova wasp
#

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

meager spade
#

iirc this one takes in target data

#

ah wait

#

yeah this never got finished

#

to support spanwing an actor predicted

#

ignore :p

frosty harbor
#

Shouldn't be too hard to add in

meager spade
#

im seeing if i have a cut down example

#

somewhere

hollow breach
#

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

nova wasp
#

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

hollow breach
#

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

nova wasp
#

you did not include if the target was replicating in your original description

hollow breach
#

Yeah my bad, it is

nova wasp
#

"only receiving the Character and Location variables properly" is two things

meager spade
#

@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

nova wasp
#

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?)

hollow breach
#

The only thing appearing on other side is Character and Location vars

nova wasp
#

this node converts a boolean and an integer? I did not even know you could do this... does this print twice?

nova wasp
#

I am asking what the value is

#

a boolean can be either true or false

meager spade
#

i see a bad mix of replicated vars and multicast here

hollow breach
#

gfd

#

Someone added these to all the children

nova wasp
#

oh, oof

meager spade
#

this is why i always make seperate things

#

cause you cant trust bp users

#

i make explicit overridable stuff

hollow breach
#

plz esplain

meager spade
#

its a bit hard on BP only projects

nova wasp
#

yeah I'm not sure if you can enforce this in any way in a bp event

#

can it just be non-public?

meager spade
#

possible, but C++ makes this trivial

#

though i hate BP Native Events

nova wasp
#

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)

meager spade
#

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

hollow breach
#

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

quasi tide
#

Huh?

dark parcel
nocturne quail
#

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;
}
gentle mauve
#

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?

dark parcel
#

do what ever you need to do, then call Super

covert marten
# nova wasp nothing in the `NetRefHandleManager` is exported at all

@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!

nova wasp
#

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

covert marten
thin stratus
#

@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.

covert marten
#

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.

thin stratus
#

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.

nova wasp
#

they access things to get net ref handles from the internal object index all of the time

thin stratus
nova wasp
#

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

thin stratus
#

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".

nova wasp
#

the way Epic handles it is entirely inside of a bridge that is not going to be replaced by user code ever

thin stratus
#

Yeah, when I looked at it I felt like it's missing some form of user-code hook for this stuff.

nova wasp
#

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)

thin stratus
#

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.

nova wasp
#

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

thin stratus
#

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.

nova wasp
#

yeah... I'm more familiar with the client part of iris more so than the filtering/prio parts

thin stratus
#
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.
nova wasp
#

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

thin stratus
#

That's 5.7 Iris docs :<

#

The Group one isn't even correct.

nova wasp
#

no Replay conditions 😔

thin stratus
#

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.

nova wasp
#

FReplicationConditionals::GetLifetimeConditionals is one nice place all flags get set

thin stratus
#

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 Level

An 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.

nova wasp
#

so you would need a unique group for almost every team... that's probably fine

thin stratus
#

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.

nova wasp
#

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

thin stratus
#

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.

nova wasp
#

yeah this is kind of where Iris starts to actually matter

thin stratus
#

And with "random" I mean actually random.

nova wasp
#

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

thin stratus
#

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.

nova wasp
#

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

thin stratus
#

Yeah, it's a bit of a different story here as it wasn't about relevancy bugs.

nova wasp
#

yeah, just me bitching about relevancy lol

thin stratus
#

There are some config variables for how much time has to pass between 2 relevancy changes, before UE even accepts the next one.

nova wasp
#

I can kind of see why because flip/flopping would be expensive

thin stratus
#

And that makes sense in general, and battles actors that are right on the edge.

nova wasp
#

but that is frustrating

thin stratus
#

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.

nocturne quail
#

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

thin stratus
#

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.

nocturne quail
#

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);
        }
    }
thin stratus
#

If you can't use Mutable, cause you aren't using UE5 (...), then you will probably have to continue creating a SkelMeshComp per Asset.

frosty harbor
# meager spade ```cpp /** * */ UCLASS(Abstract) class SHOOTERGAME_API UMyProjectileFiringAbi...

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

nova wasp
#

use GetDebugStringForWorld

#

that way it has a nice client/server/listen server string for these

meager spade
#

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);
frosty harbor
frosty harbor
frosty harbor
#

[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

frosty harbor
#

Kaos is the goat

#

❤️

nova wasp
#

you figured it out? nice

#

I'm curious what the fix was

frosty harbor
# nova wasp I'm curious what the fix was

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

nova wasp
#

I had never even considered that, neat

frosty harbor
#

Yea I dont think I would ever get there alone 💀

frosty harbor
#

Does anyone know how much lag compensation FPS games tend to give?

#

I'm guessing a lot

fossil spoke
#

Thats not really a question you can answer directly. Depends a lot on your game and what your tolerance for the tradeoffs is.

nova wasp
#

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

fossil spoke
#

This is an older talk, but a good one.

#

I vaugely remember Dice doing one to, but cant remember what it was.

frosty harbor
#

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

fossil spoke
#

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.

frosty harbor
#

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

fossil spoke
#

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.

frosty harbor
#

thats true actually

#

Might need to rethink that

fossil spoke
#

There are many tradeoffs you have to make

#

Lag compensation isnt something you just add and it magically makes your game amazing.

frosty harbor
#

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

fossil spoke
#

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.

frosty harbor
#

Will do thanks!

dark parcel
#

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.

fossil spoke
#

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.

tardy fossil
#

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

dark parcel
#

in CharacterMovementComponent, it's not a must to include flags in CompressedFlag right?

#

8 bits isn't enough for my use case.

thin stratus
bitter veldt
#

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?

verbal ice
#

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

crisp shard
#

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

kindred widget
crisp shard
#

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?

gritty warren
#

--

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

sinful tree
verbal ice
#

PlayerState is created with the PlayerController

#

So you can just handle this in the BeginPlay of your PlayerState subclass

latent heart
#

There's a client version of the possessed event.

#

What you can do is use beginplay on both the character and the player state.

gritty warren
latent heart
#

In both events, check if the other object exists and, if it does, do the thing.

gritty warren
nova wasp
#

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

dark parcel
# bitter veldt is it true if you want a game / round timer, it's better to replicate when did t...

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.

verbal ice
#

Literally just use the game state's server world time seconds

robust linden
#

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

harsh stag
#

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

tardy fossil
#

the playercontroller enables the tick in OnPossess

harsh stag
#

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

tardy fossil
#

unless you set start with tick enabled to false

#

you could probably just disable the tick after possession

harsh stag
tardy fossil
#

well you could set "start with tick enabled" to false and instead of disabling tick, enable it when you need it

harsh stag
harsh stag
#

after that actor didnt move normaly

pallid stone
#

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?

bitter veldt
harsh stag
haughty ingot
#

Use NetMaxConstructedPartialBunchSizeBytes to subdivide the chunks into N RPCs

gritty warren
# nova wasp for example calling GetPlayerState on something that doesn't set the playerstate...

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

dark parcel
#

Doesn't lyra use delay till next tick and make it loop to get around that in bp

sinful tree
# gritty warren I just found this out lol. I had to make my function take in a player state as...

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:

gritty warren
#

appreciate that!

blazing spruce
#

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?

quasi tide
#

They won't experience it locally. But they could with packets coming from the client or sending to the client.

#

Would be weird otherwise

blazing spruce
#

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

dark parcel
#

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.

blazing spruce
#

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

dark parcel
#

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

blazing spruce
#

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

dark parcel
#

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.

dark parcel
#

3 scenario to address.

  1. Show data when begin overlap.
  2. Update data when there are changes. E.g removed interaction data.
  3. Remove widget on end overlap.
blazing spruce
# dark parcel <@605390088247050271> perhaps you have issue with widget not being removed when ...

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

dark parcel
#

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.

blazing spruce
# dark parcel My locally controlled player interaction component just scans every tick. Get al...

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

dark parcel
#

I will do the same test when I got on the pc

blazing spruce
#

Can you see the video already or do you need to be on PC to see it as well?

dark parcel
#

I see it yeah

#

Not sure why they all become visible at once and removed all at once

blazing spruce
# dark parcel Not sure why they all become visible at once and removed all at once

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

fast yoke
#

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

fossil spoke
#

How does it fail?

fast yoke
#

well it just kicks all players back to the main menu

fossil spoke
#

Then you need to enable Seamless Travel on your GameMode.

fast yoke
#

Sorry I was never aware that existed lol, will repackage and check now

fossil spoke
#

👍

#

You should never need to disable it.

fossil spoke
fast yoke
fossil spoke
gritty warren
#

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

fossil spoke
#

OnReps are always called by the Server in Blueprint

#

No way around that

#

AFAIK

dark edge
#

What are you actually doing where the server running the OnRep breaks it?

gritty warren
#

Incredibly, incredibly annoying lol yeesh

gritty warren
# dark edge What are you actually doing where the server running the OnRep breaks it?

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

dark edge
#

What's the actual mechanic? What are you counting here

fossil spoke
#

Or better yet, to use C++ lol

gritty warren
#

does it actually matter? lol

gritty warren
halcyon ore
gritty warren
nova wasp
#

it's honestly hard to imagine not having the delegates for the playerstate being updated

pallid stone
chrome bay
#

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

pallid stone
#

Any reading material on modifying the delta serializer?

chrome bay
#

no, just need to study it and basically make your own version of fast array

pallid stone