Jump to content
  • entries
    3
  • comments
    2
  • views
    2,156

The Starbound Animation Framework .sequence files


Severyx

1,579 views

This entry will be expanded upon as the Starbound Animation Framework (SAF) is further worked upon.

 

The SAF posts are primarily directed at modders who intend to use the Starbound Animation Framework or create their own animations for it. Hopefully this post becomes a sort of tutorial in creating animations for Starbound using this system. Let's get into some detail about the Starbound Animation Framework and how it utilizes the new json configuration type I've introduced: .sequence files.

 

First, let's get a look at what a .sequence configuration file looks like:

 

blogentry-229749-0-09328100-1504629917_thumb.png

 

Bunch of stuff in there! Let's break it all down. For those of you unfamiliar with JSON format, it's actually really simple. Unfold the following 'spoiler' to get a crash course.


There are several different 'types' of information that can be used in JSON files, but I'll only go over the ones necessary to the .sequence files.

  • Strings: Usually text or numbers treated as text. Strings have "double quotes" around them.
  • Numbers: Pretty straightforward. Numbers are just numbers with no quotes and can contain decimals where necessary. They cannot be letters or special characters.
    • IMPORTANT IMPORTANT IMPORTANT NOTE: "5" and 5 are NOT the same! "5" is a string showing the number five, 5 (no quotes) is a number. This can be confusing, but it is critical to remember!

    [*]Arrays: A container of an ordered collection of things. Arrays begin with [ and end with ]. Any other data type can be inside the [ ] including other arrays. Each piece of data is separated by a comma.

    • Example array: ["string1", "string2"] (notice the comma between them, but not after the second string)
    • Example of two arrays IN an array: [ [1, 3, 6], [9, 4, 2] ] (notice the comma between data AND between arrays
    • The order in which things are written into an array is important, especially in a .sequence file (you'll see later).

    [*]Objects: The top-level container for data, staring with { and ending with }. In the case of the sequence file, each sequence file is an object, which is why you see a { at the very top and a } at the very bottom. You won't need more than this.


Each piece of data in a JSON configuration file has a Property Name and the data for that property, separated by a colon.

 


Example:
"propertyName" : "String Data"
or
"thisIsAnArray" : [ "arrayString1", "arrayString2" ]

 

Something quite important to note: ANY time you have more than one of anything in a container, you need to put a comma at the end to denote the fact that this particular piece of data is finished. Just like the commas between things in an array, this applies to everything, including objects. After we define a property name and the data it includes, it needs a comma after each one unless it is the last.

 

Example:
"propertyName" : "String Data", <-- COMMA (this is one property and there are more after it)
"thisIsAnArray" : [ "arrayString1", <-- COMMA (this is one piece of the array)"arrayString2" <-- NO COMMA (last piece of the array)], <-- COMMA (this is one property and there's more)
"lastProperty" : 5 <-- NO COMMA (this is the last piece of data in this container)

 

The comma thing is EXTREMELY IMPORTANT, as Starbound will CRASH if it tries to load a JSON file that doesn't follow this specific format.

 

Starbound doesn't really tell you in plain text where the problem is (you have to get used to reading the starbound.log file and picking out the right information), so if you need to find a problem or you just want to ensure it's correct before you start using it, you can go to an online JSON validator and paste the entire code in to see if it checks out. If not, they'll usually tell you where and why in a way that's a bit more straightforward.

 

https://jsonlint.com is but one of many json validators you can use to check your JSON code.

  • "name" (string): This is, obviously, the name of the sequence. This should match the name of the sequence file name and cannot be empty.
    • In this case, the name of the file is testTwo.sequence

    [*]"receivers" (number): This is a number used to denote how many receivers there are in this animation sequence. A receiver is, in the case of use here, a character getting pounded. Currently limited to 1 OR 2. Cannot be 0, ever. Solo animations consider the one character as a receiver. [*]"givers" (number): This is a number used to denote how many givers there are in this animation sequence. A giver is opposite of the receiver, that is, the character doing the pounding. Currently limited to 0-3.

    • The giver and receivers are internally used aren't necessarily locked to the role of giving and receiving. Since positioning, animations played, and facing direction are controlled during the animations, a giver can appear to receive during the animation. The important thing to remember is that when the animation framework assigns a character to a giver or receiver position, it will use that through the entire sequence.
    • Example: If the player is the giver and an NPC is the receiver when the animation begins, the player will always be 'giver' and the NPC will always be 'receiver' until that entire sequence is done. You CAN, however, give the player 'receiving'-type dances to make them LOOK like they are getting pounded despite having the role of 'giver'.

    [*]"stages" (number): This is the number of stages the animation sequence has. This allows you to have the characters swap positions and change to new dances mid-sequence. There is no limit to how many stages there are, but the number of durations and the number of dances, emotes, and facings for EACH PARTICIPANT must be equal to the number of stages. [*]"durations" (array of numbers): This is how long, in seconds, each stage will last. The go in order, so the first number is duration of the first stage, the second number is for the duration of the second stage, etc. [*]"receiverAnchors" (array of arrays of numbers): This is an ordered set of lounge anchors used to position the characters (more information in the Animation Framework portion).

    • Each array inside the main array corresponds to a receiver character. In this case, there is only one receiver in this sequence so there is only one set of receiverAnchors. Were there 2 receivers, it would look like this: [ [1, 7, 1], [3, 5, 3] ] with the green array referring to the first receiver's anchors, and the yellow array referring to the second receiver's anchors.
    • Each number inside the character's set is the loungeAnchor they will use per stage. The first number is where they will position in the first stage, the second in the second stage, etc. In this case, the receiver will be on the left (anchor 1) in the first stage, on the right (anchor 7) in the second stage, and back to the left in the third stage.
    • There are 3 stages, so there must be 3 anchors in each character's array.

    [*]"receiverFacings" (array of array of numbers): This is an ordered set of character facings used for each stage, similar to receiverAnchors.

    • There are only two numbers to be used for each character's stage. 0 faces the character left. 1 faces the character right.
    • 1 receiver means 1 array of facings.
    • 3 Stages means three facings for each receiver.

    [*]"receiverDances" (array of arrays of strings): This is an ordered set of dances for each receiver's stages, structured similar to receiverAnchors but with strings instead of numbers.

    • The dances are what ACTUALLY make the characters perform their animations (see my previous blog about these), and they are referred to by their name.
    • In this case, the receiver will play the "playerStanding" .dance file during the first stage, playerKneeling.dance in the second stage, etc.
    • 1 receiver means 1 array of dances.
    • 3 stages means three dances in each array.
    • If you misspell a dance file name, STARBOUND WILL CRASH. Make sure you get it right!

    [*]"receiverEmotes" (array of arrays of strings): This is an ordered set of facial expressions the receivers will show during each stage, structured similar to receiverDances.

    • Emotes are referred to within script by their name. It might be good to get a reference for the actual names the game uses.
    • 1 receiver means one array of emote names.
    • 3 stages means--- you get the idea.
    • If you misspell an emote name, STARBOUND WILL CRASH. Make sure you get it right!

    [*]"giverAnchors": Same as receiverAnchors, but for the giver positions. Can be empty if the number of givers is 0. [*]"giverFacings": Same as receiverFacings, but for the giver positions. Can be empty if the number of givers is 0. [*]"giverDances": Same as receiverDances, but for the giver positions. Can be empty if the number of givers is 0. [*]"giverEmotes": Same as receiverEmotes, but for the giver positions. Can be empty if the number of givers is 0. [*]"tags" (array of strings): This is an unordered array of tags that the sequence applies to so that the animation framework's sequence loader/utility can narrow down a list of applicable sequence animations to choose from when an animation needs to be selected (sexlab style). This has not been standardized yet, and won't be until the framework is in a more completed state and I will go over seqUtil.lua functionality at a later date. You will get a warning in the log if your sequence doesn't have tags.


Lots to absorb, I know! However, I tried to include as many useful properties as necessary in order to make the animation framework as useful as possible from the beginning so that I wouldn't have to go back and refactor entire chunks of code when certain core features (like tag searching) were included.

 


Every .sequence file needs all of these things. If anything is missing, empty, isn't the right type of data (you put "" around a number, for example), or doesn't match up (you have 3 stages but receiverDances only has 2 dances per receiver) the sequence loader in seqUtil.lua will NOT include your sequence when it loads them! The only exception to this is the tags property, but your sequence cannot be sorted by tag searches if you have none. It will, however, list out all of the problems with the sequence configuration in the starbound.log file so you can find and correct them.

 

This took longer to put together than I expected, so I will go over SAF API functionality in my next blog post!

0 Comments


Recommended Comments

There are no comments to display.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use