Note on Knights Province animations and how they got better last week

Knights Province needs a lot of animations. They are essential to making the games’ world feel alive. Here’s how they work and how they just got better.

Animations start with a skeleton rig. Rig is a description of how character skeleton bones are located and which of the characters parts they affect. Typical character rig in Knights Province consists of ~20 bones. 20 is a good compromise between animation visual quality (more is better), animation cost (less is cheaper) and game’s performance (less is faster). Typical rig looks like this:


After the rig comes the animation. Typical animations are made by an artist in 3D modelling app (Blender, Maya, etc.) with keyframes. Keyframes are bones positions at specified times. For example a simple walk animation has 2 keyframes for legs movements, spine, arms and head (this is much alike “penguin” walk animation was made).


Once animation is made it gets exported into format compatible with the game. Simplest way is to record each animation frame (each bones position and orientation) at fixed frame-rate (typically 30). This way, 3 seconds of exported animation look like a list of 90 frames, each describing each bone’s position and rotation in the rig:


At 30 frames of animation per second it looks good enough.

When in game, every house and character has some state. This state links to an animation (e.g. work state of a Stonecutter links to a stonecutting animation). The game then knows that it needs to render a Stonecutter using the stonecutting animation and choose a specific frame.

Simple approach of choosing an animation frame was to see when the state has started, calculate state duration to the moment, then convert this into an animation position (picking closest frame). E.g. Stonecutter has been cutting the stone for 2.3 seconds:

Round(2.3 * 30 / animation_framecount)

Interpolating is very similar to the approach above – it takes two closest frames and “blends” them together proportionally. For this we take pairs of bones from each frame and linearly interpolate between them, obtaining new bone position/orientation.

Best example of interpolation is a Mill:


Mill blades make a full revolution in 6 seconds. Before interpolation that would require 6*30 = 180 frames of animation (that would still look choppy in high fps, cos every frame is strictly 2 degrees apart). Now, with interpolation we can do just 2(!) frames. First frame at 0 rotation, second – at 360 degrees (perfectly looped, since 0 = 360). Now every time the blades are rendered their rotation gets interpolated between 0 and 360 degrees, giving us the best smooth animation!

Of course interpolation has some caveats as well. Now we need to be careful about animations, so that bones rotations do not reset to 0 when passing 360 degrees. Otherwise interpolating between 359 on one frame and 1 on other would give 180 instead of 0.

This entry was posted in How things work. Bookmark the permalink.

6 Responses to Note on Knights Province animations and how they got better last week

  1. Czempion_PL says:

    Thanks Krom for your time which you spend in developing this game is great and will be even better 🙂

  2. hecu says:

    I’m want to play new version ASAP. Do you know when can we expect alpha 7 ?

    • Krom says:

      For that I need to finally sit down, play the game like a player and write up all the things that need to fit into Alpha 7, then cross those that can wait till Alpha 8, and then do the rest (planning a post about that).
      Alpha 7 Preview will be made then and supposedly a week after – Alpha 7.
      When that is going to happen – I can not predict.

      I’m quite happy with how the game looks like, there are not many things left in need of urgent fixing/improvement (will make a post about that soon too).

  3. Flasat says:

    Thanks for the update Krom and keep up the really good work

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.