Hello. We support attribute value changes from dynamically constructed gameplay effects. Whether an attribute replicates or not, is defined in the UAttributeSet subclass, just like any other replicated property. It’s compatible with all ASC replication modes. GAS is compatible with push-model replication. For an attribute, whether it uses push model or not will be defined by its attribute set’s GetLifetimeReplicatedProps implementation.
First some sanity checks:
- Are the attributes you’re modifying marked as replicated?
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated)
FGameplayAttributeData ExampleAttribute;
ATTRIBUTE_ACCESSORS_BASIC(UMyAttributeSet, ExampleAttribute)
- What is that attribute set’s implementation of GetLifetimeReplicatedProps?
void UMyAttributeSet::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
FDoRepLifetimeParams Params;
Params.bIsPushBased = true;
DOREPLIFETIME_WITH_PARAMS_FAST(UMyAttributeSet, ExampleAttribute, Params);
}
- "Narrowed this down a bit. It’s related to having the replication mode set to full rather than minimal. " Are you seeing the correct result in full replication mode only, or on minimal only? And are we talking about autonomous proxies or simulated proxies?
With the above type of setup, any server-side change to “ExampleAttribute” in this case should replicate down to clients: both autonomous proxies and simulated proxies. However, with push model you must also ensure that the property is marked dirty on any change. In that SourceASC->ApplyGameplayEffectToTarget call, any modifiers applied by the ManagedEffect itself will mark the attribute dirty for push model networking. FGameplayAttribute::SetNumericValueChecked is the function that does that by calling MARK_PROPERTY_DIRTY.
You might want to double check whether the MARK_PROPERTY_DIRTY call in SetNumericValueChecked actually enters all the way into MarkPropertyDirty() in PushModel.cpp, like this callstack:
> UnrealEditor-NetCore.dll!UEPushModelPrivate::MarkPropertyDirty(const UObject * Object, const UEPushModelPrivate::FNetPushObjectId ObjectId, const int RepIndex) Line 469 C++
UnrealEditor-GameplayAbilities.dll!FGameplayAttribute::SetNumericValueChecked(float & NewValue, UAttributeSet * Dest) Line 100 C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::InternalUpdateNumericalAttribute(FGameplayAttribute Attribute, float NewValue, const FGameplayEffectModCallbackData * ModData, bool bFromRecursiveCall) Line 3897 C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::SetAttributeBaseValue(FGameplayAttribute Attribute, float NewBaseValue) Line 3985 C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::ApplyModToAttribute(const FGameplayAttribute & Attribute, TEnumAsByte<enum EGameplayModOp::Type> ModifierOp, float ModifierMagnitude, const FGameplayEffectModCallbackData * ModData) Line 4109 C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::InternalExecuteMod(FGameplayEffectSpec & Spec, FGameplayModifierEvaluatedData & ModEvalData) Line 4063 C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::ExecuteActiveEffectsFrom(FGameplayEffectSpec & Spec, FPredictionKey PredictionKey) Line 3205 C++
I’m not sure what you’re doing during the lifetime of that active GE. Are you modifying attributes and are those modifications not reflected on clients? Whenever an attribute changes value server-side, see if that actually triggers a call to FGameplayAttribute::SetNumericValueChecked.
Note: the value stored on the AttributeSet may be different, from the value calculated on the fly with FAggregators. Depending on how you’re using gameplay attributes:
- (a) The value on the attribute set that’s updated on applying a GE, or
- (b) Calculating attribute values on the fly via AttemptCalculateAttributeMagnitude
The (b) value calculated server-side vs. client-side might differ if any of its dependencies aren’t replicated over. Is that the type of issue you’re seeing?
Hopefully this provides some help debugging already.
By the way, if you’re not using Gameplay Debugger in PIE yet, please use it so that you can see whether the server and client at least agree on the replicated attribute value stored on the attribute set.
[Attachment Removed]