Advanced Animation Tutorial

From The Battle for Wesnoth Wiki
Revision as of 09:03, 11 May 2007 by Zookeeper (talk | contribs) (Added some new guidelines on macros as well as poison and slows sounds)

How to write animations

This page deals with how to write the animation WML when you got the frames drawn and ready as well as general guidelines for animation lengths and timing. Proper timing is in many cases almost as important in getting an animation to look nice, smooth and consistent with the rest of the game as the actual frames are.

Timing

As a general rule, a melee swing should last at least 300ms and at most 400ms: about 200ms before and after the moment when the swing hits, to keep the speed at which the unit slides back and forth somewhat constant. Naturally there can be exceptions to the "normal" animation lengths, like woses, which have much slower attack animations than most. With ranged attacks, the length of the animation isn't quite as important, since the units aren't taking turns in sliding back and forth (as is the case with melee combat), which makes different animation speeds much more visible. With ranged attacks, however, you have an additional animation to consider: the missile itself. Most normal missiles such as arrows, knives and spears should fly for 150ms. Magical missiles, big rocks or other unusual projectiles can fly longer, but 150ms is the unofficial standard for normal missiles.

Filler frames

The most common use of this is when you only got one frame to represent an attack. Usually, a single attack frame sliding back and forth (if it's a melee attack) looks pretty bad. Ideally, you'd want to have an animation that has the unit stepping forwards and backwards while swinging his weapon, but now we'll assume that for some reason you have to do with just one drawn frame.

Instead of using the common method, which looks like this:

[animation]
    [frame]
        begin=-100
        end=100
        image=unit-attack.png
    [/frame]
[/animation]

...you can with little trouble make that attack smoother, by having the attack frame kick in only at about halfway into the attack and also having it last only slightly past the point where it actually hits the enemy. How do you do this, if you only got one frame to work with? Well, the easiest solution - and one that works fine with almost any kind of unit - is to use the base frame:

[animation]
    [frame]
        begin=-200
        end=-150
        image=unit.png
    [/frame]
    [frame]
        begin=-150
        end=100
        image=unit-attack.png
    [/frame]
    [frame]
        begin=100
        end=200
        image=unit.png
    [/frame]
[/animation]

This makes most melee attack frames look much more natural, since this way it seems more like the attacker is hitting the enemy he's approaching, instead of hitting air where he stands and then sliding towards the enemy and back. The same technique can and should be used whenever you have less than 3 drawn attack frames, whereas animations that have more than that would probably benefit very little from this.

Simple way of getting new drawn frames

Sometimes, the unit has frames made for other animations that can be used as part of the attack animation. Most usually this is a defense, movement or a leadership frame. Quite a few defense frames, for example, are quite suitable as a wind-up to the attack.

...

Sounds

For the vast majority of attacks it is important that it has different sounds for when the attack hits and when it misses. Especially important are "normal" weapons, such as swords, bows, spears and so on. Magical attacks don't necessarily need a different sound when they miss, but if one is available, it should naturally be put to use. Absolutely never leave an attack without any sound altogether! If there isn't a fitting sound available for that weapon or attack, use the second best fitting sound. No attack, unless it's by a silent psychic assassin perhaps, should ever be without an accompanying sound.

Many sounds have changed since 1.1.2 and even more since 1.0, so it's a good idea to check the mainline units in newer versions as reference to what sounds to use for which weapons.

One common way to create hit and miss sound variations is by creating two separate [animation]s for the attack and filtering them by the hits= condition, like this:

[animation]
    hits=no
    [frame]
        begin=-200
        end=-150
        image=unit.png
    [/frame]
    [frame]
        begin=-150
        end=100
        image=unit-attack.png
        sound={SOUND_LIST:MISS}
    [/frame]
    [frame]
        begin=100
        end=200
        image=unit.png
    [/frame]
[/animation]
[animation]
    hits=yes
    [frame]
        begin=-200
        end=-150
        image=unit.png
    [/frame]
    [frame]
        begin=-150
        end=100
        image=unit-attack.png
        sound=axe.ogg
    [/frame]
    [frame]
        begin=100
        end=200
        image=unit.png
    [/frame]
[/animation]

The other way is to use [if] and [else] tags in the animation. In this case, they could be used like this:

[animation]
    [frame]
        begin=-200
        end=-150
        image=unit.png
    [/frame]
    [if]
        hits=no
        [frame]
            begin=-150
            end=100
            image=unit-attack.png
            sound={SOUND_LIST:MISS}
        [/frame]
    [/if]
    [else]
        hits=yes
        [frame]
            begin=-150
            end=100
            image=unit-attack.png
            sound=axe.ogg
        [/frame]
    [/else]
    [frame]
        begin=100
        end=200
        image=unit.png
    [/frame]
[/animation]

In case you're wondering, the {SOUND_LIST:MISS} is a simple macro that just expands to miss-1.ogg,miss-2.ogg,miss-3.ogg. A comma-separated list of sounds can be given to all sound= keys, making the game pick one of them at random whenever the sound is triggered, and the macros (you can find them in data/sound-utils.cfg) exist simply to make writing them more convenient.

A new Template:DevFeature way of doing this would be by using the HIT_MISS_SOUNDS macro. Using that, the animation above would be somewhat more comfortable, quick and less error-prone to write:

[animation]
    [frame]
        begin=-200
        end=-150
        image=unit.png
    [/frame]
    {HIT_MISS_SOUNDS axe.ogg {SOUND_LIST:MISS (
        [frame]
            begin=-150
            end=100
            image=unit-attack.png
        [/frame]
    )}
    [frame]
        begin=100
        end=200
        image=unit.png
    [/frame]
[/animation]

Slows, poison and other special situations Template:DevFeature

Attacks with the slows or poison specials should emit appropriate sounds when they successfully slow or poison an enemy. We have two ready-made macros, FRAME_ON_SLOW and FRAME_ON_POISON available for this which should make the task trivial. Below is an example of how FRAME_OF_POISON is used on mainline units (also note the use of the above-described HIT_MISS_SOUNDS):

[animation]
    [missile_frame]
        begin=-150
        end=0
        image="projectiles/dagger-n.png"
        image_diagonal="projectiles/dagger-ne.png"
    [/missile_frame]
    {HIT_MISS_SOUNDS throwing-knife.ogg throwing-knife-miss.ogg (
        [frame]
            begin=-200
            end=-100
            image="units/orcs/assassin-ranged1.png"
        [/frame]
    )}
    {FRAME_ON_POISON (
        [frame]
            begin=-100
            end=0
            image="units/orcs/assassin-ranged2.png"
            sound=poison.ogg
        [/frame]
    )}
[/animation]

The FRAME_ON_POISON macro makes whatever sound you specify inside the enclosed [frame] (so you could give different poisoning sounds to different units, for example to make magical poisoning sound different from traditional poison, like that on poisoned knives) to be played when the attack hits and the target is not already poisoned, with no sound played if the attack misses or the target is already poisoned. The FRAME_ON_SLOW macro is used in an identical manner, except of course with a different sound (slowed.ogg) as the standard one to use.