CrimsonObjectPool
Actors that spawn and die in bursts - projectiles, impact effects, pickups, decals, shell casings, summoned turrets - 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 stands it down and parks it, and the next acquire reuses it.
Pooling is always explicit. The plugin never hooks engine spawn paths, so an actor is pooled only where you asked for it to be, and turning pooling off is a single console command.
Replicated actors have extra rules
Pooling a cosmetic actor is trivial. Pooling a replicated actor works and is fully supported, but it has rules - the most important being that
COND_InitialOnly silently breaks, because a recycled actor's channel is already open on its second use. Read How-To: Pool a Replicated Actor before pooling anything that replicates.What's included
| System | Key types | Purpose |
|---|---|---|
| The pool | UCrimsonObjectPoolSubsystem | Per-world, per-class actor recycling. Acquire, release, prewarm, drain, stats. |
| Actor contract | ICrimsonPoolable (ships in CrimsonCommon) | Optional. Lets an actor control its own reactivation, and optionally reclaim itself. |
| Configuration | UCrimsonObjectPoolSettings, FCrimsonObjectPoolClassConfig | Capacity, growth policy, prewarm counts - globally or per actor class. |
| Diagnostics | FCrimsonObjectPoolStats, Crimson.ObjectPool.Bypass, Crimson.ObjectPool.Dump | See what each pool is doing, and turn pooling off to isolate a bug. |
Plugin dependencies
| Dependency | Kind | Why |
|---|---|---|
CrimsonCommon | Crimson plugin | Logging macros, and the ICrimsonPoolable contract. |
Core, CoreUObject, Engine | Engine module | Actors, worlds, subsystems. |
DeveloperSettings | Engine module | Project Settings integration. |
NetCore | Engine module | The replicated-actor path. |
Why the interface lives in CrimsonCommon
No Crimson plugin may reference a sibling. An interface shipped inside CrimsonObjectPool could therefore never be implemented by an actor in another Crimson plugin. Putting
ICrimsonPoolable in the shared layer means any plugin's actor can be pooled with no glue code anywhere - which is exactly how ACrimsonProjectile works.Where to go next
- New here? Quick Start - pooling a cosmetic actor end to end, in about five minutes.
- Actor needs to control its own reactivation, or reclaim itself? How-To: Make an Actor Poolable.
- Pooling something that replicates? How-To: Pool a Replicated Actor - read this one before you write the code, not after.
- Deciding capacities? How-To: Size and Prewarm a Pool.
- Something is behaving oddly? How-To: Diagnose Pool Problems.
- Want the model rather than the recipe? Concept: The Reuse Contract and Concept: Replication and Recycling.
- Need an exact signature? API Reference.