The correct approach in our opinion is that a runtime supports only a specific
major.minor version of Spine. A runtime should not try to load data from other Spine editor versions. None of our runtimes do that. The reason for is it would bloat the runtimes to have code to read older versions. Beyond that, the runtimes and their APIs evolve over time and there is no guarantee that all old data makes sense for the latest APIs.
To move to a higher
major.minor version, skeletons must be exported with the corresponding Spine editor version to provide data compatible with the new runtime version. See here:
This approach keeps the compatibility complexity centralized in the Spine editor. Of all the many Spine runtimes for all the different programming languages and game toolkits, none of them need to be bloated by loading old data and massaging it to work with the latest APIs. This reduces the runtimes code size and complexity and means fewer bugs.
The downside is an inconvenience for users because they need to re-export all their projects. While that can be a pain, generally it is a one-time pain to set up some scripts to automate the exporting. After that, re-exporting is easy. Users that have integrated exporting into their build processes, which we highly recommend, won't be inconvenienced at all. We do not feel that it is worth bloating the runtimes to avoid re-exporting.
If you want to support old skeleton data, branch your runtime and maintain a copy of your runtime for each version you support. Users then choose the appropriate runtime version that matches the version of the Spine editor they are using. This is the way. It's what we do. Any Spine user can choose a branch for an older version. We generally only support the latest version, though sometimes we still make fixes one version back. If users want more fixes than that, they should use the latest.
I can ramble some thoughts on general game toolkit Spine support: First, loading data from old versions does not need to be a design goal. It's not an insurmountable problem for any other runtime. Next, the runtime should basically be layer between the game toolkit and our spine-ts runtime that is as thin as possible. The Spine skeleton should be a single scene graph node that renders all the skeleton's attachments. Don't add game toolkit scene graph nodes for Spine attachments or use game toolkit transforms for them. spine-ts already does the computations. Rendering in the game toolkit should look very similar to rendering in our official runtimes: iterate the slots, get the triangles, render them. If the game toolkit doesn't have a batching mechanism to do that rendering, then that needs to be added. Any half serious game toolkit should already have it, but for a few game toolkits we have needed to add it ourselves (residing in our runtime). In some cases we have had to wait for the game toolkit developers to expose appropriate APIs for rendering (which says a lot about their lacking APIs). Debug rendering should be done the same way. Don't hide or wrap spine-ts APIs. Providing additional APIs can make sense, such as adding a texture as a new attachment. You should not need to copy/paste/modify or otherwise re-implement functionality that our runtimes provide (TextureAtlas, Color, interfaces for every Spine class, etc). Doing so makes it more difficult for you to update to new runtime versions in the future. If you find yourself doing a ton of work to get something done, there is probably an easier way. We are available and happy to discuss the best ways to get things done.
Please note that Mario is our runtimes lead and he's currently out for a little while for reasons. When he gets back he can also weigh in with his thoughts.