Animations¶
This article covers how to get your animations into the Widelands engine. For information on how to create the animations’ images with Blender, see GraphicsDevelopment.
The Blender export will give you a list of files for each animation. We call this a “file” animation. Once you have tested your animation in Widelands and are satisfied with the results, we recommend that you convert it to a spritesheet. This will save disk space and make animation loading faster.
Animations are defined as Lua tables.
All map objects have a mandatory idle
animation.
They can then have further animations, depending on what their specific capabilities are.
File Animations¶
First, let’s look at an example to understand which options are available, and what your image files need to look like:
-- Tell the engine where the png files are located
animation_directory = path.dirname(__file__),
-- Define the animations
animations = {
idle = {
hotspot = { 5, 7 },
fps = 4,
sound_effect = {
path = "sound/foo/bar",
priority = "5.4%",
allow_multiple = true,
},
representative_frame = 3,
},
walkload = {
basename = "walk",
hotspot = { 5, 7 },
fps = 4,
directional = true
},
...
}
Let’s have a detailed look at the idle
animation:
- idle
Mandatory. This is the name of the animation. The animation can then be referenced by this name e.g. if you want to trigger it in a production program.
- directory
DEPRECATED. The directory where the animation image files are located. Replaced by animation_directory in the Unit’s definition.
- basename
DEPRECATED. The filename prefix for the image files. The plan is to make the file name prefixes identical to the animation name and then to get rid of this parameter.
Our example will pick up any image from
idle_00.png
throughidle_99.png
in the specified directory path – the current path in our example. These images can optionally have corresponding player color mask images calledidle_00_pc.png
throughidle_99_pc.png
. Make sure to include leading 0’s in the file names and to have consistent length – we support 1, 2 and 3 digit numbers in an animation. If your animation contains only one file, you can also call itidle.png
(andidle_pc.png
for the player color mask) without_
or any numbers in the file name. You can omit the basename if it’s identical to the animation’s name.We support mipmaps for animations. They allow us to provide the same image in different resolutions for optimum rendering quality. For using mipmaps, simply name your files accordingly, and the engine will pick them up. e.g.
idle_0.5_00.png
will be rendered at scale0.5
, andidle_1_00.png
will be rendered at the neutral scale1
. The scale of1
is mandatory, and other supported scales are0.5
,2
and4
.- pictures
DEPRECATED. This is older code that is slowly being phased out - do not use this parameter. A table with full directory and file names.
- directional
Optional. If this is
true
, indicates to the engine that this is a directional animation. In our example, the engine will create a set of 6 animations called"walk_ne"
,"walk_e"
,"walk_se"
,"walk_sw"
,"walk_w"
, and"walk_nw"
. See Directional Animations below.- hotspot
Mandatory. Hotspots define a place on a graphic image through its x and y coordinates that can be used as a handle or reference point to provide control over positioning the image on the map. For example, hotspots help carriers stay on the road, and control the positioning of the wares they carry. Increase
x
to shift the animation to the left andy
to shift it upwards.- fps
Optional. The frames per second for this animation if you want to deviate from the default fps. This will control the playback speed of the animation. Do not specify this value if you have only 1 animation frame.
- sound_effect
Optional. Our example will look for the sound files
bar_00.ogg
throughbar_99.ogg
in the directorydata/sound/foo
and play one of them at random. The priority ranges from0.01%
to100%`,` and it is the percent chance of the sound being played. If ``allow_multiple = true
, the same sound can be played by multiple map objects at the same time.
Directional Animations¶
For objects that move around the map, like carriers, ships or animals, there need to be 6 animations for the walking directions northeast "ne"
, east "e"
, southeast "se"
, southwest "sw"
, west "w"
, and northwest "nw"
. So, a “walk” animation would consist of 6 animations called "walk_ne"
, "walk_e"
, "walk_se"
, "walk_sw"
, "walk_w"
, and "walk_nw"
.
Each of these 6 animations will then be defined like the animation above, so we would end up with files called walk_ne_00.png
, walk_ne_01.png
… walk_nw_00.png
, walk_nw_01.png
…, and for player color: walk_ne_00_pc.png
, walk_ne_01_pc.png
… walk_nw_00_pc.png
, walk_nw_01_pc.png
, …
We also support mipmaps here – name the files walk_ne_0.5_00.png
,
walk_ne_0.5_01.png
etc. for scale 0.5, walk_ne_1_00.png
,
walk_ne_1_01.png
etc. for scale 1 and so on.
In the Lua code, the option directional = true
will signal to the engine that it needs to treat it as a directional animation.
Spritesheet Animations¶
The same map object can have a mix of file and spritesheet animations.
For converting a file animation to a spritesheet animation, use the command line
to call ./wl_create_spritesheet
from the Widelands program directory.
This will print the command line options to use for converting your animation.
After conversion, you will need to delete the old files and copy over the new files,
then delete the old animation code in the map object’s init.lua
file and add the new code.
The tool will print the new code to the console for you, so all you need to do is copy/paste
and then add any missing optional parameters back in.
Note that the table for spritesheets is called spritesheets
, not animations
!
This distinction is necessary for performance reasons.
Spritesheets have three additional mandatory parameters so that the engine can identify the individual textures in the sheet:
- frames
The number of frames (images) that this animation has. Equal to the number of files in a file animation.
- columns
The number of image columns in the spritesheet.
- rows
The number of image rows in the spritesheet.
Here’s the example from above as spritesheets:
spritesheets = {
idle = {
fps = 4,
frames = 150,
rows = 13,
columns = 12,
hotspot = { 5, 7 }
sound_effect = {
path = "sound/foo/bar",
priority = "5.4%",
allow_multiple = true
},
representative_frame = 3,
},
walk = {
fps = 4,
frames = 10,
rows = 4,
columns = 3,
directional = true,
hotspot = { 5, 7 }
},
...
}
Converting Animation Formats¶
When converting a simple file animation to a mipmap animation, follow these steps:
Use utils/rename_animation.py to rename the previous animation, to make sure that our version control system will not lose its history, e.g.:
utils/rename_animation.py data/tribes/workers/fancytribe/diligentworker/walk_ne data/tribes/workers/fancytribe/diligentworker/walk_ne_1 utils/rename_animation.py data/tribes/workers/fancytribe/diligentworker/walk_nw data/tribes/workers/fancytribe/diligentworker/walk_nw_1 ...
Export the new animations from Blender, preferably at all supported scales. Only export the higher resolution scales if the textures have sufficient resolution.
Alternatively, you can use the Java tool MipmapMaker that is contained in the widelands-media repository. MipmapMaker accepts high-resolution images as input files (they should be at least 4 times the in-game size) and creates correctly named mipmap images for all supported scales for each animation, e.g.:
java MipmapMaker ~/widelands/data/tribes/workers/fancytribe/diligentworker walk_se 2 true true true 4.0
MipmapMaker is documented in
widelands-media/graphics/tools/Graphics Tools (Java)/Readme
.
Map Object Types¶
Each type of map object needs a specific set of animations defined. All map objects have an idle
animation. Specialized map objects have the following additional animations:
Buildings¶
For building animations, the hotspot denotes where the road ends at the building. Typical building animations are:
- build
This is the building’s construction animation, which usually consist of 4 frames.
- idle
This animation depicts the building in a non-working or resting state.
- working
The building in a productive working state.
- unoccupied
There is no worker in the building.
- empty
For mines when the mine can’t find any more resources.
Any animation other than the build
and idle
animations are referenced in the building’s programs
table via the animate
command. For more information on building programs, see Productionsite Programs.
For example, the animations for a mine could look like this:
animation_directory = path.dirname(__file__),
animations = {
idle = {
hotspot = { 21, 36 },
},
build = {
hotspot = { 21, 36 },
},
working = {
hotspot = { 21, 36 },
},
empty = {
hotspot = { 21, 36 },
},
}
Immovables¶
Unlike for other map objects, the idle
animation needs to be referenced via the animate
command for the default program
in an immovable’s programs
table.
Workers¶
Workers can have both non-directional animations and directional animations. The following animations will always be loaded if defined:
- idle
Mandatory. This non-directional animation depicts the worker in a non-working or resting state, e.g. a carrier waiting on a road when there are no wares to transport.
- walk
Mandatory. A directional animation. The worker is walking towards a destination.
- walkload
Optional. A directional animation. The worker is walking while carrying something.
Any further animations like e.g. “plant”, “harvest”, or “breed” will be referenced in the Worker Programs, under the animation
command.
For example, a fisher’s animations could look like this:
animation_directory = path.dirname(__file__),
-- A file animation for the idle. Ideally, we'll only have those if the animation only has 1 frame.
animations = {
idle = {
hotspot = { 7, 33 },
},
},
spritesheets = {
-- A directional animation as a spritesheet
walk = {
fps = 10,
frames = 10,
rows = 4,
columns = 3,
directional = true,
hotspot = { 8, 32 }
},
-- A stationary animation as a spritesheet
fish = {
fps = 10,
frames = 30,
rows = 6,
columns = 5,
hotspot = { 7, 33 }
}
}
Soldiers¶
Soldiers have the same animations as workers, plus additional non-directional battle animations. There can be multiple animations for each action in battle to be selected at random.
Each animation for a soldier requires a range of training levels to be specified. An animation will be used only for soldiers within the chosen range. Refer to Tribes.new_soldier_type
for details on the syntax.
For example, attacking towards the west can be defined like this:
level_rookie = {
min_health = 0,
min_attack = 0,
min_defense = 0,
min_evade = 0,
max_health = 0,
max_attack = 3,
max_defense = 2,
max_evade = 0,
}
wl.Descriptions():new_soldier_type {
name = "fancytribe_soldier",
...
animation_directory = path.dirname(__file__),
animations = {
idle = {
hotspot = { 16, 31 },
fps = 5
},
-- First attack animation
atk_ok_w1 = {
hotspot = { 30, 36 },
fps = 10
},
-- Second attack animation
atk_ok_w2 = {
hotspot = { 30, 36 },
fps = 10
},
...
walk = {
hotspot = { 16, 31 },
fps = 10,
directional = true
},
},
-- Reference the attack animations in your map object
attack_success_w = {
atk_ok_w1 = level_rookie,
atk_ok_w2 = level_rookie,
},
...
}
The battle animations are:
- attack_success_w
A successful attack towards the west.
- attack_success_e
A successful attack towards the east.
- attack_failure_e
A failed attack towards the west.
- attack_failure_w
A failed attack towards the west.
- evade_success_w
Successfully evaded an attack from the west.
- evade_success_e
Successfully evaded an attack from the east.
- evade_failure_e
Is being hit by an attack from the west.
- evade_failure_w
Is being hit by an attack from the east.
- die_w
Killed by an attack from the west.
- die_e
Killed by an attack from the east.
Ships¶
All ships have the following animations:
- idle
The ship is waiting for something to do.
- sinking
The ship is being sunk.
- sail
A directional animation shown while the ship is traveling.
Critters (Animals)¶
Critters have an idle
and a walk
animation.