Engine Tutorial - 03 - A Simple Animation System


So far, our paperdoll was handcrafted, and our CSS was handwritten. It's time to change that and get into generating CSS!

To do so, I've prepared a re-usable state file. I'll demonstrate the use of it later, for now, let's focus on how it works. You'll be able to find this file under automata\waifu\build.state, I've commented it for your convenience, but I'd still like to expand on some things and explain other files needed to make this work.


At the beginning, we have some inputs explained, in the next update, we'll go over some examples and a list of possible animation elements that can be used with this system. The important thing I wanted to point out there is a solution for a little problem with CSS animations, the keyframes are % based, which can cause some issues for animation authoring. Generally, you want to use more absolute time units, like milliseconds, which is what we use in this system. To facilitate this, we need a conversion rate from ms to %. Also please note we have nine separate points of articulation listed, that's just what came up with the file, everything here is prepared to be modified in case a different set of points is needed.


CSS can also be fairly fiddly when it comes to the initial and final conditions of the animation. You can easily override the initial state of an object by using animations, but animations cannot inherit from an object. As such, we'll have a set of variables that help us consolidate this; we'll build the animations, and that'll replace the object's initial setup. To do this, we first have to define all our variables. In case the person doing the animations doesn't want to do that on their own, we'll build a file containing all the needed variable creation lines and use that.


The idea is that if anything needs to be set to a different value, it can be set created separately, everything else (that doesn't exist yet, that is) will be created automatically and initialised with a default value. Speaking of those values, setting variables can sometimes be a chore, so let's add a few presets that can be easily called (by name) to set up specific articulation points or settings.


This is a grammatical file where every production rule has associated tags and results. The statement in the square brackets we've seen two images before will evaluate to one of these options each time it is called for a new setting. It is essentially allowing us to execute these settings by name. A setup like this is typical for my work.


Next, we'll be iterating over all the articulation points; I pointed out that we have them listed at the very beginning, and here we'll be using that for our outer loop. We build the CSS for each point and move on, iterating over the keyframes each time. The important thing is that we load all the archetypes for the animation from a file. We'll get to a file like that later, but for now, know that we'll be doing it a bit differently than before. Because we need to tackle it a bit more carefully, we'll be using a selector from the tools automaton instead of just direct grammatical statements. This allows for finer control but requires the options to be loaded into an array.

Let's look at one of the archetype files:


A bit of a mess and hard to parse for a human, so let's unfold just one specific example, the eye-lookahead archetype.


A bit clearer, I hope? This is essentially a grammatical statement that outputs CSS; it also interops with my scripting language. These archetypes use the variables set up previously, construct CSS animation keyframes based on them and alter the variables to maintain consistency. Because it's quite clear CSS has no intention to do so!

Aaaaanyway...


Let's get to building the keyframes into usable CSS. Any CSS animation needs a start and an endpoint or else they get wonky. So we'll start by generating a name for the keyframe set and then dump the initial state (the 0% frame into it). We do this using another grammar file, not unlike the ones I've already shown here.


Well do the 100% the same way after processing all keyframes, I won't show that off, it's exactly the same thing.


Most of the magic happens here, and it's a crucial demonstration of how a selector state works. Grammatical constructions are powerful, and in the vast majority of all cases are more than needed to get the job done. But sometimes additional finesse is required. There are cases where, for example, the available choices need to be examined before being applied. This is one such case. We need to check if we have any matching selections at all. Otherwise, we skip this archetype; it might just not be meant for this specific articulation point.


After doing this for each articulation point, it's time to print the CSS. And the CSS file itself is also one huge grammatical statement that ties this all together. It's somewhat repetitive, doing essentially the same thing for each articulation point, so let's continue just focusing on one of the eyes as an example.


Here we link up the element being animated with the animations prepared for it, and it uses a statement that I don't believe I've explained before. [i?option_0|..|option_m], is a simple non-terminal that selects the i-th among the options. If i was originally a logic variable, like here, false gets converted to 0 (left option), and true gets converted to 1 (right option). So it'll either link up the animation and the idle state afterwards, or just the idle animation.


Then finally, lower down in the file all the animation keyframes are inserted into the... oh and some of the idle animations are not quite as static as it might be!

Next time I'll wrap up this system with some usage examples, and we can get to writing the story.

Get Esoteric ♥ Esoterica

Leave a comment

Log in with itch.io to leave a comment.