I built a similar thing that includes forces between particles meant to simulate a sort of fluid or, as you scroll down, a gelatinous solid. There’s a bit of free energy injected to keep things moving so it’s actually a very bad fluid sim, but I think that makes it a better interactive toy in exchange.
One of the fun parts of naively n^2 particle simulations is trying to find ways to reduce the algorithmic complexity of collision detection. I remember messing with sweep lines and similar, though I don’t remember what optimizations made it into the final code. [0]