Grid/Destruction/DebrisPool.cs
using Sandbox;
using SWB.Base;
using SWB.Demo;
using System.Collections.Generic;

public sealed class DebrisPool : Component
{
    [Property] public GameObject DebrisPrefab { get; set; }
    [Property] public int MaxDebris = 400;

    readonly Queue<GameObject> _pool = new();
    int _active;

    
    public bool TrySpawn(Vector3 position, Vector3 velocity)
    {
        if (_active >= MaxDebris)
            return false;
        
        var go = GetOrCreate();
        go.Transform.Position = position;
        go.Enabled = true;

        if (go.Components.TryGet<Rigidbody>(out var body))
        {
            body.Velocity = velocity;
            body.AngularVelocity = Vector3.Random * 6f;
        }

        _active++;
        //ReturnToPoolDelayed(go, 6f);
        return true;
    }

    bool IsNearAnyPlayer(Vector3 pos, float maxDist = 1200f)
    {
        foreach (var p in Scene.GetAllComponents<DemoPlayer>())
        {
            if (p.GameObject.Transform.Position.Distance(pos) < maxDist)
                return true;
        }
        return false;
    }

    GameObject GetOrCreate()
    {
        if (_pool.Count > 0)
            return _pool.Dequeue();

        var go = DebrisPrefab.Clone();
        go.NetworkSpawn();
        return go;
    }
    async void ReturnToPoolDelayed(GameObject go, float delay)
    {
        await Task.DelayRealtimeSeconds(delay);
        
        ReturnToPool(go);
    }
    void ReturnToPool(GameObject go)
    {
        if (go == null)
            return;

        if (go.Components.TryGet<Rigidbody>(out var body))
        {
            body.Velocity = 0;
            body.AngularVelocity = 0;
        }

        go.Enabled = false;
        _pool.Enqueue(go);
        _active--;
    }
}