This document is about: QUANTUM 2
SWITCH TO

Entity Context

EntityContext is a special object holding cached references to entity components. This reduces the performance cost of accessing specific components multiple times in a single frame.

C#

foreach (EntityComponentPointerPair<AI> pair in frame.Unsafe.GetComponentBlockIterator<AI>())
{
    EntityRef entity = pair.Entity;
    if (frame.IsCulled(entity) == true)
        continue;
    if (frame.DestroyPending(entity) == true)
        continue;

    // Prepare EntityContext to currently iterated EntityRef
    frame.EntityContext.Set(frame, entity);
    
    pair.Component->Update(frame, entity);
    
    // Reset EntityContext, important to prevent garbage being stored
    frame.EntityContext.Reset();
}

Internally, pair.Component->Update(frame, entity) runs a state machine with the ability of executing many AI actions and decisions which often access entity components. Using EntityContext, a component lookup happens only once and the overhead for any subsequent lookup results in a single method call + bool check.

Following classes are used by gameplay HFSM logic and contain access to frame.EntityContext.AIMemory. Executing at least 2 of them in single frame results in optimized performance.

C#

public unsafe sealed class DamagedByEntityHFSMDecision : HFSMDecision
{
    public AIParamFP MinAmount = (FP)15;

    public override bool Decide(Frame frame, EntityRef entity)
    {
        AIMemoryRecord* damageRecord = frame.EntityContext.AIMemory->GetRecord(frame, EMemoryType.Damage);

        return damageRecord != null && damageRecord->Data.Damage->Amount > MinAmount.Resolve(frame, frame.EntityContext.AIBlackboard, frame.EntityContext.AIConfig);
    }
}

C#

public unsafe sealed class HasMemoryRecordHFSMDecision : HFSMDecision
{
    public EMemoryType MemoryType;

    public override bool Decide(Frame frame, EntityRef entity)
    {
        return frame.EntityContext.AIMemory->GetRecord(frame, MemoryType) != null;
    }
}

C#

public unsafe sealed class ClearMemoryAIAction : AIAction
{
    public EMemoryType MemoryType;

    public override void Update(Frame frame, EntityRef entity)
    {
        frame.EntityContext.AIMemory->RemoveRecords(frame, MemoryType);
    }
}
Back to top