👷‍♂️🛑 New poser Construction has started 🚜🚧
 
 
(4 intermediate revisions by the same user not shown)
Line 3: Line 3:
{{TOC|right}}
{{TOC|right}}
== Preface ==
== Preface ==
The <code>poser</code> JSON controls all the animations of a Pokémon. It contains information on when the Pokémon will perform certain animations. You can set your Pokémon to only ever perform one animation if you’d like, or you can give it different animations for just about every action it performs! It can even be used to adjust certain properties of an animation so you don't have to edit the animation itself. How smoothly one animation transitions to another can also be set through the poser.  
The new <code>poser</code> JSON controls all the animations of a Pokémon just as the old [[Poser]] did. It contains the same information for when the Pokémon will perform certain animations, but has received many requested upgrades. Some of these upgrades include multi-bone look animations, support for move animations, and even selecting from a pool of animations for quirks. Functionality of the new Poser will always be maintained and should let addon creators have the same options as the [https://gitlab.com/cable-mc/cobblemon/-/blob/main/common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/pokemon/gen1/SquirtleModel.kt hard-coded Kotlin Posers.]


=== Poser File Breakdown ===
== Poser Properties ==
The <code>poser</code> file requires an <code>animation</code> JSON to assign animations to a <code>model</code>. You're always going to want to be familiar with all the animations that were made for a model. If you assign an animation type that doesn't exist in the animation JSON then the game will crash! Also, if a bone you listed in the poser doesn't exist on the model then the game will crash! Once you figure out what animations were made for your target Pokémon model, you can simply apply the existing animations to appropriate <code>poses</code>.
Before breaking down each section of the new Poser file, let's take a look at all its different properties and how to use them. This section includes all of the different functions of the poser, any configurable options for said function, and how to write each function. You will notice that the poser now includes something in the format of <code>q.<function></code>. These are molang functions which allow you to do many new things. The q stands for query and its just part of the standard format for these new functions. Some functions can even go inside of other functions. It's not terribly complicated once you read what each one does. They allow addon creators to do many things they couldn't before!</br>


Sometimes there may be animations that don't seem to have a matching pose, such as <code>blink</code> animations. These can be applied using the <code>quirk</code> animation system. This system allows you to layer certain animations over an animation that is already playing in game. Making use of the quirk system can really help your Pokémon feel more alive!
=== Poses & Animations ===
There's a handful of Pose types and Animation types that you can make animations for. <code>Poses</code> are the states a Pokémon is in, like idle or moving. Poses are for assigning animations like your ground idles, ground walks, water idles, etc. The <code>animation types</code> are the different events in battles that you can assign animations to for each Pokémon. Animation types would include your faints, cries, and attack animations. Below is a list of currently available Animation types and Poses to choose from. </br>


Here is a breakdown of an example poser file which includes all the different properties that can be assigned. Hover over the underlined text to see more information. '''Every kind of possible poser function is included in this example at least once! So make sure that you review the whole file to see why some things are written the way they are.''' This example is not meant to be used as a template.
==== Animations ====
* '''faint''': <code>animation.<pokemon>.faint</code> - The animation that plays when a Pokémon faints.
* '''cry''': <code>animation.<pokemon>.cry</code> - The animation that plays when a Pokémon is called out or when it starts battle.
* '''recoil''': <code>animation.<pokemon>.recoil</code> - The animation that plays when a Pokémon takes damage in battle.
* '''physical''': <code>animation.<pokemon>.physical</code> - The animation that plays when a Pokémon uses a physical move in battle.
* '''special''': <code>animation.<pokemon>.special</code> - The animation that plays when a Pokémon uses a special move in battle.
* '''status''': <code>animation.<pokemon>.status</code> - The animation that plays when a pokemon uses a status move in battle.
</br>
==== Poses ====
* '''"STAND"''': <code>animation.<pokemon>.ground_idle</code> - The animation that plays when a Pokémon is idle on land.
** This pose type is also used for battle-idles: <code>animation.<pokemon>.battle_idle</code>
* '''"PORTRAIT"''': <code>animation.<pokemon>.portrait</code> - The animation that plays in the Party Overlay, or left hand party GUI
** This pose often uses the <code>ground_idle</code> instead of a dedicated animation.
* '''"PROFILE"''': <code>animation.<pokemon>.profile</code> - The animation that plays in the Party Menu, or when you press M.
** This pose often uses the <code>ground_idle</code> instead of a dedicated animation.
* '''"WALK"''': <code>animation.<pokemon>.ground_walk</code> - The animation that plays when a Pokémon is moving on land
* '''"HOVER"''': <code>animation.<pokemon>.air_idle</code> - The animation that plays when a Pokémon is idle in the air.
* '''"FLY"''': <code>animation.<pokemon>.air_fly</code> - The animation that plays when a Pokémon is moving in the air.
* '''"FLOAT"''': <code>animation.<pokemon>.water_idle</code> - The animation that plays when a Pokémon is idle in or on water.
* '''"SWIM"''': <code>animation.<pokemon>.water_swim</code> - The animation that plays when a Pokémon is moving in or on water.
* '''"SLEEP"''': <code>animation.<pokemon>.sleep</code> - The animation that plays when a Pokémon is asleep. Usually on land.
* '''"SHOULDER_LEFT"''': <code>animation.<pokemon>.shoulder_left</code> - The animation that plays when the Pokémon is on the player's left shoulder.  
* '''"SHOULDER_RIGHT"''': <code>animation.<pokemon>.shoulder_right</code> - The animation that plays when the Pokémon is on the player's right shoulder.
</br>
==== q.bedrock_stateful ====
The function <code>q.bedrock_stateful()</code> allows you to assign a stateful animation to an animation type. <code>Stateful animations</code> are meant to animate just a few bones of the Pokémon and get overlaid on the current pose. An example would be cries only animating the mouth or head of the Pokémon. A stateful animation won't take control of the whole model to play its animation.  
</br>


{
Here is an example of the 2 stateful animations, cry and recoil, in the poser:
  "portraitScale": 1.3,
  "portraitTranslation": [-0.7, 2.1, 0],
  "profileScale": 0.45,
  "profileTranslation": [-0.1, 1.0, 0],
  "animations": {
    "faint": "q.bedrock_primary('blastoise', 'faint', q.curve('one'))",
     "cry": "q.bedrock_stateful('blastoise', 'cry')",
     "cry": "q.bedrock_stateful('blastoise', 'cry')",
     "recoil": "q.bedrock_stateful('blastoise', 'recoil')",
     "recoil": "q.bedrock_stateful('blastoise', 'recoil')",
</br>
==== q.bedrock_primary ====
The function <code>q.bedrock_primary()</code> allows you to assign a primary animation to an animation type. <code>Primary animations</code> are meant to take control of the entire model to play its animation and will clear any previous animations it was doing. An example would be a Pokémon's physical attack animation. When a Pokémon uses a physical move, it should clear the battle idle animation and play its physical animation instead. These animations often move the whole body and many of its limbs. When the physical animation is done, it returns control of the model to the battle idle after the physical animation has finished and should play a short transition animation in between.
</br>
Since Primary animations behave in a similar way to swapping poses, they can use special transition animation types via the <code>q.curve</code> property written within its sub properties. These provide different types of smoothness to the interpolation and will be explained in the next section.
</br>
Below is an example of the 4 primary animation in the poser:
    "faint": "q.bedrock_primary('blastoise', 'faint', q.curve('one'))",
     "physical": "q.bedrock_primary('blastoise', 'physical', q.curve('symmetrical_wide'))",
     "physical": "q.bedrock_primary('blastoise', 'physical', q.curve('symmetrical_wide'))",
     "special": "q.bedrock_primary('blastoise', 'special', q.curve('symmetrical_wide'))",
     "special": "q.bedrock_primary('blastoise', 'special', q.curve('symmetrical_wide'))",
     "status": "q.bedrock_primary('blastoise', 'status', q.curve('symmetrical_wide'))"
     "status": "q.bedrock_primary('blastoise', 'status', q.curve('symmetrical_wide'))"
  },
 
  "poses": {
</br>
    "battle-standing": {
==== q.curve ====
      "poseTypes": ["STAND"],
The function <code>q.curve()</code> is a sub function for <code>q.bedrock_primary()</code> which allows the animation to interpolate back into the main pose. This allows the transition between animations to behave similarly to linear keyframes and smooth keyframes when animating.
      "isBattle": true,
</br>
      "animations": [
 
        "q.look('head_ai')",
The q.curve function comes with 3 options for now which are:
        "q.bedrock('blastoise', 'battle_idle')"
* <code>one</code>: Does not interpolate at all. Just jumps from one animation to the next. Preferred for faint animations.
      ],
* <code>symmetric</code>: Interpolates in a similar fashion to 2 smooth keyframes in blockbench. Not preferable, but is an option.
      "quirks": [
* <code>symmetrical_wide</code>: Interpolates in a similar fashion to 2 smooth keyframes in blockbench, but with a wider margin. The preferred choice when transitioning from moves.</br>
        "q.bedrock_quirk('blastoise', 'blink')",
 
        "q.bedrock_quirk('blastoise', q.array('quirk_battle_idle', 'quirk_battle_idle2'), 30, 60, 1)"
Below is an example of the 2 main q.curve types:
      ]
    "faint": "q.bedrock_primary('blastoise', 'faint', q.curve('one'))",
    },
    "physical": "q.bedrock_primary('blastoise', 'physical', q.curve('symmetrical_wide'))",
    "standing": {
</br>
      "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
==== q.bedrock ====
      "isBattle": false,
The <code>q.bedrock()</code> function is the familiar animation format from the [[Poser | old poser]] which got converted into a molang function. It's the same thing as before, just in a new look. You are still just listing your Pokémon and then the animation in the parenthesis. This function is mainly used to assign poses their animations. These animations are meant to be overwritten by Primary or Stateful animations whenever convenient.</br>
      "animations": [
Below is an example of the <code>q.bedrock</code> function assigning a walk animation to the <code>"WALK"</code> pose type:
        "q.look('head_ai')",
        "q.bedrock('blastoise', 'ground_idle')"
      ],
      "quirks": [
        "q.bedrock_quirk('blastoise', 'blink')",
        "q.bedrock_quirk('blastoise', 'quirk_ground_idle', 20, 60, 1)"
      ]
    },
     "walking": {
     "walking": {
       "poseTypes": ["WALK"],
       "poseTypes": ["WALK"],
       "animations": [
       "animations": [
        "q.look('head_ai')",
         "q.bedrock('blastoise', 'ground_walk')"
         "q.bedrock('blastoise', 'ground_walk')"
       ],
       ]
      "quirks": ["q.bedrock_quirk('blastoise', 'blink')"]
     },
     },
    "float": {
      "poseTypes": ["FLOAT"],
      "animations": [
        "q.look('head_ai')",
        "q.bedrock('blastoise', 'water_idle')"
      ],
      "quirks": ["q.bedrock_quirk('blastoise', 'blink')"]
    },
    "swim": {
      "poseTypes": ["SWIM"],
      "animations": [
        "q.look('head_ai')",
        "q.bedrock('blastoise', 'water_swim')"
      ],
      "quirks": ["q.bedrock_quirk('blastoise', 'blink')"]
    },
    "sleep": {
      "poseTypes": ["SLEEP"],
      "animations": ["q.bedrock('blastoise', 'sleep')"]
    }
  }
}
</br>


=== Advanced Poser Functions And When to Use Them ===
Posers can do a lot more than just assign one animation to a pose. Certain things can be tweaked in the poser to make your Pokémon livelier in game. If you enjoy making many different animations for Pokémon, then this section will help you implement them in game. Using these advanced feature can help you make custom Pokémon that are on the same level of quality as the official Pokémon!


Remember that you can have an unzipped copy of your addon as a resourcepack in the game for easier editing. Since the poser file is a part of the resources of an addon, it can be refreshed in game by pressing <code>F3 + T</code>. This reloads all your resourcepacks and allows you to see the changes you've made to the poser only if the poser you are editing is in the resourcepack folder. '''It is highly recommended to use unzipped folders to test addon stuff when implementing them into the game!''' You can simply make your file edits, save the file, and then refresh your resourcepack in game to see the changes immediately!
=== Portraits and Profiles & Scale and Translation ===
</br>
Portrait and Profile are the poses that are used when rendering any Pokémon in a GUI or Menu. Portrait is used for the left hand party screen, or Party Overlay, and Profile is used for the Party Menu. The poser file assigns some <code>Scale</code> and <code>Translation</code> values to these poses which control the camera location for rendering the Pokémon. There is a dev tool that you can enable in the [[Config]] which allows you to use some customizable keys to move the camera around the Pokémon in these menus. This tool will print the Scale and Translation values when the associated hotkey is pressed. </br>
==== Layered Animations ====
Layered animations are two or more animations that are listed together in your <code>animations</code> list. The most common example would be adding the <code>look</code> animation on top of your <code>ground_idle</code> animation for your standing pose. You're able to list more than two animations and your main limit would be running out of bones to animate.


The first animation listed should have priority control over the bones of the model. This is how Pokémon are able to look at you while walking around. The look animation has priority over the head bone, or whatever bone is listed as the head. This head bone will always attempt to look at a player if the player approaches.


Another example of layering animations would be having 2 kinds of animations that are meant to be played together and separate. A great example of this is charizard's walk animation. The walking animation itself only moves the legs for when it's walking. It combines the ground idle and the ground walk animations for its walking pose. The walk animation only controls the bottom half of the body, while the ground idle only controls the top half of the body. If you only listed its walk animation and it started walking, then the top half of charizard would t-pose whenever it walks.</br>
<code>Translation</code> values control the location of the camera for the Portrait or Profile. Translation is a set of 3 values which represent xyz coordinates. You will mainly be changing the first 2 values, or the x and y axis values. X for left and right, and Y for up and down. The Z value is rarely used, but is important for really big models that are not being fully rendered in the menus. It often needs a larger Z value.</br>
Charizard's walking animation list for its walking pose:
      "<abbr title="Here you will list which animations will play during these poses.">animations</abbr>": [
        "<abbr title="Allows the Pokémon to move its head around to observe its surroundings. You can delete this if your Pokémon doesn't have a head bone, or you just don't want them looking around.">look</abbr>",
        "<abbr title="This points to charizard's ground walk animation. Due to the way charizard's animations were made, this specified animation only animates the bottom half of charizard. If you do not include the matching ground idle after this, the arms of charizard will t-pose while it walks.">bedrock(charizard, ground_walk)</abbr>",
        "<abbr title="This points to charizard's ground idle animation. Due to the way charizard's animations were made, this specified animation only animates the top half of charizard. Adding this animation will allow charizard's arms and wings to be animated while it walks.">bedrock(charizard, ground_idle)</abbr>"
        ]
</br>


==== Animation Overwrites ====
<code>Scale</code> values control the amount of zoom for the Portrait or Profile. A value less than one should make it zoom out and a value greater than one will zoom in. Sometimes with larger models, the camera cannot render the whole Pokémon no matter how far you zoom out. The back side of the Pokémon may not be rendered. This means you need to increase the Translation z value.</br>
This function is mostly used for cases where you want an animation to be played exclusively for certain situations. You simply write <code>, true</code> after your animation type in your animations list. The most common use for this function would be writing it into your faint so the faint animation should always be playing when a Pokémon faints. Sometimes animations don't change properly and this can fix it most of the time.  


Below is an example of the faint using this overwrite function. What's going to happen in game is that when charizard faints, it will always play the faint animation over other animations it was already doing. This is fine because the faint animation animates the whole model. The cry animation does not contain this function because we want the cry to play over the idle animation, but not completely overwrite everything! If it did, then charizard would t-pose whenever it tried to do it's cry animation because it only animates the head bone.</br>


"<abbr title="This points to the faint animation for this Pokémon. If you have no faint animation, you can delete this line.">faint</abbr>": "<abbr title="This points to charizard's faint animation">bedrock(charizard, faint</abbr>, <abbr title="Adding 'true' like this will force this faint animation to play over all other animations whenever charizard faints.">true</abbr>)",
Below is a short breakdown of the previously mentioned properties:
  "<abbr title="This points to the cry animation for this Pokémon. Cries play whenever the Pokémon is called out of the pokeball. This occurs in and out of battle.">cry</abbr>": "<abbr title="This points to charizard's cry animation. Since it does not contain 'true' written after it, then this cry animation will not completely overwrite other animations when it plays. It should simply animate the bones it's supposed to while the rest of the bones can be controlled by another animation.">bedrock(charizard, cry)</abbr>",
    "<abbr title="This property controls the size of the Pokémon in the party menu on the left side of the screen. (Tip: you can refresh your resource pack with F3 + T for quick edits.)">portraitScale</abbr>": 1.65,
    "<abbr title="This property controls the location of the Pokémon in the party menu on the left side of the screen. The first value moves it left or right, which is your x axis. The second value moves it up or down, which is your y axis. The third value seems to do nothing and can generally be ignored. (Tip: you can refresh your resource pack with F3 + T for quick edits.)">portraitTranslation</abbr>": [0, -0.6, 0],
    "<abbr title="These refer to the full body view of the Pokémon seen in GUI, but most notably the summary UI. (Tip: you can refresh your resource pack with F3 + T for quick edits.)">profileScale</abbr>": 1,
    "<abbr title="This property controls the location of the Pokémon seen in GUI, but most notably the summary UI. The first value moves it left or right, which is your x axis. The second value moves it up or down, which is your y axis. The third value seems to do nothing and can generally be ignored. (Tip: you can refresh your resource pack with F3 + T for quick
edits.)">profileTranslation</abbr>": [0, 0.15, 0],
</br>
</br>


==== Quirks ====
=== Conditions ===
Quirk animations are extra animations that you can have play over the main animation list. What makes them different from the previous animation overwrite function is that these quirks can have extra properties applied to them. You can make them loop a certain number of times and include timers for these quirks. The most common example of a quirk animation would be the blink animations. By default, a quirk animation should play once every 8-20 seconds!
You can expand the amount of animations a Pokémon can have and when they should be played by using <code>conditions</code>. Conditions are what allow for battle animations despite the <code>standing</code> and <code>battle-idle</code> poses both using the <code>"STAND"</code> pose type. Typically, if you want different animations using the same pose types, then you must set one pose's condition to true, and the other pose's matching condition to false. You can mix and match these conditions to make something like an animation that only plays in battle, if it is raining while the sun is setting. </br>


Making a quirk in your poser file would largely depend on an animator making these quirky little animations to play in game. You can do more than just blinking animations. You can make a Pokémon roar, sneeze, or dance and have it play as a quirk for its standing pose or any other pose. A timer can then be applied to these quirk animations so you could end up with something like charizard doing a roar every 30-60 seconds when its idle. It's a very flexible sub system for animations that is only limited by your creativity.


Here is a list of properties that can affect quirks:
List of Currently Implemented Conditions:
"loopTimes": Int = 1 // The number of times the animation should play for the quirk
* <code>"isBattle"</code>: The Pokémon must be in a battle.
"minSecondsBetweenOccurrences": Float = 8 // The decimal-friendly number of seconds that is the  
* <code>"isTouchingWater"</code>: The Pokémon must be touching water. Not necessarily underwater.
minimum between the quirk playing once and it playing a second time
* <code>"isTouchingWaterOrRain"</code>: The Pokémon must be touching water or rain. Again, not necessarily underwater.
"maxSecondsBetweenOccurrences": Float = 30 // What do you think
* <code>"isSubmergedInWater"</code>: The Pokémon must be underwater. The red line on the hitbox must be below the surface.
"animations": List<Animation> = [] // The list of animations to play (together) when this quirk runs
* <code>"isStandingOnRedSand"</code>: The Pokémon must be standing on red sand.
"name": String // The name of the quirk
* <code>"isStandingOnSand"</code>: The Pokémon must be standing on sand
* <code>"isStandingOnSandOrRedSand"</code>: The Pokémon must be standing on either sand or red sand.
* <code>"isDusk"</code>: It must be "Dusk" time in the world, or roughly at sunset.
</br>
</br>
Below is an example of a modified quirk animation. What this will do is eventually make charizard play the blink animation 5 times in a row. Then after the animation plays, an 8-20 second timer begins to play this quirk again. The quirk timer starts after the quirk animations end.</br>
Below is an example of 2 poses using the <code>"STAND"</code> pose type and <code>Conditions</code> to separate the battle-idle animation from the ground idle animation:
* In these scenarios, you want one pose to have the condition set to true, and any other pose that shares the same pose type to have the condition set to false.
    "battle-standing": {
      "poseTypes": ["STAND"],
      "isBattle": true,
      "animations": [
        "q.bedrock('blastoise', 'battle_idle')"
      ]
    },
    "standing": {
      "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
      "isBattle": false,
      "animations": [
        "q.bedrock('blastoise', 'ground_idle')"
      ]
    },


"<abbr title="This property allows you to play other animations over the main list of animations for this pose. The most common type of quirk animations are blinks, but you can apply any animation you wish as a quirk.">quirks</abbr>": [
        {
          "<abbr title="Here we are defining the name of this quirk">name</abbr>": "<abbr title="The name of this quirk will simply be called 'blink'.">blink</abbr>",
          "<abbr title="The number of times the animation should play for the quirk. By default, this value is 1.">loopTimes</abbr>": <abbr title="For this example, we will let the blink animation play 5 times. After the blink plays 5 times, it will then start a timer before it can play again.">5</abbr>,
          "<abbr title="The decimal-friendly number of seconds that is the minimum between the quirk playing once and it playing a second time. Default value is 8.">minSecondsBetweenOccurrences</abbr>": <abbr title="After 8 seconds, there is a chance that this quirk animation will play.">8</abbr>,
          "<abbr title="The decimal-friendly number of seconds that is the maximum between the quirk playing once and it playing a second time. Default value is 30.">maxSecondsBetweenOccurrences</abbr>": <abbr title="It will take 20 seconds at most for the quirk animation to play again.">20</abbr>,
          "<abbr title="Here, you are going to list the animation that you want to play as a quirk. Given the data of the previous lines, this animation will play 5 times every 8-20 seconds.">animations</abbr>": ["<abbr title="This points towards charizard's blink animation">bedrock(charizard, blink)</abbr>"]
          }
</br>
</br>
 
=== Transformed Parts ===
==== Transformed Parts ====
This function allows you to transform parts of the model when the Pokémon is in a certain pose. You can change the location, rotation, and visibility of bones for each pose. This allows you to make some slight adjustments to an in-game animation without having to edit the animation itself. While there aren't many examples of this function, it's most common use is to hide model parts when a Pokémon is not in its battle idle. This is the case with Rillaboom and its drum.
This function allows you to transform parts of the model when the Pokémon is in a certain pose. You can change the location, rotation, and visibility of bones for each pose. This allows you to make some slight adjustments to an in-game animation without having to edit the animation itself. While there aren't many examples of this function, it's most common use is to hide model parts when a Pokémon is not in its battle idle. This is the case with Rillaboom and its drum.


Line 160: Line 156:
</br>
</br>


==== Animation Conditions ====
=== Look Animation(s) ===
This function allows you to have more control over when an animation is allowed to play. The current conditions we can use are for battle and for touching water. This can be used to make animations specific to being in battle or in water. You can also mix and match the battle and water conditions if you really want more specific animations. This can result in having a ground idle, ground battle idle, water idle, and water battle idle!
The new Poser allows you to manipulate the look animation in a number of ways. Creators can now list multiple look animations where each one can define its own head bone and edit some of the properties of the look animation. Changing the properties allows you to manipulate the sight cone of the Pokémon if desired. This can help prevent some odd clipping or extend/shorten how far it can look up and down or left and right. Having multiple look animations allows for Pokémon with multiple heads to turn each head individually. You could even assign the torso and head bones to look at the same time while limiting the range for each. This can be helpful for Pokémon with little to no neck and they have to look with their body more than their head. </br>
</br>
The <code>q.look()</code> function is the format of this new look animation. When using this function, all the properties must be listed in a specific order and the name of the bone must be in single quotes. (the apostrophe key) </br>
</br>
* Please refer to the image below to visualize pitch, yaw, and the origin.
* Pressing F3+B in game can show the hitboxes. That blue line shows where the pokemon is looking at and if its looking at nothing, it is centered at 0 pitch and yaw. You can call this the origin.</br>
[[File:Sight_Cones.png|800px|caption|The default sight cone visualized.]]
</br>
 
 
The properties of <code>q.look</code> must be in the following order:
* With the exception of the bone name, these are also the default values for each property
# Bone name: <code>'head_ai'</code> - The name of the bone on the model which will perform the look animation
# Pitch Multiplier - <code>1</code> - Multiplies the amount of pitch gained by this amount. Can use -1 to invert the pitch!
# Yaw Multiplier - <code>1</code> - Multiplies the amount of yaw gained by this amount. Can use -1 to invert the yaw!
# Max Pitch - <code>70</code> - How many degrees the Pokémon can look down from origin.
# Min Pitch - <code>-45</code> - How many degrees the Pokémon can look up from origin.
# Max Yaw - <code>45</code> - How many degrees the Pokémon can look right from origin.
# Min Yaw - <code>-45</code> - How many degrees the Pokémon can look left from origin.
</br>
A look animation using the previously listed values would look something like this inside of the standing pose:
    "standing": {
      "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
      "animations": [
        "q.look('head_ai', 1, 1, 70, -45, 45, -45)",
        "q.bedrock('riolu', 'ground_idle')"
      ],
</br>
If you want to use the default values and keep it short, you can also write it like this:
    "standing": {
      "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
      "animations": [
        "q.look('head_ai')",
        "q.bedrock('riolu', 'ground_idle')"
      ],
</br>
If you want to list multiple head bones, you can write the q.look function multiple times:
    "standing": {
      "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
      "animations": [
        "q.look('head_ai')",
        "q.look('torso')",
        "q.bedrock('riolu', 'ground_idle')"
      ],
</br>
 
=== Quirks ===
Quirk animations are stateful animations (for now) that you can have play over the main animation for a pose. The new poser format introduced a shorthand method to writing in your quirk animations in the <code>q.bedrock_quirk()</code> format. The [[Poser#Quirks | old Poser method for quirks]] can be condensed into one line using this function. When using this function, all the properties must be listed in specific order, placed inside of single quotes (the apostrophe key) unless its a number, and separated by commas.
 
If your poser and animations are made just right, then you can have a single Pokémon running so many quirk animations at once. Remember that you can combine any of the following quirk examples if you have lots of animations like Blastoise.</br>
</br>
The properties of <code>q.bedrock_quirk</code> must be in the following order:
# Animation Group: <code>'blastoise'</code> - the name of the Pokémon
# Animation Name(s): <code>'quirk_ground_idle'</code> - the name of the animation. Supports a pool of animations using the <code>q.array</code> function
# Minimum seconds between occurences: <code>20</code> - The decimal-friendly number of seconds that is the minimum between the quirk playing once and it playing a second time.
# Maximum seconds between occurences: <code>60</code> - What do you think?
# Loop times: <code>1</code> - The number of times the animation should play for the quirk
</br>
The previously listed properties would get written as a quirk like so:
      "quirks": [
        "q.bedrock_quirk('blastoise', 'quirk_ground_idle', 20, 60, 1)"
      ]
</br>
You don't need to include all the properties if you just want to use the default values of 8-30 seconds between quirks. You can write it like so to use the default values and keep it short:
      "quirks": [
        "q.bedrock_quirk('blastoise', 'blink')"
      ]
</br>
==== q.array ====
You can replace your animation name with the <code>q.array()</code> function to have the quirk pick from a list of animations to play. This can be helpful if you have a lot of quirks that you want to play under one pose. You simply need to put the list of animations inside of the parenthesis, include each animation name inside of single quotes, and separate them with a comma.
* Example: <code>q.array('quirk_battle_idle', 'quirk_battle_idle2')</code>
** These quirks are for Blastoise adjusting each of its cannons. Writing it this way lets Blastoise adjust only one cannon at a time, but it's a random cannon each time.
 
So if you were to make that into a quirk, it would look like this:
      "quirks": [
        "q.bedrock_quirk('blastoise', q.array('quirk_battle_idle', 'quirk_battle_idle2'), 30, 60, 1)"
      ]
</br>


This function is mostly for helping you organize your animations for each pose. Setting a condition to true will only allow the animation to play when this condition is met. Setting it to false will prevent the animation from being played when this condition is met. This allows you to set 2 or more animations per <code>poseType</code>. This basic fundamental is what allows us to have battle animations that can only play in battle!
=== Placeholder Animations ===
The new poser allows creators to use the placeholder animations which the JSON poser could not access before. These placeholder animations are based on the body type or limb features of the Pokémon. Each placeholder features a very simple animation that swings a limb back and forth. For now, you'll have to figure out how to configure these yourself lol</br>


Transformed parts work really well with this function! Combining these 2 functions is what allows Rillaboom to use its drum only when in battle. You can allow certain model parts to appear visible only when these conditions are met. Keep these functions in mind the next time you make a custom Pokémon model. You can create livelier animations using this system!
Here is a list of all the Placeholder animations:
* <code>[https://gitlab.com/cable-mc/cobblemon/-/blob/main/common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt#L172 "q.quadruped_walk()"]</code> - A basic walk animation for Pokémon with 4 legs
* <code>[https://gitlab.com/cable-mc/cobblemon/-/blob/main/common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt#L192 "q.biped_walk()"]</code> - A basic walking animation for Pokémon who stand on 2 legs.
* <code>[https://gitlab.com/cable-mc/cobblemon/-/blob/main/common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt#L208 "q.bimanual_swing()"]</code> - A basic arm swinging animation for Pokémon with 2 arms that usually stand on 2 legs.
* <code>[https://gitlab.com/cable-mc/cobblemon/-/blob/main/common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PoseableEntityModel.kt#L224 "q.sine_wing_flap()"]</code> - A basic wing flap animation for a pair of wings on a Pokémon.  


Below is an example of these animation conditions being used. In this example, the battle idle will only play when charizard is in battle, but never while charizard is in water.
</br>
</br>


    "<abbr title="Here we are defining a list of our poses.">poses</abbr>": {
== Poser File Breakdown ==
      "<abbr title="The name of your pose. In this case, its called 'battle-idle'. Here, we will list animations that will play when the Pokémon is in battle.">battle-idle</abbr>": {
Soon™
        "<abbr title="Here we are defining the name of the pose.">poseName</abbr>": "<abbr title="The name of this pose is 'battle-idle'">battle-idle</abbr>",
        "<abbr title="This is transition time between animations measured in minecraft ticks. You probably won't need to mess with this.>transformTicks</abbr>": 10,
        "<abbr title="Here, we are telling the game when this animation will take place.">poseTypes</abbr>": [<abbr title="One of the pose types that will use the following animation. 'STAND - when stationary on the ground.' In the next line, we will define that the following animation will only work in battle">"STAND"</abbr>],
        "<abbr title="This property controls whether the animation will play during battle or not.">isBattle</abbr>": <abbr title="Setting it to true will make the following animation play only while the Pokémon is idle while it's also in battle!">true</abbr>,
        "<abbr title="This property controls whether the animation will play while the Pokémon is in water or not.">isTouchingWater</abbr>": <abbr title="Setting it to false will prevent the following animation from playing whenever the Pokémon touches water, but only while it's also in battle! So if this Pokémon starts battle in water, it is not allowed to use this pose and its assigned animation.">false</abbr>,
        "<abbr title="Here you will list which animations will play during these poses.">animations</abbr>": ["<abbr title="The animation you are telling it to use when your Pokémon is standing, while in battle, but not touching water.">bedrock(charizard, battle_idle)</abbr>"]
      },
</br>
</br>


=== Poser File Example ===
== Poser File Example ==
Instead of making <code>poser</code> files from scratch each time, you can use other custom Pokémon posers as a template. Just be aware of the animations each Pokémon has. Also be aware that some Pokémon don't use a <code>head bone</code>.
Instead of making <code>poser</code> files from scratch each time, you can use other custom Pokémon posers as a template. Just be aware of the animations each Pokémon has. Also be aware that not all Pokémon have a bone called <code>head</code>.


Here is an example of a poser file for a custom <code>starly</code> that includes all currently implemented poses and their appropriate animations.
Here is an example of a poser file for a custom <code>riolu</code> that includes all currently implemented poses and their appropriate animations.
* Riolu obviously can't fly. This is just an example as no Pokémon can do everything currently.
* Blink animations are not applied to the sleep pose. This is because you don't blink when you sleep!
* Blink animations are not applied to the sleep pose. This is because you don't blink when you sleep!
  {
  {
   "portraitScale": 1.3,
   "portraitScale": 2.3,
   "portraitTranslation": [-0.7, 2.1, 0],
   "portraitTranslation": [-0.1, 0.58, 0],
   "profileScale": 0.45,
   "profileScale": 0.75,
   "profileTranslation": [-0.1, 1.0, 0],
   "profileTranslation": [0, 0.68, 0],
   "animations": {
   "animations": {
     "faint": "q.bedrock_primary('blastoise', 'faint', q.curve('one'))",
     "faint": "q.bedrock_primary('riolu', 'faint', q.curve('one'))",
     "cry": "q.bedrock_stateful('blastoise', 'cry')",
     "cry": "q.bedrock_stateful('riolu', 'cry')",
     "recoil": "q.bedrock_stateful('blastoise', 'recoil')",
     "recoil": "q.bedrock_stateful('riolu', 'recoil')",
     "physical": "q.bedrock_primary('blastoise', 'physical', q.curve('symmetrical_wide'))",
     "physical": "q.bedrock_primary('riolu', 'physical', q.curve('symmetrical_wide'))",
     "special": "q.bedrock_primary('blastoise', 'special', q.curve('symmetrical_wide'))",
     "special": "q.bedrock_primary('riolu', 'special', q.curve('symmetrical_wide'))",
     "status": "q.bedrock_primary('blastoise', 'status', q.curve('symmetrical_wide'))"
     "status": "q.bedrock_primary('riolu', 'status', q.curve('symmetrical_wide'))"
   },
   },
   "poses": {
   "poses": {
Line 204: Line 275:
       "isBattle": true,
       "isBattle": true,
       "animations": [
       "animations": [
         "q.look('head_ai')",
         "q.look('head')",
         "q.bedrock('blastoise', 'battle_idle')"
         "q.bedrock('riolu', 'battle_idle')"
       ],
       ],
       "quirks": [
       "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
        "q.bedrock_quirk('blastoise', 'blink')",
        "q.bedrock_quirk('blastoise', q.array('quirk_battle_idle', 'quirk_battle_idle2'), 30, 60, 1)"
      ]
     },
     },
     "standing": {
     "standing": {
Line 216: Line 284:
       "isBattle": false,
       "isBattle": false,
       "animations": [
       "animations": [
         "q.look('head_ai')",
         "q.look('head')",
         "q.bedrock('blastoise', 'ground_idle')"
         "q.bedrock('riolu', 'ground_idle')"
       ],
       ],
       "quirks": [
       "quirks": [
         "q.bedrock_quirk('blastoise', 'blink')",
         "q.bedrock_quirk('riolu', 'blink')"
        "q.bedrock_quirk('blastoise', 'quirk_ground_idle', 20, 60, 1)"
       ]
       ]
     },
     },
Line 227: Line 294:
       "poseTypes": ["WALK"],
       "poseTypes": ["WALK"],
       "animations": [
       "animations": [
         "q.look('head_ai')",
         "q.look('head')",
         "q.bedrock('blastoise', 'ground_walk')"
         "q.bedrock('riolu', 'ground_walk')"
      ],
      "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
    },
    "hover": {
      "poseTypes": ["HOVER"],
      "animations": [
        "q.look('head')",
        "q.bedrock('riolu', 'air_idle')"
      ],
      "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
    },
    "fly": {
      "poseTypes": ["FLY"],
      "animations": [
        "q.look('head')",
        "q.bedrock('riolu', 'air_fly')"
       ],
       ],
       "quirks": ["q.bedrock_quirk('blastoise', 'blink')"]
       "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
     },
     },
     "float": {
     "float": {
       "poseTypes": ["FLOAT"],
       "poseTypes": ["FLOAT"],
       "animations": [
       "animations": [
         "q.look('head_ai')",
         "q.look('head')",
         "q.bedrock('blastoise', 'water_idle')"
         "q.bedrock('riolu', 'water_idle')"
       ],
       ],
       "quirks": ["q.bedrock_quirk('blastoise', 'blink')"]
       "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
     },
     },
     "swim": {
     "swim": {
       "poseTypes": ["SWIM"],
       "poseTypes": ["SWIM"],
       "animations": [
       "animations": [
         "q.look('head_ai')",
         "q.look('head')",
         "q.bedrock('blastoise', 'water_swim')"
         "q.bedrock('riolu', 'water_swim')"
       ],
       ],
       "quirks": ["q.bedrock_quirk('blastoise', 'blink')"]
       "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
     },
     },
     "sleep": {
     "sleep": {
       "poseTypes": ["SLEEP"],
       "poseTypes": ["SLEEP"],
       "animations": ["q.bedrock('blastoise', 'sleep')"]
       "animations": ["q.bedrock('riolu', 'sleep')"]
    },
    "shoulder_left": {
      "poseTypes": ["SHOULDER_LEFT"],
      "animations": [
        "q.look('head')",
        "q.bedrock('riolu', 'shoulder_left')"
      ],
      "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
    },
    "shoulder_right": {
      "poseTypes": ["SHOULDER_RIGHT"],
      "animations": [
        "q.look('head')",
        "q.bedrock('riolu', 'shoulder_right')"
      ],
      "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
     }
     }
   }
   }

Latest revision as of 12:27, 19 May 2024

Under construction. Dont look or else!

Preface

The new poser JSON controls all the animations of a Pokémon just as the old Poser did. It contains the same information for when the Pokémon will perform certain animations, but has received many requested upgrades. Some of these upgrades include multi-bone look animations, support for move animations, and even selecting from a pool of animations for quirks. Functionality of the new Poser will always be maintained and should let addon creators have the same options as the hard-coded Kotlin Posers.

Poser Properties

Before breaking down each section of the new Poser file, let's take a look at all its different properties and how to use them. This section includes all of the different functions of the poser, any configurable options for said function, and how to write each function. You will notice that the poser now includes something in the format of q.<function>. These are molang functions which allow you to do many new things. The q stands for query and its just part of the standard format for these new functions. Some functions can even go inside of other functions. It's not terribly complicated once you read what each one does. They allow addon creators to do many things they couldn't before!

Poses & Animations

There's a handful of Pose types and Animation types that you can make animations for. Poses are the states a Pokémon is in, like idle or moving. Poses are for assigning animations like your ground idles, ground walks, water idles, etc. The animation types are the different events in battles that you can assign animations to for each Pokémon. Animation types would include your faints, cries, and attack animations. Below is a list of currently available Animation types and Poses to choose from.

Animations

  • faint: animation.<pokemon>.faint - The animation that plays when a Pokémon faints.
  • cry: animation.<pokemon>.cry - The animation that plays when a Pokémon is called out or when it starts battle.
  • recoil: animation.<pokemon>.recoil - The animation that plays when a Pokémon takes damage in battle.
  • physical: animation.<pokemon>.physical - The animation that plays when a Pokémon uses a physical move in battle.
  • special: animation.<pokemon>.special - The animation that plays when a Pokémon uses a special move in battle.
  • status: animation.<pokemon>.status - The animation that plays when a pokemon uses a status move in battle.


Poses

  • "STAND": animation.<pokemon>.ground_idle - The animation that plays when a Pokémon is idle on land.
    • This pose type is also used for battle-idles: animation.<pokemon>.battle_idle
  • "PORTRAIT": animation.<pokemon>.portrait - The animation that plays in the Party Overlay, or left hand party GUI
    • This pose often uses the ground_idle instead of a dedicated animation.
  • "PROFILE": animation.<pokemon>.profile - The animation that plays in the Party Menu, or when you press M.
    • This pose often uses the ground_idle instead of a dedicated animation.
  • "WALK": animation.<pokemon>.ground_walk - The animation that plays when a Pokémon is moving on land
  • "HOVER": animation.<pokemon>.air_idle - The animation that plays when a Pokémon is idle in the air.
  • "FLY": animation.<pokemon>.air_fly - The animation that plays when a Pokémon is moving in the air.
  • "FLOAT": animation.<pokemon>.water_idle - The animation that plays when a Pokémon is idle in or on water.
  • "SWIM": animation.<pokemon>.water_swim - The animation that plays when a Pokémon is moving in or on water.
  • "SLEEP": animation.<pokemon>.sleep - The animation that plays when a Pokémon is asleep. Usually on land.
  • "SHOULDER_LEFT": animation.<pokemon>.shoulder_left - The animation that plays when the Pokémon is on the player's left shoulder.
  • "SHOULDER_RIGHT": animation.<pokemon>.shoulder_right - The animation that plays when the Pokémon is on the player's right shoulder.


q.bedrock_stateful

The function q.bedrock_stateful() allows you to assign a stateful animation to an animation type. Stateful animations are meant to animate just a few bones of the Pokémon and get overlaid on the current pose. An example would be cries only animating the mouth or head of the Pokémon. A stateful animation won't take control of the whole model to play its animation.

Here is an example of the 2 stateful animations, cry and recoil, in the poser:

   "cry": "q.bedrock_stateful('blastoise', 'cry')",
   "recoil": "q.bedrock_stateful('blastoise', 'recoil')",


q.bedrock_primary

The function q.bedrock_primary() allows you to assign a primary animation to an animation type. Primary animations are meant to take control of the entire model to play its animation and will clear any previous animations it was doing. An example would be a Pokémon's physical attack animation. When a Pokémon uses a physical move, it should clear the battle idle animation and play its physical animation instead. These animations often move the whole body and many of its limbs. When the physical animation is done, it returns control of the model to the battle idle after the physical animation has finished and should play a short transition animation in between.

Since Primary animations behave in a similar way to swapping poses, they can use special transition animation types via the q.curve property written within its sub properties. These provide different types of smoothness to the interpolation and will be explained in the next section.

Below is an example of the 4 primary animation in the poser:

   "faint": "q.bedrock_primary('blastoise', 'faint', q.curve('one'))",
   "physical": "q.bedrock_primary('blastoise', 'physical', q.curve('symmetrical_wide'))",
   "special": "q.bedrock_primary('blastoise', 'special', q.curve('symmetrical_wide'))",
   "status": "q.bedrock_primary('blastoise', 'status', q.curve('symmetrical_wide'))"


q.curve

The function q.curve() is a sub function for q.bedrock_primary() which allows the animation to interpolate back into the main pose. This allows the transition between animations to behave similarly to linear keyframes and smooth keyframes when animating.

The q.curve function comes with 3 options for now which are:

  • one: Does not interpolate at all. Just jumps from one animation to the next. Preferred for faint animations.
  • symmetric: Interpolates in a similar fashion to 2 smooth keyframes in blockbench. Not preferable, but is an option.
  • symmetrical_wide: Interpolates in a similar fashion to 2 smooth keyframes in blockbench, but with a wider margin. The preferred choice when transitioning from moves.

Below is an example of the 2 main q.curve types:

   "faint": "q.bedrock_primary('blastoise', 'faint', q.curve('one'))",
   "physical": "q.bedrock_primary('blastoise', 'physical', q.curve('symmetrical_wide'))",


q.bedrock

The q.bedrock() function is the familiar animation format from the old poser which got converted into a molang function. It's the same thing as before, just in a new look. You are still just listing your Pokémon and then the animation in the parenthesis. This function is mainly used to assign poses their animations. These animations are meant to be overwritten by Primary or Stateful animations whenever convenient.
Below is an example of the q.bedrock function assigning a walk animation to the "WALK" pose type:

   "walking": {
     "poseTypes": ["WALK"],
     "animations": [
       "q.bedrock('blastoise', 'ground_walk')"
     ]
   },


Portraits and Profiles & Scale and Translation

Portrait and Profile are the poses that are used when rendering any Pokémon in a GUI or Menu. Portrait is used for the left hand party screen, or Party Overlay, and Profile is used for the Party Menu. The poser file assigns some Scale and Translation values to these poses which control the camera location for rendering the Pokémon. There is a dev tool that you can enable in the Config which allows you to use some customizable keys to move the camera around the Pokémon in these menus. This tool will print the Scale and Translation values when the associated hotkey is pressed.


Translation values control the location of the camera for the Portrait or Profile. Translation is a set of 3 values which represent xyz coordinates. You will mainly be changing the first 2 values, or the x and y axis values. X for left and right, and Y for up and down. The Z value is rarely used, but is important for really big models that are not being fully rendered in the menus. It often needs a larger Z value.

Scale values control the amount of zoom for the Portrait or Profile. A value less than one should make it zoom out and a value greater than one will zoom in. Sometimes with larger models, the camera cannot render the whole Pokémon no matter how far you zoom out. The back side of the Pokémon may not be rendered. This means you need to increase the Translation z value.


Below is a short breakdown of the previously mentioned properties:

   "portraitScale": 1.65,
   "portraitTranslation": [0, -0.6, 0],
   "profileScale": 1,
   "profileTranslation": [0, 0.15, 0],


Conditions

You can expand the amount of animations a Pokémon can have and when they should be played by using conditions. Conditions are what allow for battle animations despite the standing and battle-idle poses both using the "STAND" pose type. Typically, if you want different animations using the same pose types, then you must set one pose's condition to true, and the other pose's matching condition to false. You can mix and match these conditions to make something like an animation that only plays in battle, if it is raining while the sun is setting.


List of Currently Implemented Conditions:

  • "isBattle": The Pokémon must be in a battle.
  • "isTouchingWater": The Pokémon must be touching water. Not necessarily underwater.
  • "isTouchingWaterOrRain": The Pokémon must be touching water or rain. Again, not necessarily underwater.
  • "isSubmergedInWater": The Pokémon must be underwater. The red line on the hitbox must be below the surface.
  • "isStandingOnRedSand": The Pokémon must be standing on red sand.
  • "isStandingOnSand": The Pokémon must be standing on sand
  • "isStandingOnSandOrRedSand": The Pokémon must be standing on either sand or red sand.
  • "isDusk": It must be "Dusk" time in the world, or roughly at sunset.


Below is an example of 2 poses using the "STAND" pose type and Conditions to separate the battle-idle animation from the ground idle animation:

  • In these scenarios, you want one pose to have the condition set to true, and any other pose that shares the same pose type to have the condition set to false.
   "battle-standing": {
     "poseTypes": ["STAND"],
     "isBattle": true,
     "animations": [
       "q.bedrock('blastoise', 'battle_idle')"
     ]
   },
   "standing": {
     "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
     "isBattle": false,
     "animations": [
       "q.bedrock('blastoise', 'ground_idle')"
     ]
   },


Transformed Parts

This function allows you to transform parts of the model when the Pokémon is in a certain pose. You can change the location, rotation, and visibility of bones for each pose. This allows you to make some slight adjustments to an in-game animation without having to edit the animation itself. While there aren't many examples of this function, it's most common use is to hide model parts when a Pokémon is not in its battle idle. This is the case with Rillaboom and its drum.

A great use for location and rotation transformation is to adjust shoulder animations. You don't have to account for the model location on the player shoulder when making the animation. If it doesn't line up in the game, you can move the whole model using this function.

The visibility transformation allows you to hide a specific bone in the model when the Pokémon is currently in a pose. This can be used to hide certain bones if needed. This allows you to do things like making Rillaboom use its drum for its battle-idle. It also allows Typhlosion to have its flames ignited only during battle. Something to keep in mind is that if you want a bone to be visible only during battle, then you must set this bone as invisible for all other poses. This is why transformedParts is written under every pose in the poser file breakdown.

Below is an example of all the transformed part properties being used. This is mostly a demonstration of your options when using this function. If this example was applied in game, Charizard's wings would be detached from its body, but only the left wing would be invisible. Realistically, you would never want to do something like that.

"transformedParts": [
         {
           "part": "wing_right",
           "position": [10, 0, 0],
           "rotation": [0, 0, 0],
           "isVisible": true
         },
         {
           "part": "wing_left",
           "position": [-10, 0, 0],
           "rotationrotation": [0, 0, 0],
           "isVisible": false
         }
        ]


Look Animation(s)

The new Poser allows you to manipulate the look animation in a number of ways. Creators can now list multiple look animations where each one can define its own head bone and edit some of the properties of the look animation. Changing the properties allows you to manipulate the sight cone of the Pokémon if desired. This can help prevent some odd clipping or extend/shorten how far it can look up and down or left and right. Having multiple look animations allows for Pokémon with multiple heads to turn each head individually. You could even assign the torso and head bones to look at the same time while limiting the range for each. This can be helpful for Pokémon with little to no neck and they have to look with their body more than their head.

The q.look() function is the format of this new look animation. When using this function, all the properties must be listed in a specific order and the name of the bone must be in single quotes. (the apostrophe key)

  • Please refer to the image below to visualize pitch, yaw, and the origin.
  • Pressing F3+B in game can show the hitboxes. That blue line shows where the pokemon is looking at and if its looking at nothing, it is centered at 0 pitch and yaw. You can call this the origin.

The default sight cone visualized.


The properties of q.look must be in the following order:

  • With the exception of the bone name, these are also the default values for each property
  1. Bone name: 'head_ai' - The name of the bone on the model which will perform the look animation
  2. Pitch Multiplier - 1 - Multiplies the amount of pitch gained by this amount. Can use -1 to invert the pitch!
  3. Yaw Multiplier - 1 - Multiplies the amount of yaw gained by this amount. Can use -1 to invert the yaw!
  4. Max Pitch - 70 - How many degrees the Pokémon can look down from origin.
  5. Min Pitch - -45 - How many degrees the Pokémon can look up from origin.
  6. Max Yaw - 45 - How many degrees the Pokémon can look right from origin.
  7. Min Yaw - -45 - How many degrees the Pokémon can look left from origin.


A look animation using the previously listed values would look something like this inside of the standing pose:

   "standing": {
     "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
     "animations": [
       "q.look('head_ai', 1, 1, 70, -45, 45, -45)",
       "q.bedrock('riolu', 'ground_idle')"
     ],


If you want to use the default values and keep it short, you can also write it like this:

   "standing": {
     "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
     "animations": [
       "q.look('head_ai')",
       "q.bedrock('riolu', 'ground_idle')"
     ],


If you want to list multiple head bones, you can write the q.look function multiple times:

   "standing": {
     "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
     "animations": [
       "q.look('head_ai')",
       "q.look('torso')",
       "q.bedrock('riolu', 'ground_idle')"
     ],


Quirks

Quirk animations are stateful animations (for now) that you can have play over the main animation for a pose. The new poser format introduced a shorthand method to writing in your quirk animations in the q.bedrock_quirk() format. The old Poser method for quirks can be condensed into one line using this function. When using this function, all the properties must be listed in specific order, placed inside of single quotes (the apostrophe key) unless its a number, and separated by commas.

If your poser and animations are made just right, then you can have a single Pokémon running so many quirk animations at once. Remember that you can combine any of the following quirk examples if you have lots of animations like Blastoise.

The properties of q.bedrock_quirk must be in the following order:

  1. Animation Group: 'blastoise' - the name of the Pokémon
  2. Animation Name(s): 'quirk_ground_idle' - the name of the animation. Supports a pool of animations using the q.array function
  3. Minimum seconds between occurences: 20 - The decimal-friendly number of seconds that is the minimum between the quirk playing once and it playing a second time.
  4. Maximum seconds between occurences: 60 - What do you think?
  5. Loop times: 1 - The number of times the animation should play for the quirk


The previously listed properties would get written as a quirk like so:

     "quirks": [
       "q.bedrock_quirk('blastoise', 'quirk_ground_idle', 20, 60, 1)"
     ]


You don't need to include all the properties if you just want to use the default values of 8-30 seconds between quirks. You can write it like so to use the default values and keep it short:

     "quirks": [
       "q.bedrock_quirk('blastoise', 'blink')"
     ]


q.array

You can replace your animation name with the q.array() function to have the quirk pick from a list of animations to play. This can be helpful if you have a lot of quirks that you want to play under one pose. You simply need to put the list of animations inside of the parenthesis, include each animation name inside of single quotes, and separate them with a comma.

  • Example: q.array('quirk_battle_idle', 'quirk_battle_idle2')
    • These quirks are for Blastoise adjusting each of its cannons. Writing it this way lets Blastoise adjust only one cannon at a time, but it's a random cannon each time.

So if you were to make that into a quirk, it would look like this:

     "quirks": [
       "q.bedrock_quirk('blastoise', q.array('quirk_battle_idle', 'quirk_battle_idle2'), 30, 60, 1)"
     ]


Placeholder Animations

The new poser allows creators to use the placeholder animations which the JSON poser could not access before. These placeholder animations are based on the body type or limb features of the Pokémon. Each placeholder features a very simple animation that swings a limb back and forth. For now, you'll have to figure out how to configure these yourself lol

Here is a list of all the Placeholder animations:


Poser File Breakdown

Soon™

Poser File Example

Instead of making poser files from scratch each time, you can use other custom Pokémon posers as a template. Just be aware of the animations each Pokémon has. Also be aware that not all Pokémon have a bone called head.

Here is an example of a poser file for a custom riolu that includes all currently implemented poses and their appropriate animations.

  • Riolu obviously can't fly. This is just an example as no Pokémon can do everything currently.
  • Blink animations are not applied to the sleep pose. This is because you don't blink when you sleep!
{
 "portraitScale": 2.3,
 "portraitTranslation": [-0.1, 0.58, 0],
 "profileScale": 0.75,
 "profileTranslation": [0, 0.68, 0],
 "animations": {
   "faint": "q.bedrock_primary('riolu', 'faint', q.curve('one'))",
   "cry": "q.bedrock_stateful('riolu', 'cry')",
   "recoil": "q.bedrock_stateful('riolu', 'recoil')",
   "physical": "q.bedrock_primary('riolu', 'physical', q.curve('symmetrical_wide'))",
   "special": "q.bedrock_primary('riolu', 'special', q.curve('symmetrical_wide'))",
   "status": "q.bedrock_primary('riolu', 'status', q.curve('symmetrical_wide'))"
 },
 "poses": {
   "battle-standing": {
     "poseTypes": ["STAND"],
     "isBattle": true,
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'battle_idle')"
     ],
     "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
   },
   "standing": {
     "poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
     "isBattle": false,
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'ground_idle')"
     ],
     "quirks": [
       "q.bedrock_quirk('riolu', 'blink')"
     ]
   },
   "walking": {
     "poseTypes": ["WALK"],
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'ground_walk')"
     ],
     "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
   },
   "hover": {
     "poseTypes": ["HOVER"],
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'air_idle')"
     ],
     "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
   },
   "fly": {
     "poseTypes": ["FLY"],
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'air_fly')"
     ],
     "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
   },
   "float": {
     "poseTypes": ["FLOAT"],
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'water_idle')"
     ],
     "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
   },
   "swim": {
     "poseTypes": ["SWIM"],
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'water_swim')"
     ],
     "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
   },
   "sleep": {
     "poseTypes": ["SLEEP"],
     "animations": ["q.bedrock('riolu', 'sleep')"]
   },
   "shoulder_left": {
     "poseTypes": ["SHOULDER_LEFT"],
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'shoulder_left')"
     ],
     "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
   },
   "shoulder_right": {
     "poseTypes": ["SHOULDER_RIGHT"],
     "animations": [
       "q.look('head')",
       "q.bedrock('riolu', 'shoulder_right')"
     ],
     "quirks": ["q.bedrock_quirk('riolu', 'blink')"]
   }
 }
}