Vixen
caa30e12
csharp
public sealed class AgentMemoryPool

Fixed-size blocks of per-agent state, carved out of pages and handed back on a free list.

Read the guide page for this →

Remarks

This is what makes "one asset, a thousand agents" cost one allocation each, at load. The asset — a behaviour-tree template, a utility set, a plan — is immutable and shared and has no per-agent field anywhere; everything that varies per agent is in a block here, and a node is handed a window into it. Unreal's behaviour-tree component holds the same TArray<uint8> for the same reason, and it is the correct design for an ECS engine rather than merely a workable one.

⚠ Pages, not one growable array, and the reason is a dangling span. A single arena that doubled would move every byte in it, quietly invalidating every Span`1 a caller was holding — which for a system that resolves a block and then ticks an action is a use-after-free with no symptom until it has one. A page is allocated once and never moves, so growth is a new page and every outstanding span stays valid.

The free list is per size. A thousand agents on one tree all want the same number of bytes, so a rental is a pop and a return is a push, with no search and no fragmentation to manage. A pool whose agents run twenty different templates holds twenty lists, which is twenty integers.

⚠ A returned block is zeroed on rental, not on return. Zeroing on return means paying for a block nobody rents again; zeroing on rental means an action's Start always sees a clean span, which is the guarantee IAgentAction makes.

Fields and properties (3)

  • public int BlockCount

    How many blocks have ever been carved, rented or not.

  • public int RentedCount

    How many blocks are rented out right now.

  • public long Capacity

    How many bytes the pool has allocated in total.

Methods (5)

  • public AgentMemoryPool(int pageSize = 65536)

    Creates a pool.

  • public AgentMemoryHandle Rent(int size)

    Takes a zeroed block.

  • public bool Return(AgentMemoryHandle handle)

    Gives a block back.

  • public bool TryResolve(AgentMemoryHandle handle, out Span<byte> state)

    The bytes a handle names.

  • public Span<byte> Resolve(AgentMemoryHandle handle)

    The bytes a handle names, or nothing.

Used by (10)

  • AgentMemoryPoolTestsVixen.Ai.Tests
  • AiSchedulingTestsVixen.Ai.Tests
  • AiSystemVixen.Ai
  • AiSystemTestsVixen.Ai.Tests
  • AiSystemTreeTestsVixen.Ai.Tests
  • BehaviorTreeCostTestsVixen.Ai.Tests
  • BehaviorTreeInstanceVixen.Ai
  • BehaviorTreeServiceTestsVixen.Ai.Tests
  • RunQueryNodeTestsVixen.Ai.Nodes.Tests
  • TreeHarnessVixen.Ai.Tests