Recycle actors instead of spawning and destroying them, with an explicit acquire/release API and a documented path for replicated actors.
Free · Performance · Unreal Engine 5
Spawn it once. Reuse it all match.
Projectiles, impact effects, pickups and shell casings pay for a full SpawnActor and Destroy every single time. CrimsonObjectPool replaces that with a per-world subsystem that recycles actors by class: Acquire Actor hands you a live instance, Release Actor parks it for the next acquire. Replicated actors included.
Why CrimsonObjectPool
Pooling that stays predictable: explicit at every call site, correct over the network, and removable in one command.
Explicit, never implicit
The plugin never hooks engine spawn paths. An actor is pooled only where you asked for it to be, so there is no hidden behaviour to reason about when something goes wrong, and nothing changes for the rest of your project.
Replicated actors, done right
Parked actors go dormant rather than being hidden at a far-off location. A hidden, non-colliding or net-culled actor loses relevancy, and every client destroys its copy, which is the cost the pool exists to remove. Acquire and release are server-only for a replicating class.
Bulk spawns without the hitch
Request Actor Queued serves acquires across frames under a MaxSpawnsPerFrame budget (2 by default) and hands each one back through On Pooled Actor Ready. Requests a warm pool can fill from its free list skip the budget entirely; only real spawns are throttled.
Sizing you control per class
Default Capacity, growth policy (Grow or HardCap) and over-capacity behaviour are project-wide defaults; a Class Overrides entry can change any of them plus a prewarm count for one class. Override lookup walks up the class hierarchy, so one entry covers a whole family of projectiles.
Counters that prove it works
Crimson.ObjectPool.Dump prints pooled, live, high-water, created and spawns-avoided per class. If created keeps climbing, instances aren't being released, and you can see it in one command. A pool-pressure ratio also warns once per class when the live count reaches 90% of capacity.
Rule pooling out instantly
Crimson.ObjectPool.Bypass 1 turns every acquire into a real SpawnActor and every release into a real Destroy. Reproduce a bug with pooling off and you know immediately whether the pool is involved.
A closer look
Two node swaps and you're pooling
Replace Spawn Actor from Class with Acquire Actor, and Destroy Actor with Release Actor. That's the whole integration for a cosmetic actor: no interface, no subclass, no settings changes.
- You cannot tell whether an acquire recycled or spawned, and you don't need to
- Acquire Actor Deferred hands over a dormant instance to configure; Finish Acquiring Actor brings it in
The reuse contract
A pooled actor is never destroyed, so BeginPlay runs once per lifetime, not once per use. One-way latches stay latched and per-use delegate bindings multiply. The optional ICrimsonPoolable hooks let you control reactivation yourself.
ICrimsonPoolableships here; for a class you cannot edit, a C++ adapter supplies the same hooks- Write
On Released To Poolto stand the actor down even when released mid-use - A delayed release, a pool drain and a manual release can all reach an unfinished actor
Who decides when a use ends
Two approaches, and they are not interchangeable. Release Actor After(Actor, Seconds) is a blunt cutoff owned by the caller, right for impacts, decals and casings, which have no notion of having finished. An actor with real completion semantics should own the decision instead.
- Give it per-use launch parameters and let it close its own state
- In C++, publish a release delegate the pool binds once, so it reclaims itself
- Stack both and one actor gets two independent cutoffs; whichever lands first wins
The trap that reaches production
COND_InitialOnly sends a property only in an actor's first bunch. A recycled actor's channel is already open on its second use, so the property is never resent. Nothing errors and nothing logs.
- Clients keep acting on the first use's data
- The docs call it out before you write the code
Technical details
- Engine
- UE 5.8
- Tested platforms
- Windows
- Blueprint-ready
- Yes
- C++ required
- No
- Network replicated
- Yes
- Dependencies
- DeveloperSettings, NetCore
Frequently asked questions
Do I need C++ to use it?
GetPoolReleaseDelegate, a way for an actor to reclaim itself, because a Blueprint cannot hand out a delegate reference (Blueprints call Release Actor instead), and ICrimsonPoolableAdapter, for pooling a class you cannot edit.Does it work in multiplayer?
Do I have to implement an interface?
ICrimsonPoolable makes your OnAcquiredFromPool the only reactivation that happens, which is what you want when an actor needs to reset its own state. There is no middle setting: two owners writing the same visibility and collision state is the failure mode the exclusivity rule exists to prevent.Is there anything that can't be pooled?
bOnlyRelevantToOwner. Changing the owner on reuse makes it non-relevant to the previous owner, whose client destroys it; the pool warns once per class if you try. There is also one ordering rule worth knowing: prewarming is refused before the world has begun play, because actors spawned that early run BeginPlay while parked in the free list and undo their own deactivation. From BeginPlay onward is always safe.Does it depend on other Crimson plugins?
ICrimsonPoolable ships in this plugin, and a class you cannot edit is pooled through a registered ICrimsonPoolableAdapter. With CrimsonCore, CrimsonHitDetection's ACrimsonProjectile is registered automatically and pooled launch ability tasks are added; standalone, write that glue yourself.Is it really free?
Stop paying for spawns you already paid for
Swap two nodes, watch spawnsAvoided climb, and keep the bypass switch in your pocket for the day something looks wrong. The Quick Start pools a cosmetic actor end to end in about five minutes.
Ready for more? Add a premium system
Every premium system runs on its own, so add only the ones your game needs.
Data-driven hit detection for melee, area, hitscan and projectiles.
- GAS Target Data
- Interpolated Sweeps
- Composable Filters
- Hit Zones
- Pool-Ready Projectiles
A full Gameplay Ability System layer for UE5.
- Custom ASC & Abilities
- Slot-Based Augments
- Modifiers & Phases
- Graph-Based Combos
Layout-agnostic, fully replicated inventory with bags and containers.
- Pluggable Topology
- Runtime Constraints
- Scoped Containers
- No RPCs to Write