Optimized Static Mesh Projectile Pooling

All my data is separate. Each weapon on spawn creates a config (structs) pulled from data tables. A projectile configuration is stored in the weapon class based the specific weapon (M416 vs 1911 pistol)… The class that’s actually working with the pool.

Upon firing, the weapon class determines trajectory (Aim Velocity, LifeSpan etc) based on the config. It then passes the config’d values to the pool on projectile request. A single projectile class works for all calibers etc.

Data tables can be updated at run time. This makes it possible to adjust stats without a patch. Simple editing of a spreadsheet then push.

This is Data-Oriented Design. Pure ECS is just a variant with its strength coming from how things are a laid out in memory. You can’t do that with BP (Allocations & Memory Layout). It requires a lot of low level C++ programming.

Standard design principle is to bind data to logic that operates only on that data. Keep components as small as possible with one clearly defined responsibility.


Performance wise I get a 1-10 FPS dip when mag dumping 700 rnds/m at 790m/s muzzle velocity on Epic scalability settings. Depends on what else is in scene of course.

The only framerates I’m concerned with are the shooting client and the server. The only projectiles for the vast majority of time being simulated on each client is their own shots. Servers simulate all shots. Sim Proxy shots technically do not need to send a projectile down range. All you need from Sims is the action of shooting. Muzzle Flash, Audio, and recoil animation.

The only time you’d ever want to actually send a projectile down range on another clients simulation (Sim Shots) is if it would fly close enough for that client to hear a whizz as it flew by.

To help achieve this determination my character class’s begin play sets a proxy role enum. Proxy Role is then used by sims when they spawn to identify who is the autonomous (actual client) in the simulation.

Now all the sim proxy characters in my simulation know that my character is the local authority… Autonomous Proxy. I can do simple sphere traces to determine if any of their shots would register a muzzle sound (attenuation radius of shot) and/or if the projectile would fly by close enough to be heard in flight.

These two traces alone massively reduce the number of projectiles being simulated on a per client basis. Plus the added bonus of not playing additional audio / visual fx that will not be seen or heard by the local client.

For hit FX (Audio, Visual) the server can multicast the relevant data to sims.
struct [Location, Normal, PhysMat]

Here’s a demo I just recorded. I disabled muzzle flash/audio and recoil to help see the pooled projectile.