Jump to content

[TUTORIAL] Compiling animations that remove symbols correctly


Monti18
 Share

Recommended Posts

This is just a short tutorial as to how compile animations correctly.

If you ever decompiled a Klei animation and tried to recompile it, you probably had the same problem as I had:
The recompiled animation file has some anims that look wonky, as some symbols are not removed during the animation.


Ex: the symbol chester_lid_0 is not properly removed in the closed animation
819011976_ezgif.com-gif-maker(9).gif.80bc1a3b5404b00274e2ee85764ec056.gif

 

Solution

To prevent this, you just need to tell the autocompiler if it's a looping animation or not. That's it!

Finding this error took me a lot of hours, the problem lies in the fact that Spriter (to my knowledge) doesn't have the option to set the animation as a looping anim or not. The autocompiler checks if the animation has a looping parameter, if it has none, the value is set to true, which isn't what we want for non-looping animations and as Spriter doesn't set this value, it's always true. A more in-depth explanation as to why we don't want that can be found at the end.

 

There are two different ways to rectify this:

 

Possibility 1:

You can add a looping = false for each animation that isn't a loop.

<animation id="22" name="open" length="200" looping = "false">

The autocompiler will read it and set the looping parameter to the corresponding value.

You will need to add them back each time you save the scml again, as those changes will be overwritten.

 

Possibility 2:

You can also change the source code of the autocompiler and compile it, this way you won't have to add the looping variable manually each time.

You will need to change the code at line 718 in src/app/scml/SCMLpp.cpp to this code or your own interpretation:

bool Data::Entity::Animation::load(TiXmlElement *elem) {
    id = xmlGetIntAttr(elem, "id", 0);
    name = xmlGetStringAttr(elem, "name", "");
    length = xmlGetIntAttr(elem, "length", 0);
    if (name.find("_loop") != -1) {
        looping = xmlGetStringAttr(elem, "looping", "true");
    } else {
        looping = xmlGetStringAttr(elem, "looping", "false");
    }
    loop_to = xmlGetIntAttr(elem, "loop_to", 0);

This is my way of making it automatic by checking if the name of the animation contains "_loop", if it does, the default value (i.e the value if no value is given in the looping parameter) will be set to true else to false. This way, you can still override each animation to be looping or not otherwise it gets the correct value from the name.

I already compiled this for myself so I added the scml.exe to the post, you can take it or create it yourself. 
If you use my file, you will need to replace the scml.exe with mine in the same folder as the autocompiler.

If you then recompile the scml with one of these possibilities, you get a correctly compiled chester:

127599171_ezgif.com-gif-maker(8).gif.9e0fdcacaf46f84f94986257d2851ec4.gif

 

Conclusion:

I hope this helps some people who wanted to make some more complex animations or wanted to reuse Klei assets but couldn't because the animations didn't work properly.

----------------------------------------------------------------------------

More in-depth explanation as to why we don't want non-looping animations to be set as looping:

The autocompiler sets the value of should_export to the value of looping in src/app/scml/main.cpp at line 544 in the function convert_timeline_to_frames, if the symbol isn't defined for the frame (if it was deleted for the frame). For looping animations, it should still be there, for non-looping it should be removed. The default value of the looping parameter is set to true, so every animation will be seen as a looping animation.

Edited by Monti18
Added where scml.exe should be replaced
  • Like 7
Link to comment
Share on other sites

On 12/14/2022 at 8:37 AM, FollowedPlate62 said:

What did you use to recompile the animations? I've been trying to make a mod and I haven't been able to compile my hat's animations with spriter. I have also not been able to find any info on this, so any help is appreciated.

You need to place the project file "anim_name.scml" and the image folders used in this project in the "exported" folder, which should be in your mod folder.
Then you just start the game, and the files are compiled into build.bin, anim.bin, atlas.tex, which will be in your mod folder with the name "anim", packed into an archive.
You can read the instructions here (steam tutorial)

And install the tools for modding in Steam, in the category "tools"

Link to comment
Share on other sites

On 12/14/2022 at 12:37 AM, FollowedPlate62 said:

What did you use to recompile the animations? I've been trying to make a mod and I haven't been able to compile my hat's animations with spriter. I have also not been able to find any info on this, so any help is appreciated.

The original poster mentioned a program called "scml.exe". For a Windows user, this can be found in

Program Files (x86)\Steam\steamapps\Don't Starve Mod Tools\mod_tools\

unless it's in Program Files instead of Program Files (x86).

As Leon Sadeness mentioned, if you have an scml file in your mod's folder, this program will automatically run when you start up DST, compiling your SCML into the formats DST uses, consisting of anim and build files.

You can also use this program directly through command line. It takes two arguments, the first of which is an SCML file, and the second of which is a directory to put the compiled files in. For instance, I've written a batch file that goes

set /P filename=Drag in your scml file  
set /P output=Where should the stuff go? 

"C:\Program Files (x86)\Steam\steamapps\common\Don't Starve Mod Tools\mod_tools\scml.exe" %filename% "%output%"

I'm a little haphazard about my SCMLs, and I don't mind the inconvenience of having to drag the generated files into my mod folder myself, especially since I typically need to poke inside them to remove either the build or the anim anyway.

 

Anyway, er, question, where is this cpp file? I'm not sure where to look for the "src" directory you have at the beginning of the path the OP specified.

And another thing I just noticed, that may be the answer to

On 9/1/2022 at 8:41 AM, Monti18 said:

Spriter (to my knowledge) doesn't have the option to set the animation as a looping anim

image.thumb.png.6ad4e3caa310b52fadf3f158a423e524.png

image.png.166a05b53a8661d317b227fb06b70e16.png

It seems this toggle (to which I've never paid attention before) is on by default, even for animations not meant to be looped. (I've checked on all my freshly decompiled Spriter projects too, since the one pictured has had some processing done to it after decompiling.)

Turning it off does make looping="false" appear in the SCML code. Turning it on removes the attribute, rather than adding looping="true", which lines up with what the cpp code seems to expect.

Still a pain to do so for every animation you decompile, of course. Is there any downside to marking a looped animation as non-looped? Will it randomly make things disappear fail to appear when an animation is looped, or something?

Edited by IceNine99
Clarification
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...