[Answered] Multiple spine "skeletons" inside a single spine export. Is it possible?

gkri

Member
I was wondering if GMS2 can handle more than one skeleton from same json file (single spine export). I see on line many examples with a single skeleton but nowhere a case with 2 or more. I can not even tell if possible from the GMS2 manual.

Can anyone confirm it?
 

rIKmAN

Member
I was wondering if GMS2 can handle more than one skeleton from same json file (single spine export). I see on line many examples with a single skeleton but nowhere a case with 2 or more. I can not even tell if possible from the GMS2 manual.

Can anyone confirm it?
I'm not sure what you are trying to do, but Spine will export multiple skeletons inside the same project as seperate .json for each skeleton.

You can choose to share a single .atlas between them in the Spine export settings, but GMS2 wouldn't make use of this as it uses an atlas (or multiple atlases if required) per skeleton even if it's the same one being used by both Spine sprites.
 

gkri

Member
In order to understand better; Lets say a I have 10 skeletons that they share the same atlas (eg a single png 2048x2048), GMS2 will have in its memory this particular png x10 times?

And another question if you allow me; Let's say I have an instance of an object containing a spine skeleton, inside a room, will I able to switch the skeleton with another skeleton as I could normally do as it was a normal sprite?

Thank you! You are very helpful!
 

rIKmAN

Member
In order to understand better; Lets say a I have 10 skeletons that they share the same atlas (eg a single png 2048x2048), GMS2 will have in its memory this particular png x10 times?

And another question if you allow me; Let's say I have an instance of an object containing a spine skeleton, inside a room, will I able to switch the skeleton with another skeleton as I could normally do as it was a normal sprite?

Thank you! You are very helpful!
From my understanding each .json when loaded as a sprite in GMS2 also loads it's own atlas / set of atlases specific to that sprite even if it is the same skeleton and same atlases that are being used in different sprites.

You can test this by adding the same Spine skeleton into two different sprites in an empty project, assigning each one to a different object and dragging them both into the room.

Then run the project in debug mode and use the buttons at the top of debugger window pause the game, then restart it.

Now in the top menu of the IDE go to Debugger > Windows > Surfaces & Textures to open the "Surfaces & Textures" window, make sure "Textures" is selected in the dropdown at the bottom left and hit the "Refresh" button at the bottom right.

You will see that the texture atlas is listed twice - once for each skeleton - even though they are identical.


This is likely because of the way slot colouring and other functions specific to Spine skeletons work behind the scenes, and support for shared atlases is something I submitted as a feature request a long time ago so I know they aren't supported either.

In case there is some optimisation going on in the black box you should get in touch with support and ask them to confirm, though as I say from my knowledge of things it's unlikely.

For switching skeleton - yes you can change them just as you do with normal sprites by assigning the sprite_index to a Spine sprite.
 
Last edited:

gkri

Member
Thank you! I am "bombarding" questions because I am trying to figure out my workflow with GMS2...
 

rIKmAN

Member
Thank you! I am "bombarding" questions because I am trying to figure out my workflow with GMS2...
No problem - I just added some extra info so you can test it yourself using the Debugger.

My advice would be not to start over optimising before you have started making the game and if you do start to hit any issues later then to tackle them then.

Most of the time people worry about things that really aren't going to have a noticeable effect on their game and it stops them from actually making the thing. Pre-emptive optimisation can be a curse.

You have to be a bit more cautious on mobile but with regular on-device testing this can also be handled without too much of an issue.
 
My advice would be not to start over optimising before you have started making the game and if you do start to hit any issues later then to tackle them then. Most of the time people worry about things that really aren't going to have a noticeable effect on their game and it stops them from actually making the thing. Pre-emptive optimisation can be a curse. You have to be a bit more cautious on mobile but with regular on-device testing this can also be handled without too much of an issue.
This. Definitely don't over-optimize too soon....BUT IF YOU DID WANT TO........lol, I accidentally read the original question wrong and as way more intricate a question that it actually is, but I wrote all this optimization stuff up before I realized that so I'm gonna leave my insanity here for anyone searching for excessive Spine optimization theory in GMS2 because it's depressing to just delete this, especially if mobile devs who need extreme speed boosts might get some use out of it:

