Try it in Dream Daemon and check the memory report. That will show you if there's an object leak in your code at all.
server mem usage:
Prototypes:
obj: 2552 (19)
mob: 2568 (1)
proc: 14272 (63)
str: 16219 (559)
appearance: 10142299 (46880)
id array: 14424 (118)
map: 8652 (10,10,1)
objects:
mobs: 156 (1)
objs: 509020 (3217)
datums: 0 (2)
lists: 15840 (14)


1 Minute Later -
server mem usage:
Prototypes:
obj: 2552 (19)
mob: 2568 (1)
proc: 14272 (63)
str: 16219 (559)
appearance: 6905755 (31896)
id array: 14424 (118)
map: 8652 (10,10,1)
objects:
mobs: 156 (1)
objs: 509020 (3217)
datums: 0 (2)
lists: 15840 (14)
Yep, that's what I'm seeing too. Appearance churn appears to be your biggest problem. When you show an appearance to the client, it will persist on the server until the client garbage-collects it, which is why the appearances are growing out of control.

The problem is that you have too many permutations in your projectiles. The source color has 21**3 permutations because of the three rand(10,30) operations, multiplied by 5 for the number of icons, multiplied by 360 because of rand(0,360) on the transform. (That should be rand(0,359) since the 360 is redundant.) Your animation target however is better, having only three possible target colors and another rand(0,360) rotation, for 5*3*360 possibilities.

What you need to do here is reduce the granularity. There's no way you need 1° of precision on the rotation, so instead of rand(0,359) you can go with rand(0,23)*15 for 15° increments. The three rand(10,30) operations on the source color are a big problem too, so find a way to reduce those by quite a lot. With the number of possible appearances reduced drastically, you should have much less churn. That will pretty much limit the remaining issues to whatever the proc's overhead is, and to rendering.

[edit]
I'm actually wrong about the source color permutations. It looks like 5*(21**2) rather than 21**3, so roughly 1/4 as many. That's still really bad, though.
I did some profiling, albeit with difficulty, to get some preliminary answers about the client side. On the client end of it, the problem appears to be multifaceted, but rendering doesn't seem to be the big problem. The GetMapIcons() function is taking up way more time than the renderer, and I had to do more in-depth profiling (which was extremely difficult and ultimately required dialing back the FPS) to get more answers there. The profiler is imperfect and I think it inflated some routines' influence while underestimating others, but it got me some numbers to work with.

The super-high FPS is obviously a big part of the problem, as all issues are going to scale with it.

GetMapIcons() is showing a high self-time, which I think may be based on some big-icon layering code that was meant to handle situations like big turf icons so they would overlay other turf icons more naturally; I suspect the nasty loops in there are playing some part, so it may be time to revisit that code OR eliminate it entirely (if a way can be found not to screw up games that rely on it).

While the sorting time in GetMapIcons() is showing up as slightly above insignificant, I think it's being inflated and I don't put too much stock into it.

CappearanceAnimate(), which does interpolation, is showing up as a high time-user, but with a low actual time. Instead most of its work is being done inside the matrix routines. Eliminating the transform from your animation showed a massive improvement in client-side CPU, but obviously that's not a great solution because you're varying size and not just rotation. The client-side code isn't really doing anything to avoid deconstructing the matrices when linear transforms are specified (not that you're doing that), so those won't be the time-saver I thought they would until I tweak this code.

All that said, the code that reads appearances took about as much time as the code used to display the map. You're generating so many new appearances here, it caused a significant slowdown. I understand that without severely limiting their permutations even beyond what I did for testing, though, really isn't an option, so I'll see what I can clean up in the appearance reading code. I already found that the "text movie" code is really doing way too much work for games that don't even use it, so I can cut down on that quite a bit for the next maintenance release.
In response to Lummox JR
After reducing the fps and increasing the loop tick from 0.3 to 1, I was able to spawn about 100 times more particles while keeping the CPU at 3%~. This makes sense, I don't know why I was using a number like 0.3 in the first place. I might even be able to get away with a slightly larger number as well.

EDIT
Even with 60 FPS, so long as the loop tick is 1, I can keep it at 3%. This is pretty awesome, only thing is, this is without transforms/unique appearances being generated. With them on it's roughly around 4-6%, and it being 100 times the particles I was originally generating, still really really good.
In response to Ishuri
Ok so I wasn't getting 100 times the particles active at once (they were dieing out too soon), after correcting that and making it 10 times, it's still at 3%~ but with the unique appearances off.
Making it 20 times pushes it up to 10%~.

I guess what I'm asking for is a way to spawn a whole bunch of these like how I am now while keeping the CPU count low. I could always increase the loop tick again, but I think any number higher than 1 might make things a little difficult to work with.
DM wasn't designed to handle particles well. If you can, attempt to batch your particles into a flat animated icon. If you can't, you are going to have to deal with some poor performance in the meantime.
Page: 1 2