Client vertex arrays (which I assume you meant, it's a bit ambiguous with unrelated Vertex Array Objects also existing), while a whole lot better than direct vertex specification, are actually also immediate mode and very slow in comparison to retained-mode buffer objects. The difference being that with vertex arrays, you re-send the data every time you draw it, while with buffer objects you send it once and then refer to it via a handle. It's a huge PITA to set up and manage, but the performance gains are stunning - draw commands are just a tiny handful of bytes and are fully asynchronous. For example, the very basic integrated Intel graphics card in my laptop can easily draw 5 million triangles at 60 frames per second if they're all in one retained buffer.
Yeah, I meant client-side, not VBOs (didn't realize that was also called immediate mode, thanks for pointing that out!). I did actually try VBOs for some things - the speed was very similar to client-side arrays, though I suspect it's the sort of thing where it can start to matter more when you scale up. (Actually had an issue with VBO with some graphics drivers (on a Mac) where it was literally 100x slower than straight glVertex2f calls, though I'd hope that's fixed by now.)
The bigger problem with VBO usefulness is having to stick with a single texture. A VBO with 4 vertices in it isn't really worth it, performance-wise. Those 5 million triangles wouldn't render so quickly if they were split into 2.5 million VBOs, you know?
And that's kind of what you're stuck with, in sprite land. You could create a sprite sheet/atlas and batch things up that way, but that's 1) a big pain content-creation-wise and 2) makes things much harder to make mod-friendly. Imagine if all the weapons were in a sheet - they'd certainly fit, and it could make the "draw all weapons" part of ship rendering faster (heck, even without VBO use - just not having to bind new textures all the time would be a savings), but how would you go about mods adding new weapons in a setup like that?
Hmm. I guess you'd create a new texture with all the weapons at load-time, so that's doable, even if the problem of laying them out in the new texture ranges from "hard" to "NP-hard", depending on how efficient you need to be with the space. If weapon rendering was a big issue, then that might be worthwhile (but very time-consuming) optimization to make. It gets messier when you need things rendered in a particular order, though... like, for weapons, you've got the weapon sprites in a specific order, but then you've also got damage decals interleaved if there's damage.
... all of which, I suppose, falls right under "It's a huge PITA to set up and manage"