Skip to content

High-volume compiled effects

Mass Forge's normal Instant Effect and Persistent Effect APIs prioritize flexible Data Assets, structured context, events, and detailed dynamic results. When one Mass processor must apply or remove the same simple effect across thousands of entities, use the opt-in Mass Forge High Volume Effects Trait instead. It compiles effect names and schema lookups once at Entity Config build time, then runs fixed-capacity numeric operations inside Mass entity iteration.

This path is C++-first by design. It does not load assets, allocate containers, perform FName lookup, call a world subsystem, or broadcast delegates in the entity loop.

Supported contract

Each trait supports up to four stable effect pairs. Every pair has:

  • an Effect ID used only during setup to resolve a numeric index;
  • an Apply Effect containing the forward attribute and counted-tag changes;
  • an explicit Remove Effect containing the inverse or cleanup changes.

Each side supports at most eight attribute operations and eight counted Gameplay Tag operations. Attribute operations may use finite constant Set, Add, or Multiply magnitudes. Context parameters, source/target attribute-backed magnitudes, and custom magnitude calculations are rejected because they require per-request contextual resolution or UObject/Blueprint dispatch. Use the normal Instant/Persistent Effect path for those features.

Removal is deliberately authored, not inferred. Negating Add is sometimes correct, but Set, Multiply, clamps, derived values, stacking, and intervening gameplay changes make automatic reversal ambiguous. The pair tells Mass Forge exactly what “remove” means for that project.

Entity Config setup

  1. Create and validate the normal Instant Effect assets for the Apply and Remove sides.
  2. Add Mass Forge Attributes Trait to the Entity Config.
  3. Add Mass Forge High Volume Effects Trait.
  4. Add one to four uniquely named effect pairs.
  5. If either side changes counted tags, also configure the Gameplay Tag behavior expected by the entity. The high-volume trait requires the compact tag fragment for that template.
  6. Resolve every compile or validation error before spawning the template.

The trait adds a 16-byte FMF_HighVolumeEffectCommandFragment per opted-in entity. Its compiled maximum-capacity table is FMF_HighVolumeEffectSetSharedFragment, stored once per matching archetype rather than once per entity.

Producer-processor workflow

Resolve the authored ID once outside the producer's entity loop:

cpp
const int32 DamageIndex = EffectSet.FindEffectIndex(TEXT("Crowd.Damage"));
if (DamageIndex == INDEX_NONE)
{
	return;
}

Inside the producer processor, submit by numeric index with a positive project-owned correlation ID:

cpp
const EMFHighVolumeEffectResult Admission = UE::MassForge::RequestHighVolumeEffect(
	CommandFragment,
	EffectSet,
	static_cast<uint8>(DamageIndex),
	EMFHighVolumeEffectOperation::Apply,
	CorrelationId);

Accepted means the built-in processor owns the command. It is not proof of application. One entity has one command/completion mailbox. Busy means the previous request is pending or its completion has not been consumed; do not overwrite it or spin.

After Mass Forge High Volume Effects Processor runs, consume the completion from a later ordered processor:

cpp
FMFHighVolumeEffectCompletion Completion;
if (UE::MassForge::ConsumeHighVolumeEffectCompletion(CommandFragment, Completion))
{
	// Completion.RequestId correlates the exact command.
	// Completion.Result is the terminal outcome.
}

Consuming resets the mailbox to Idle. Projects should order producer processors before UMF_HighVolumeEffectsProcessor and completion consumers after it. A command submitted after the built-in processor has run naturally waits for the next processing pass.

Atomicity and interaction with other systems

Every selected Apply or Remove side is projected completely before mutation. Missing slots, non-finite math, missing tag storage, tag capacity, count overflow, absent tags, and insufficient removal counts reject the command without partial attribute or tag changes. The completion identifies the failing operation index and preserves the nested Gameplay Tag result when applicable.

When an attribute currently has a Persistent Effect aggregate, the compiled operation updates the reversible base through the same persistent-attribute math used by normal mutations. Removing the persistent modifier later therefore does not discard the high-volume change.

The processor runs before Mass Forge's Derived Attributes processor in PrePhysics. Derived outputs are recalculated afterward; author high-volume operations against independent/base inputs when the value is supposed to survive derivation.

Events and presentation

The high-volume path intentionally emits no Blueprint or native per-entity delegates. A million event objects would defeat the purpose and could not be dispatched safely from worker processing. Use the completion mailbox for simulation coordination, or collect a bounded aggregate/presentation request in a later processor. Use the normal queued Instant/Persistent Effect API when individual gameplay events and full dynamic result arrays are required.

Choosing the correct path

NeedUse
One flexible effect with context, source/target captures, or delegatesNormal Instant Effect API
Timed, periodic, stacking, dispellable, or handle-based statePersistent Effect API
Same bounded constant Apply/Remove pair over a large Mass populationHigh-volume compiled effect processor
Blueprint orchestration outside Mass processingDirect or queued Blueprint APIs

This path removes avoidable per-entity lookup and allocation work; it does not by itself prove a supported entity count. The separate benchmark gate still requires packaged 10k, 100k, and 1M measurements on documented hardware.

Mass Forge documentation — generated from the shipping Markdown source.