Skip to content

Custom effect magnitude calculations

Mass Forge magnitude calculations are reusable Primary Data Assets for project-owned damage, healing, scaling, and resource formulas. Each receives the fully resolved built-in magnitude before returning the final value. They extend normal Instant Effects and reversible Persistent Effect contributions without putting a UObject on each entity or changing the compact Mass fragments.

Blueprint setup

  1. Create a Blueprint derived from Mass Forge Effect Magnitude Calculation.
  2. Assign a durable, unique Calculation Id.
  3. Implement Calculate Magnitude and return a Mass Forge Effect Magnitude Calculation Response.
  4. Assign the asset to an Instant Effect modifier or Persistent Effect attribute modifier under Magnitude Calculation.
  5. Run Unreal Data Validation and Tools > Mass Forge Project Health.

The query contains the world context, complete read-only effect context, target attribute, zero-based modifier index, usage (Instant Modifier or Persistent Contribution), and Input Magnitude. The effect context includes source/target entity handles, optional represented Actors, source/effect/ability IDs, origin, optional hit data, scalar parameters, and any captured attributes.

Return Success only with a finite final Magnitude. Set a stable Reason for game UI, AI, analytics, and support. Mass Forge fills an omitted response Calculation Id from the asset. The native base class deliberately returns Invalid Configuration with NoCalculationImplementation, so an accidentally unimplemented asset fails closed.

For a data-only calculation, Mass Forge Linear Magnitude Calculation ships as a reusable example:

Output = Input Magnitude * Scale + Bias

Exact evaluation order

For each modifier, Mass Forge resolves values in this order:

  1. Authored base Magnitude.
  2. Optional named context parameter multiplied by Magnitude Parameter Scale.
  3. Optional source/target attribute multiplied by Magnitude Attribute Scale, using the authored capture policy.
  4. The assigned custom calculation receives that finite total as Input Magnitude.
  5. The returned finite magnitude is used by the modifier's Set/Add/Multiply or persistent Add/Multiply/Override operation.
  6. Schema clamping and the enclosing atomic transaction rules apply normally.

Every calculation in a transaction runs against committed pre-transaction entity state. Earlier staged modifiers are not visible through subsystem reads. This prevents authored ordering from exposing half-committed state.

Transaction and lifecycle guarantees

  • Direct and queued Instant Effects: calculations run during execution-time staging. If any calculation fails, no attribute or counted-tag change commits and the result identifies the failed modifier.
  • Abilities: calculations in self/target Instant Effects run inside the same transaction as costs, tags, cooldowns, charges, persistent effects, and lifecycle admission. Failure rolls the entire ability transaction back and reports the effect ID, modifier index, calculation ID, result, and reason.
  • Periodic effects: the referenced Instant Effect is executed normally at each earned pulse, so its calculations evaluate once per pulse using that pulse's context and capture policy.
  • Reversible Persistent Effect contributions: calculations run once when the incoming instance or replacement is staged. The finite output is snapshotted with that active handle, remains stable if the asset later changes in memory, and reverses exactly on removal/expiration.
  • Stack refresh/replace: the incoming definition is calculated before projected aggregate validation. A failed calculation cannot partially refresh, replace, cancel, grant tags, or alter attributes.

Failure handling

Branch first on the enclosing result:

  • Instant Effect: MagnitudeCalculationFailed in EMFAttributeAccessResult, then inspect FailedModifierIndex and MagnitudeCalculationResponse.
  • Persistent Effect: MagnitudeCalculationFailed in EMFPersistentEffectResult, then inspect the same nested diagnostics.
  • Ability: MagnitudeCalculationFailed in EMFAbilityResult, then inspect FailedEffectId, FailedModifierIndex, and the nested response.

Missing assets/IDs, the base class, intentional rejection, recursive evaluation, and non-finite output all fail without gameplay mutation. Do not retry in a tight loop; fix configuration or wait until the game rule represented by a deliberate rejection changes.

Performance boundary

Calculation assets are shared definitions, never per-entity state. They execute only on the direct/queued transaction path outside Mass processing. Keep Blueprint implementations bounded, deterministic, side-effect-free, and safe to evaluate repeatedly. Do not start effects, abilities, or other custom magnitude work from inside Calculate Magnitude; recursion is rejected.

The High Volume Effects Trait intentionally rejects modifiers with custom calculation assets. Its Mass processor hot loop accepts only finite, context-free, precompiled numeric operations and performs no asset loading, Blueprint dispatch, UObject work, allocation, or name lookup. Precompute high-volume values into explicit compiled effects when that path is required.

C++ implementation

Derive from UMF_EffectMagnitudeCalculation and override CalculateMagnitude_Implementation. Read Query.InputMagnitude and any immutable context needed, then return a finite response with a stable diagnostic. Use public, generation-checked subsystem reads for source/target state; do not retain query pointers or mutate gameplay.

The built-in UMF_LinearEffectMagnitudeCalculation is the smallest reference implementation. Use a distinct Primary Data Asset for each stable formula identity so Project Health can detect duplicate IDs and saved authored references remain traceable.

Mass Forge documentation — generated from the shipping Markdown source.