{"id":1,"date":"2026-07-14T04:57:40","date_gmt":"2026-07-14T04:57:40","guid":{"rendered":"http:\/\/blog.skelform.org\/?p=1"},"modified":"2026-07-15T09:54:22","modified_gmt":"2026-07-15T09:54:22","slug":"hello-world","status":"publish","type":"post","link":"https:\/\/blog.skelform.org\/?p=1","title":{"rendered":"Re-animating the 2D Skeletal Animation Ecosystem"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Having played Flash games in the 2010s, I was accustomed to the style and charm of characters being rig-animated rather than the usual frame-by-frame. Being your usual programmer who could just barely draw up something fine, I wanted to make rigs and take advantage of procedural animation (characters looking at any angle, inverse kinematics, etc). This is apparently a big ask, as every opportunity comes with some major caveat.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s start with a bit of context; I primarily want to make my games using <a href=\"https:\/\/macroquad.rs\/\" data-type=\"link\" data-id=\"https:\/\/macroquad.rs\/\">libraries<\/a>. These tend to be very simple frameworks, so much so that they don&#8217;t have any <a href=\"https:\/\/godotengine.org\/\" data-type=\"link\" data-id=\"https:\/\/godotengine.org\/\">visual editor<\/a> to lay things out. This is fine as most visual work like <a href=\"https:\/\/www.mapeditor.org\/\" data-type=\"link\" data-id=\"https:\/\/www.mapeditor.org\/\">level design<\/a>, <a href=\"https:\/\/krita.org\/en\/\" data-type=\"link\" data-id=\"https:\/\/krita.org\/en\/\">textures<\/a>, etc. are done in separate programs. Skeletal animation is no different, but the ecosystem isn&#8217;t as bright.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Illusion of Choice<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The 1st option would be <a href=\"https:\/\/dragonbones.github.io\/en\/animation.html\" data-type=\"link\" data-id=\"https:\/\/dragonbones.github.io\/en\/animation.html\">DragonBones<\/a> &#8211; it&#8217;s the most competent while being fully free. It&#8217;s got inverse kinematics and mesh deformation; you&#8217;d say it&#8217;s a steal if they weren&#8217;t outright giving it away! Unfortunately no one&#8217;s there to give it out anymore. Scroll down to the bottom of the barely-working site and you&#8217;ll see this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"764\" height=\"94\" src=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image.png\" alt=\"\" class=\"wp-image-27\" srcset=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image.png 764w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-300x37.png 300w\" sizes=\"auto, (max-width: 764px) 100vw, 764px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Even with other signs of life taken into consideration (eg; the Twitter account made in 2020), it&#8217;s clear that DragonBones isn&#8217;t being maintained anymore. You know what <em>is<\/em> maintained, however? The subscription-based, web-only, AI-centric animator known as <a href=\"https:\/\/www.loongbones.app\/\">LoongBones<\/a>! How&#8217;s that for a juxtaposition?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I would say &#8216;the 2nd option would be&#8230;&#8217; but the rest of the animators have the same issue with minor deviations, so I&#8217;m lumping all of them in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Besides DragonBones, the other &#8216;obvious&#8217; choice is <a href=\"https:\/\/esotericsoftware.com\/\" data-type=\"link\" data-id=\"https:\/\/esotericsoftware.com\/\">Spine<\/a>. It&#8217;s the ultimate animator, and I know it is because it costs almost three times my monthly rent!<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"588\" height=\"328\" src=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-1.png\" alt=\"\" class=\"wp-image-28\" style=\"width:287px;height:auto\" srcset=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-1.png 588w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-1-300x167.png 300w\" sizes=\"auto, (max-width: 588px) 100vw, 588px\" \/><figcaption class=\"wp-element-caption\">That rent comparison was for $379, by the way<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The Essential version is still a whopping $80. No, it&#8217;s not worth it just because the full version is so prohibitively overpriced. The Essential version doesn&#8217;t even include mesh deformation, which you could at least get in game engines like Godot or Unity.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Speaking of those engines&#8230; why not pick them? As mentioned previously, I much prefer the workflow of simpler frameworks. It&#8217;s not speculation either &#8211; I used to take game dev on Unity semi-seriously (only got 2 games to show for it, but unfinished projects and all that). While I haven&#8217;t used Godot as much, I&#8217;ve heard that making and animating rigs from within it isn&#8217;t all that great, and it could still benefit from a dedicated animator.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Other options like Creature and Spriter have similar price issues as Spine. It&#8217;s on a smaller scale, but I&#8217;m still not paying that much for something I don&#8217;t even know will be good to use when the honeymoon phase of a game&#8217;s development is over and it&#8217;s time to start actually making things work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With all this in mind, I was willing to ignore DragonBones&#8217; issues and try it out anyway &#8211; it&#8217;s fine. The UI is confusing and I didn&#8217;t get far with my own characters, but that&#8217;s because I spent most of my time on the <a href=\"https:\/\/crates.io\/crates\/rusty_dragonbones\">runtime<\/a>. Being acquainted with the runtime development process gave me a very bright idea:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What if I just&#8230; made my own thing?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>The 15th Standard<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now hold on &#8211; before you go &#8216;oh boy, here&#8217;s <a href=\"https:\/\/xkcd.com\/927\/\" data-type=\"link\" data-id=\"https:\/\/xkcd.com\/927\/\">another for the pile<\/a>,&#8217; hear me out.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DragonBones has more issues than simple abandonment. The editor itself isn&#8217;t open-source, and there&#8217;s no runtime documentation or specification (reading source code of existing runtimes doesn&#8217;t count). While people like me could make said docs, there&#8217;s nothing stopping the editor&#8217;s inevitable <a href=\"https:\/\/en.wikipedia.org\/wiki\/Software_rot\" data-type=\"link\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Software_rot\">bit rot<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If it wasn&#8217;t clear by now, I&#8217;m not doing all of this just for myself &#8211; I want to see animations like these beyond just from my own games, and no amount of effort on my end will offset the constant decline of an aging editor. With all this being said, I would like to introduce my solution:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>SkelForm<\/strong> &#8211; A free and open-source 2D skeletal animator for games.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Skeletal Animation for Everyone<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s the tagline I&#8217;m building SkelForm on &#8211; it&#8217;s a bit cringy, but it helps to keep in mind that SkelForm should ideally be suited for both newcomers and veterans of animation software.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s get the easy points out of the way; it&#8217;s free, not just as in <a href=\"https:\/\/www.gnu.org\/philosophy\/free-sw.html\" data-type=\"link\" data-id=\"https:\/\/www.gnu.org\/philosophy\/free-sw.html\">free beer<\/a> but open-source. It&#8217;s on Windows, Mac, Linux, and&#8230; web! This is big not just because installation isn&#8217;t required, but it also provides a fallback if downloaded versions don&#8217;t support any particular platform (eg; FreeBSD, mobile, etc).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>A friendly UI<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I mentioned that DragonBones&#8217; UI is confusing, and that complaint did not go in vain; SkelForm&#8217;s UI was based on Godot\/Unity&#8217;s editors, which make a clear separation between object hierarchy and properties:<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"799\" data-id=\"45\" src=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/skf-1024x799.png\" alt=\"\" class=\"wp-image-45\" srcset=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/skf-1024x799.png 1024w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/skf-300x234.png 300w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/skf-768x600.png 768w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/skf-1536x1199.png 1536w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/skf.png 1628w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"746\" data-id=\"46\" src=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/godot-1024x746.png\" alt=\"\" class=\"wp-image-46\" srcset=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/godot-1024x746.png 1024w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/godot-300x218.png 300w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/godot-768x559.png 768w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/godot-1536x1119.png 1536w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/godot-2048x1492.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/figure>\n\n\n\n<p class=\"has-text-align-center is-style-text-annotation\" style=\"font-size: 14px\">left &#8211; SkelForm; right &#8211; Godot<br\/>red &#8211; hierarchy panel <br> green &#8211; properties panel<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The UI across the program trades some &#8216;efficiency&#8217; for familiarity; many elements like the edit modes (Move, Rotate, Scale) and Armature\/Animation modes could have been icons and\/or been in a single bar, but laying them out as text and spreading them across the UI ensures that no single part is overwhelming.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"771\" src=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/Screenshot-2026-07-14-at-23.43.35-1024x771.png\" alt=\"\" class=\"wp-image-57\" style=\"aspect-ratio:1.3281853281853282;width:468px;height:auto\" srcset=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/Screenshot-2026-07-14-at-23.43.35-1024x771.png 1024w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/Screenshot-2026-07-14-at-23.43.35-300x226.png 300w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/Screenshot-2026-07-14-at-23.43.35-768x578.png 768w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/Screenshot-2026-07-14-at-23.43.35-1536x1156.png 1536w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/Screenshot-2026-07-14-at-23.43.35.png 1592w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">An example of worst-case scenario for UI entropy<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Of course this will only get harder as more features are added, but I think it&#8217;s fine in spite of all the features that SkelForm currently has to offer. After all, it shouldn&#8217;t be a lot.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>A Lot to Offer<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A skeletal animator isn&#8217;t complete until it has inverse kinematics and mesh deformation. Even if most of your rigs use it, the potential of procedural animation and faster workflows can&#8217;t be overstated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These features will have their own posts when the time comes, so have this rapid-fire list for now:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Inverse Kinematics w\/ constraints (clockwise\/counter-clockwise)<\/li>\n\n\n\n<li>Mesh deformation with binds, weights, and pathing<\/li>\n\n\n\n<li>Styles &#8211; mix-and-match texture system for skins\/outfits<\/li>\n\n\n\n<li>Procedural physics via damping, swaying, bouncing<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The above is just for runtime features &#8211; the editor alone can import and convert PSD files into working armatures (provided it has the <a href=\"https:\/\/skelform.org\/user-docs\/psd.html\" data-type=\"link\" data-id=\"https:\/\/skelform.org\/user-docs\/psd.html\">right structure<\/a>), as well as exporting to armature, spritesheets, and video.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As a developer it may seem daunting to see all of those runtime features and be expected to implement them. Don&#8217;t worry, the &#8216;Everybody&#8217; in the earlier tagline includes you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Besides the <a href=\"https:\/\/skelform.org\/user-docs\/\">User Documentation<\/a> which contains help for using the editor (as well as using complete runtimes), there&#8217;s a separate <a href=\"https:\/\/skelform.org\/dev-docs\/v0.7\/introduction.html\">Developer Documentation<\/a> that is entirely dedicated to creating runtimes from scratch. While it&#8217;s not super detailed and still missing a lot of explanations, it contains commented Typescript examples for every single implementation.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"605\" src=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-3-1024x605.png\" alt=\"\" class=\"wp-image-61\" style=\"aspect-ratio:1.692566320882365;width:454px;height:auto\" srcset=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-3-1024x605.png 1024w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-3-300x177.png 300w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-3-768x454.png 768w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-3-1536x908.png 1536w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-3.png 1706w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Although it&#8217;s hard to market this as a selling point, being as friendly and transparent about every part of the runtime specification and implementation is core not just for others to integrate SkelForm, but also to hold it accountable and ensure its complexity doesn&#8217;t get out of control. If a feature is missing in SkelForm, it&#8217;s most likely because I haven&#8217;t yet figured out a practical implementation that&#8217;s easily documentable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To prove that all this documentation actually works, I&#8217;ve created not 1, not 2, but 9 different runtimes (4 generic and 4 engine)!<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"401\" src=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-4-1024x401.png\" alt=\"\" class=\"wp-image-77\" style=\"aspect-ratio:2.5516133020150824;width:416px;height:auto\" srcset=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-4-1024x401.png 1024w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-4-300x118.png 300w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-4-768x301.png 768w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-4.png 1388w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Taken as of July 2026. More will be added over time<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You may be wondering why there isn&#8217;t a Javascript game engine despite having a Javascript runtime. That one was created for the <a href=\"https:\/\/github.com\/Retropaint\/skelform-web-player\">web player<\/a>, which appears just below the web editor on the site:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"810\" src=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-6-1024x810.png\" alt=\"\" class=\"wp-image-79\" style=\"aspect-ratio:1.2648996476175884;width:355px;height:auto\" srcset=\"https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-6-1024x810.png 1024w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-6-300x237.png 300w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-6-768x607.png 768w, https:\/\/blog.skelform.org\/wp-content\/uploads\/2026\/07\/image-6.png 1318w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">No WebAssembly required!<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">It works just like any other runtime, and can be used to add SkelForm animations to your own sites \ud83d\ude42<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;ll be all for my villain origin story. What started as an innocent attempt to make a game with quirky animations led to a year-long (and counting) project to being said quirky animations to the masses. Yes, that sounds ambitious and a bit delusional, but I wouldn&#8217;t have gone this far if I didn&#8217;t believe in it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Having played Flash games in the 2010s, I was accustomed to the style and charm of characters being rig-animated rather than the usual frame-by-frame. Being your usual programmer who could just barely draw up something fine, I wanted to make rigs and take advantage of procedural animation (characters looking at any angle, inverse kinematics, etc). [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.skelform.org\/index.php?rest_route=\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.skelform.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.skelform.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.skelform.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.skelform.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1"}],"version-history":[{"count":47,"href":"https:\/\/blog.skelform.org\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":84,"href":"https:\/\/blog.skelform.org\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions\/84"}],"wp:attachment":[{"href":"https:\/\/blog.skelform.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.skelform.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.skelform.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}