Without knowing exactly which Spine runtime you are targeting...
Let's say you have 200 little guys all using the same animation set. The way Spine is setup is a single AnimationData and SkeletonData instance that contains the initial (setup) pose skeleton descriptor and a single copy of all the animations.
Then, each little dude gets his or her own Skeleton and animation state. The animation state references the AnimationData for the animations, but keeps instance specific variables. The Skeleton also references the SkeletonData, but keep instance specific attachments.
The attachments will essentially have atlas/image/texture pointers. Assuming you use the built in atlasing, all 14 parts x 3 sizes should fit onto a single texture. This is important for drawing fast.
In the ideal situation, you will draw all of your little dudes in a single render call. When you iterate over the attachments, you would batch all of the triangles to a single draw buffer and send it once. Spine bakes all of the hierarchical transforms to flatten the triangles so you don't need to push and pop render transforms.
If you have different images interleaved between the dudes, it gets a little hairy if those images are on separate textures. Basically, your draw call aggregation would need to check for state changes, like texture or shaders, and flush the current batched call before starting on the next draw set.
Many runtimes will do this for you.
Updating the animations for 200+ little dudes will get a bit hairy. Fortunately, spine uses time based updates instead of frame based and will tween positions. This means you could conceivably run a 30 fps animation @ 10 fps.
I would probably take 1 of two approaches:
-
Easy: Update 10%,25% or 33% of the little dudes each frame and update a different set each time through
-
Complicated: use a background thread to generate the geometry for each little guy and cache the results. use an atomic pointer swap so the frontend will automatically grab the latest geometry. You will need to use a concurrent queue to grab the timeline events so you can sync them on the main thread.