I think I know what you're trying to do [narrator: I didn't] because I was thinking the same thing a while back as a theoretical emergency optimization option. Are you thinking of something like having all the enemies in your game in one big "enemies" spine file, and on the root bone have children bones for "bat", "tiger", dinosaur" etc with their child bones and attachments all rigged up and then in a "bat_idle" animation all the other art would be turned off so just the bat's art is visible and so on for the other enemies, which would end up with all the enemy art for your game on one big atlas and thus one big texture sheet inside GMS2 instead of separate ones for each, and then like obj_bat, obj_tiger, and obj_dinosaur would all use the "enemies" sprite, but the obj_bat would only play the bat animations which just show bat related art?

I haven't fully tested it but from what I did test I don't have any reason to believe this wouldn't work. Separate skeletons within one Spine file like rIKmAN mentions would end up with separate JSONs, but if they're all attached to the same root bone so it's just one skeleton and ultimately just one sprite file under the Sprites in the Resource Tree, then GMS2 shouldn't have any idea you're doing tricky sleight of hand so it SHOULD work.

And if that's what you're asking about [narrator: it wasn't] then I can also tell you from testing that if you draw all your objects that use the same Spine sprites, at the same time, it only does one texture swap which is a massive speed boost. So if you draw 1000 enemies from that big spine file all at once, it's just one texture swap, but if you draw one enemy from the enemies.json file and then one coin from the items.json file and then another enemy from the enemies.json file etc 1000 times, it'll be a texture swap for every single one and slow your game to a crawl.

So ideally you would want to have something like an object that in the Draw Event goes through like "with (obj_enemies) {draw_self();} with (obj_items) {draw_self;}" etc which means you lose some depth management (since all the items would be drawn over top of all the enemies), which could be a problem for some game designs that rely on visual depth (like an RPG, as opposed to a shmup or flat 2d platformer), but you could maybe manage that with some trickery of going down the screen and drawing based on depth but dividing that into "draw the enemies on this horizontal line first, then the items..." and of course WITHIN the same spine file you should still be able to draw based on depth so you would be able to go through all the bats and tigers and dinosaurs and draw them in depth-based order, because that's all still just the same enemies.json texture sheet, but then the items.json would be drawn in front or behind all of those enemies...

Or you could just go 💩💩💩💩ing crazy and put your ENTIRE GAME into a ridiculously huge spine file with all the enemies, items, powerups, menu art, etc all going up to the same single parent root bone, using the new folders features in spine to make working in spine with this behemoth of a file manageable, and if the art for all of that fit onto like one 4096x4096 atlas or whatever...then you could presumably draw your entire game all with depth sorting however you want with essentially just one texture swap......lol

I haven't tested this because I haven't gone completely insane yet, and like 99% of games would never need to be optimized to this level...but based on what I've seen about how GMS2 and Spine interact, this should work and who knows maybe it's a technique mobile devs would get some use out of to shave off some FPS lag.

P.S. the less ridiculous optimization takeaway from this is that you want to make sure you draw stuff from the same spine file all at once wherever you can just in general. So if your game design can get away with having a layer for the bats, a layer for the tigers, a layer for the dinosaurs, etc that's going to run significantly faster than having an "enemies" layer where GMS2 is drawing a dozen bats, tigers and dinosaurs in random orders and having to swap textures each time it's drawing from a different atlas
 
Last edited:

gkri

Member
@BPOutlaws_Jeff

Thank you for your time to help me, and sorry I was not logged in for a while to see it. I was very busy with animation production. All I need to do is to display up to 12 relatively high resolution (crisp) characters, blinking, smiling and talking and was trying to figure out a workflow to serve me for the lip-sync process. I considered spine because I could do it fast and with ease, but finally I found another workaround without any extra plugins or costly licenses. Mean while my animation production kept me busy and I paused the project. Then I learned about the new features of the next version 2.3 of GMS2 which I think will resolve all my issues once and for all with the new timeline aka sequences, without any hassle. So I will resume the project when 2.3 is out of beta and stable.

Here is a sample of the results of the workaround just in case you 'd interested to see...
 
Top