How to trigger the application of loose tags on an ASC from the client

I have a scenario where I am using loose tags to manage ability activation, but those loose tags are known only at runtime, and only on the client. The problem is that I do not know how to trigger the application of the tag on the server , from the client.

Example representative scenario

1. A laser that can lock on to objects in the world

2. Depending on the object the laser is locked on to, its color will be different - this is can only be known at runtime

3. The laser has 3 abilities:

- Turn on & lockon - can only do when the laser is off

- Turn off - can only do when the laser in on

- Pulse - can only do when the laser is green

Implementation

1. Laser is a `UActorComponent`, on a pawn that has an ASC component as well.

2. When the laser is locked on, the color & state of laser is tracked by loose Gameplay tag set on the ASC.:

- Laser_Green

- Laser_Red

- Laser_LockedOn

these tags are currently applied on client only via UAbilitySystemBlueprintLibrary::AddLooseGameplayTags() via the Laser component

3. Each ability is a UGameplayAbility

- GA_Laser_LockOn- blocked by `Laser_LockedOn` (set via ActivationBlocked Tags)

- GA_Laser_Off - requires `Laser_LockedOn` (set via ActivationRequired Tags)

- GA_Laser_Pulse - requires `Laser_Green` (set via ActivationRequired Tags)

4. The abilities call in to the laser component class , and it determines the state tags to apply

5. The laser component is not replicated (intentional, would like it to be this way), and thus the server does not have enough information to deduce the tag to apply on ability activation. This means I cannot apply the tag both on the server & the client separately.

My issue is that in a Server/Client setup, when I fire `GA_Laser_On` on the client, I cannot then fire `GA_Laser_Off`, because the server rejects the activation as `GA_Laser_Off` requires `Laser_LockedOn`, and that tag was never applied on the ASC on the server.

I have tried the following:

1. Use a gameplay effect to apply the tags via ApplyGameplayEffectSpecToSelf . This does not replicate the tags to the server

2. Use a server RPC on the laser component to add replicated tags on the server - a race condition will exist:

- client activates GA_Laser_LockOn

- RPC to add Laser_LockedOn tag goes out to server

- Server adds replicated Laser_LockedOn tag

- client receives addition of replicated Laser_LockedOn tag

- client activates GA_Laser_Off

- RPC to remove Laser_LockedOn tag goes out to server

- client instantly fires GA_Laser_LockOn

- client gets blocked because locally it still has the Laser_LockedOn tag

- client receives removal of replicated Laser_LockedOn

3. Lyra method of blocking GA_Weapon_Fire with Ability.Weapon.NoFiring, added on both server & client. Does not work because the tag is dynamic and not known on server.

Given this context, what is the best way that I can trigger the application of a tag from the client to the server, when the server cannot independently deduce which tag to add?

Steps to Reproduce
Please refer to description for an example of the problem.

Hi,

The first thought was to suggest applying with Gameplay Effect, which is what you’ve already tried.

Just to clarify, the Actor Component that’s applying this is not replicated, the laser component?

How about a Server function to apply the Gameplay Effects?

I’d generally avoid using Loose Tags where possible, it’s less painful to apply and remove via Gameplay Effects.

Are you trusting the client? If not, the server should be running the same logic as the client to determine what state the laser can be in. If you run the logic on the server then the tags will match, barring networking artifacts which would result in misprediction.

The server needs to do all of the above, then the client will automatically get the matching tags, for client prediction they both can do it separately. Otherwise the client will need to fire off a SERVER_rpc in order for the server to know what the client is doing. Though at that point you are trusting the client with all the power.

Regards