WML Templates

From The Battle for Wesnoth Wiki

This page provides a set of blank 'templates' which can be used as a basis for user-made campaigns, scenarios, and units. You will need to have a basic understanding of WML to make best use of these resources. See ReferenceWML. You will also need to understand how to create text files on your computer and set up an appropriate directory structure for the campaign. By the time you have created a simple campaign using these templates, you should have learned enough about WML to be able to create more ambitious work on your own.

Campaign files

For a basic campaign, you need to create a set of .cfg files in the correct locations. That also means you have to create a set of correctly-named directories as well. These examples will lead you through the basic setup of a campaign called Example_Campaign. You will need to replace all occurrences of Example_Campaign with the name of your own campaign.

For everything to work reliably, the names must be exactly as shown. If there is a mismatch between any of the names, Wesnoth will not be able to find all the data it needs to run your campaign, and it will stop dead with an error. Assume that all names are case-sensitive, and use underscores ( _ ) for spaces between words. Avoid accented characters as well. If you do not, you may find that your campaign only works properly for other people using the same operating system as you.

You should put your campaign to userdata/data/add-ons. Where it is located, depends on your OS and Wesnoth version. See EditingWesnoth#The_user_data_directory for details.

Basic file creation

To make a campaign, you need to create a set of files and directories, as follows:

  • A campaign folder: /Example_Campaign/
    • A blank text file: /Example_Campaign/_main.cfg
    • A scenario folder: /Example_Campaign/scenarios/
      • At least one scenario file: /Example_Campaign/scenarios/01_First_Scenario.cfg
    • A maps folder: /Example_Campaign/maps/
      • A map for every scenario: /Example_Campaign/maps/01_First_Scenario
    • A units folder: /Example_Campaign/units/
      • Probably a custom unit for your hero: /Example_Campaign/units/custom_hero.cfg
      • Possibly other custom units too: /Example_Campaign/units/custom_unit.cfg
    • An images folder: /Example_Campaign/images/
      • A possible images sub-folder: /Example_Campaign/images/icons
      • A possible images sub-folder: /Example_Campaign/images/portraits
      • A possible images sub-folder: /Example_Campaign/images/story
      • A possible images sub-folder: /Example_Campaign/images/units
    • A utilities (macros) folder: /Example_Campaign/utils/
      • Inside the utils folder, a blank text file: /deaths.cfg
      • Inside the utils folder, a blank text file: /route.cfg
      • Inside the utils folder, a blank text file: /story.cfg
      • Inside the utils folder, a blank text file: /utils.cfg

Scenario map creation is considered separately. [Placeholder link - may need to be altered to point to content that already exists.]

Tip: Number your scenarios as the first part of their filenames. This makes it easier to tell what order they will be used in. If your scenarios branch (meaning a player will either play scenario A or scenario B, but not both), label the alternatives something like 03a_First_Branch.cfg, 03b_Second_Branch.cfg and so on. For a basic campaign, we advise you not to use scenario branching unless you're already a confident WML coder.

Tip: Use the same numbering scheme for your maps as well, although if you want to name the maps differently from the corresponding scenario, that's fine. For example, you might have a scenario called 01_Kidnap_Attempt.cfg, while the associated map is called 01_The_Royal_Park.map.

While you may not need custom folders for, say, units or campaign-specific graphics, it does no harm to set them up in advance and leave them empty, so we suggest you create them anyway.

It is important that you place all the parts of your campaign in the right places and that the folders are named correctly, because Wesnoth will look for these folders to find your scenarios, images etc. If you use a different folder arrangement of your own (for example if you store all your macros in a /macros/ directory) then you will have to adjust the example code accordingly.

Tip: Choose an abbreviation for your campaign that doesn't clash with the names of any other campaign. For example, Heir to the Throne is commonly abbreviated HttT.

_main.cfg

[Campaign] section

The _main.cfg file has two parts. The first part determines the available difficulty settings and difficulty descriptions for your campaign. Without this data, your campaign will not appear in the Wesnoth menu, and you won't be able to select it for playing. The difficulty settings are stored between a [campaign] and a [/campaign] tag as shown below. The parts marked in bold are the bits you will need to customise:

[campaign]
  name= _ "An Example Campaign"
  id=EXAMPLE_CAMPAIGN
  define=EXAMPLE_CAMPAIGN
  first_scenario=01_First_Scenario

difficulties=EASY,NORMAL,HARD difficulty_descriptions={MENU_IMG_TXT2 Easy_Image.png _"Easy setting description" _"(Easy)"} + ";" + {MENU_IMG_TXT2 Normal_Image.png _"Normal setting description" _"(Normal)"} + ";" + {MENU_IMG_TXT2 Hard_Image.png _"Hard setting description" _"(Hard)"}
icon=Campaign_Icon.png description= _ "This is an example campaign template, all ready to be customised."
[about] title= _ "Campaign Designer" text="Your Name" [/about]
[about] title= _ "Current Maintainer" text="Your Name" [/about]
[/campaign]

Working through this block of data a few lines at a time:


  name= _ "An Example Campaign"

The name of your campaign as it is displayed in the Wesnoth game. This is free-text. The name should more-or-less correspond to the name of the campaign folder, but you don't have to worry about file naming restrictions such as having to use underscores for spaces.


  id=EXAMPLE_CAMPAIGN

The campaign identifier. This is used internally by the Wesnoth game.


  define=EXAMPLE_CAMPAIGN

We will call this important entry the campaign name key. The #ifdef command used in the next section must exactly match whatever you define here.


  first_scenario=First_Scenario

The scenario identifier for the first scenario. This must exactly match the scenario ID (id=…) in the relevant scenario file. It's helpful (but not compulsory) to have the scenario filename and the scenario ID match.


  difficulties=EASY,NORMAL,HARD

Using three different difficulty levels is very common for Wesnoth scenarios, but you can have more or fewer if you want. For now, stick with three, and leave their names unaltered.


  difficulty_descriptions={MENU_IMG_TXT2 Easy_Image.png
  _"Easy setting description" _"(Easy)"} + ";"
  + {MENU_IMG_TXT2 Normal_Image.png
  _"Normal setting description" _"(Normal)"} + ";"
  + {MENU_IMG_TXT2 Hard_Image.png
  _"Hard setting description" _"(Hard)"}

There are six different things you can customise here. The Easy, Normal and Hard setting descriptions are usually set to an atmospheric name for the corresponding difficulty level. For example, you might use Scout for the easiest setting, Warrior for the middle setting, and General for the hardest setting. As a rough guide, you should limit yourself to 1-3 words for each difficulty description. The Easy_Image.png, Normal_Image.png and Hard_Image.png refer to custom graphics for each difficulty level. Normally you would save these in the /Example_Campaign/images/ folder. You can also use any standard Wesnoth graphic. For example, if you wanted to use the image of an orcish archer for one of the difficulty settings, you would give the filename as units/orcs/archer.png. (Version 1.13.5 and later only) difficulty_descriptions is deprecated.


  icon=Campaign_Icon.png

A custom campaign icon is optional. If you want to use a standard Wesnoth image, provide the path to the image from the main Wesnoth images directory. For example, items/monolith3.png. Otherwise Wesnoth will look in the /Example_Campaign/images/ folder, in this example for a png file called Campaign_Icon.png.


  description= _ "This is an example campaign template, all ready to be customised."

The campaign description is also free-text. This is a chance to give a quick summary of what your campaign is about. 2-3 lines of text is about the right length.


  [about]
    title= _ "Campaign Designer"
    text="Your Name"
  [/about]

[about] title= _ "Current Maintainer" text="Your Name" [/about]

These bits are optional, but if you're planning to share the campaign with others, it's helpful to have some information about who you are. You might also want to credit the people who have helped you with artwork, debugging, or lots of other things, but at the minimum you should fill in your name as the original campaign designer and presumably as the current maintainer too.

Having filled in and customised all of this data, you have set up a workable skeleton campaign structure. There are extra pieces of data that could be inserted into the campaign section, but the basic setup described here is enough to be going on with. Once you are ready to be more ambitious, see CampaignWML for details on other tags and customisation that could be of use.

#define section

The second part of the _main.cfg file contains all the extra information that Wesnoth only needs once a campaign has been selected. When Wesnoth first starts, it scans for all available campaign files. But loading all the images, macros, units etc. from all available campaigns might take a long time and might cause errors, so to begin with Wesnoth only reads the data stored between the [campaign] and [/campaign] tags.

When a particular campaign is selected by the player, Wesnoth loads the rest of the data for that campaign. But for Wesnoth to be able to find the rest of the campaign data, the campaign name key we set up earlier with the line define=EXAMPLE_CAMPAIGN and the #define section of campaign data must match up. As before, you will need to customise all the bits marked in bold. Don't alter anything else, though, unless you know what you're doing.

#ifdef EXAMPLE_CAMPAIGN

[binary_path] path=data/add-ons/Example_Campaign [/binary_path]
# Load campaign utilities first {~add-ons/Example_Campaign/utils}
# Add custom units [units] {~add-ons/Example_Campaign/units} [/units]
# Add scenarios {~add-ons/Example_Campagn/scenarios}
#endif

What do these lines of data do?


#ifdef EXAMPLE_CAMPAIGN

The EXAMPLE_CAMPAIGN text here must be exactly the same as for define=EXAMPLE_CAMPAIGN in the [campaign] section.


[binary_path]
  path=data/add-ons/Example_Campaign
[/binary_path]

The [binary_path] tag tells Wesnoth where the images/, units/, scenarios/, maps/ and utils/ folders are for this campaign.


# Load campaign utilities first

This line is just a free-text comment. In WML, the order in which we load things matters. It's usually a good idea to load campaign macros and utilities as soon as possible. By loading these utilities before the units and scenarios, we know that our custom utilities are available for use in our unit and scenario definitions. Trying to load scenario resources in the wrong order is a common cause of problems when writing campaigns. If for some reason you need to load things in a different order to make your campaign work, adjust the warning accordingly.


{~add-ons/Example_Campaign/utils}

This line loads all the campaign macros and utilities.


# Add custom units
[units]
  {~add-ons/Example_Campaign/units}
[/units]

These lines load all the custom units for the campaign. (# Add custom units is just another free-text comment.)


# Add scenarios
{~add-ons/Example_Campaign/scenarios}

Another comment, then a line that tells Wesnoth where to find all the campaign scenarios.


#endif

The #ifdef at the start of this section is a special multi-line instruction which must be closed using an #endif tag.

utils.cfg

Next you need a file called /Example_Campaign/utils/utils.cfg. If you created the utils/ folder and utils.cfg file in section 1, a blank file with the correct name will already be set up in the correct location. Otherwise, create it now.

The purpose of the utils.cfg file is to act as a repository for any campaign-specific macros you create. Other useful macros can be stored here as well. How you organise them is up to you – you can store them all in the utils.cfg file, or save each one in its own .cfg file. As long as you save all you macros inside the utils directory, everything should work as expected.

Here are some sample macros that are widely-used in many campaigns:

Maps

# A simple map-listing macro
# Usage: map={MAP scenario_name.map}

#define MAP MAP_NAME map_data="{~add-ons/CAMPAIGN_NAME/maps/{MAP_NAME}}" #enddef

Usage: Just copy-and-paste these five lines of text untouched into the utils.cfg file. When you want to use this macro, you call it in your scenario.cfg files, by inserting a line such as {MAP 01_First_Scenario.map} or {MAP 02a_Second_Scenario_Branch_A.map} customising as appropriate to your campaign.

deaths.cfg

This is a macro that will trigger on the death of major campaign characters, including the heroes. If you only need a few dying speeches, you could just store the deaths macro inside utils.cfg. If you have more than about four, or if you plan for characters to use different dying speeches in different scenarios, it's probably better to store the deaths macro separately, as it could get rather long.

#define AEC_DEATHS

[event] name=last breath [filter] id="Hero Name" [/filter] [message] speaker="Hero Name" message= _ "Hero's final words" [/message] [endlevel] result=defeat [/endlevel] [/event]
[event] name=last breath [filter] id="Sidekick Name" [/filter] [message] speaker="Sidekick Name" message= _ "Sidekick's final words" [/message] [endlevel] result=defeat [/endlevel] [/event]
[event] name=last breath [filter] id="Enemy Name" [/filter] [message] speaker="Enemy Name" message= _ "Enemy's final words" [/message] [endlevel] result=victory [/endlevel] [/event]
#enddef

Usage: Copy-and-paste this into the deaths.cfg file, and alter the names and final words for each character. If the unit's dying means game over for the player, include the section of text that says

  [endlevel]
    result=defeat
  [/endlevel]

otherwise delete it.

If the unit's dying means an immediate victory in that scenario, include the section of text that says

  [endlevel]
    result=victory
  [/endlevel]

If you have additional units who need to speak some final words, just make extra copies of the appropriate [event] … [/event] section and customise them to suit.

story.cfg

The story.cfg file allows you to collect together all the background plot for the campaign in one place. You can include this data inside the individual scenario files, but it's better coding practice to separate things out a bit. You can then manage the entire campaign plot in one place rather than having to scan through a dozen scenario files.

#define AEC_STORY01
[story]
  [part]
    music=gameplay01.ogg
    story= _ "The background story, part one."
    background=Background_Image01.png
  [/part]
  [part]
    music=gameplay02.ogg
    story= _ "The background story, part two."
    background=Background_Image02.png
  [/part]
[/story]
#enddef

#define AEC_STORY02 [story] [part] music=gameplay01.ogg story= _ "The background story, part three." background=Background_Image03.png [/part] [/story] #enddef
#define AEC_STORY03 #Placeholder macro; no extra plot exposition for this scenario. #enddef
#define AEC_STORY04 [story] [part] music=gameplay03.ogg story= _ "An unexpected twist halfway through the campaign." background=Background_Image04.png [/part] [/story] #enddef

Usage: Copy-and-paste this into the story.cfg file, and alter the music, text and background image for each stage of the campaign. Each block of story text should be about 2-4 lines. You can have more background text at the very start of the campaign, but don't insert two or three paragraphs of prose between every scenario. Very few people will read it. When you need extra plot sections, just make extra copies of the appropriate parts and customise them.

Music is optional. If you don't want any music delete the music=… lines.

On Linux the standard Wesnoth music available is in /usr/local/share/wesnoth/music/.

In Windows, the music will be in [need correct information; may vary from version to version].

On the Mac, the music will be in [need correct information; may vary from version to version].

Background images are optional but encouraged. If no image filename is supplied, the text appears against a black screen, which is rather dull. If you don't have any suitable images delete the background=… lines.

route.cfg

The route.cfg file allows you to track your heroes' progress across a campaign map. You don't have to have a campaign map at all, of course, but they are widely-used in many Wesnoth campaigns.

#define AEC_ROUTE01
[story]
  [part]
    background=Campaign_Map.png
    show_title=yes
    {DOT 100 150}
    {DOT 150 150}
    {DOT 200 150}
    {DOT 250 150}
    {DOT 250 200}
    {CROSS 250 250}
  [/part]
[/story]
#enddef

#define AEC_ROUTE02 [story] [part] background=Campaign_Map.png show_title=yes {DOT 280 290} {DOT 310 330} {DOT 340 370} {DOT 370 410} {DOT 400 450} {DOT 430 490} {DOT 460 530} {CROSS 490 570} [/part] [/story] #enddef

Usage: Copy-and-paste this into the route.cfg file, and alter the background=, DOT and CROSS commands to suit the map. Make extra copies of each section from #define to #enddef and renumber them for scenarios 03 and onwards. show_title=yes is optional, and shows the campaign title. You can delete this line if you don't want the title to appear.

Tip: The distance between dots is measured in pixels. 30-60 pixels between dots is about right. The bigger the gap, the faster the heroes are assumed to be moving, so if they're moving at constant speed try to keep the distance between dots more or less constant. That's a bit more complicated if they're moving at an angle other than exactly horizontal or exactly vertical. As a rule of thumb, 50 dots horizontally comes to 35 + 35 when moving diagonally at 45°.

See also: IntroWML

Unit files

Custom units are always fun to create. Interesting, balanced custom units are somewhat harder to make. When creating any custom unit, we strongly advise that you start by copying a pre-existing unit that's already similar to what you want. Save it under a new name in your /Example_Campaign/units/ folder, then start customising it. There's almost always going to be something similar to what you want; by copying an existing unit rather than trying to start from scratch you will have reasonable baseline values for things such as movement types, combat values, experience, attack and defense animations and timings and so on. Nevertheless, here's a blank unit template with some annotations on the basic features you might want to use. Bits in bold need customising.

[unit]
  id=Custom Unit
  name= _ "Custom Unit"
  race=human
  alignment=neutral
  usage=fighter
  description= _ "2-3 lines of custom unit description."

image=units/custom-unit.png profile=portraits/custom-unit.png
hitpoints=1 movement=1 movement_type=smallfoot cost=1 level=1 experience=1 advances_to=Advanced Unit
[abilities] {ABIILITY_MACRO} [/abilities]
[attack] name= _ "melee attack" icon=attacks/sword-human.png type=blade range=melee damage=1 number=1 [specials] {WEAPON_SPECIAL_MACRO} [/specials]
[animation] hits=no start_time=-200 [frame] duration=100 image=units/custom-unit-attack-1.png [/frame] [frame] duration=200 image=units/custom-unit-attack-2.png sound={SOUND_LIST:MISS} [/frame] [/animation]
[animation] hits=yes start_time=-200 [frame] duration=100 image=units/custom-unit-attack-1.png [/frame] [frame] duration=200 image=units/custom-unit-attack-2.png sound={SOUND_LIST:SWORD_SWISH} [/frame] [/animation] [/attack]
[attack] name= _ "missile attack" icon=attacks/bow.png type=pierce range=range damage=1 number=1 [specials] {WEAPON_SPECIAL_MACRO} [/specials]
[animation] hits=no start_time=-250 missile_start_time=-150 [missile_frame] duration=150 image=projectiles/missile-n.png image_diagonal=projectiles/missile-ne.png [/missile_frame] [frame] duration=150 image=units/custom-unit-ranged-1.png [/frame] [frame] duration=200 image=units/custom-unit-ranged-2.png sound=bow-miss.ogg [/frame] [/animation]
[animation] hits=yes start_time=-250 missile_start_time=-150 [missile_frame] duration=150 image=projectiles/missile-n.png image_diagonal=projectiles/missile-ne.png [/missile_frame] [frame] duration=150 image=units/custom-unit-ranged-1.png [/frame] [frame] duration=200 image=units/custom-unit-ranged-2.png sound=bow.ogg [/frame] [/animation] [/attack]
{DEFENSE_ANIM_RANGE "units/custom-unit-defend.png" "units/custom-unit.png" {SOUND_LIST:HUMAN_HIT} melee } {DEFENSE_ANIM_RANGE "units/custom-unit-bow-defend.png" "units/custom-unit.png" {SOUND_LIST:HUMAN_HIT} ranged }
[death] [animation] start_time=0 [frame] duration=150 image=units/custom-unit-die-1.png die_sound={SOUND_LIST:HUMAN_DIE} [/frame] [frame] duration=150 image=units/custom-unit-die-2.png [/frame] [/animation] [/death]
[/unit]

General statistics

A unit's 'general statistics' are the absolute bare-bones minimum needed to set it up for play-testing. To be incorporated into a campaign, it will also need sound effects and animations. But at the testing stage, the unit will work with just one unit image, even if it looks odd compared to all the other animated units. For more details on unit setup, see UnitsWML and UnitTypeWML.


  id=Custom Unit

This is the unit ID. When you want to do things like recall a unit, add it to a list of valid recruits or filter for the unit's presence, you must exactly match this ID. See the Scenario template below for further details. You don't need quotation marks unless the unit's name has apostrophes or other special characters in it, and you should avoid using these symbols if possible.


  name= _ "Custom Unit"

This is the translatable version of the unit ID, which is how the unit will be named in-game. This key must have quotation marks around it, but it is free-text so you can use special characters in it if needed.


  race=human

If you create your own custom race, you can freely give it a custom name, but the standard Wesnoth races currently defined are:

  • drake
  • dwarf
  • elf
  • goblin
  • human
  • lizard
  • mechanical
  • merman
  • monster
  • naga
  • ogre
  • orc
  • troll
  • undead
  • wose


  alignment=neutral

Available options:

  • lawful
  • neutral
  • chaotic
  • liminal


  usage=fighter

This value tells the AI how the unit should be used. It has no effect on the player. (Although if you try to use units in inappropriate roles you will likely have problems winning scenarios.) Standard values:

  • archer
  • fighter
  • healer
  • mixed fighter
  • scout


  description= _ "2-3 lines of custom unit description."

The description allows you to give a bit of general background information on the unit. You can use this to establish a unit's reputation, to give 'common knowledge' about its capabilities, or to record some of its origins and history, or its skills and motivations.


  image=units/custom-unit.png

The unit image used within the game.


  profile=portraits/custom-unit.png

The unit image used in pop-up dialog boxes and the on-line help. If a portrait-size image is not provided, the unit image can be used instead. Unit portraits are optional but encouraged.


  hitpoints=1

A unit's maximum hitpoints.


  movement=1

A unit's base movement rate, in hexes per turn. (Some terrain types may cost more than one movement point per hex to cross, and some terrain types are impassable to some or all units.)


  movement_type=smallfoot

A unit's movement type determines how easily it can move on a given terrain and also its defences on that terrain type. You can override both movement costs and defences, and you can create your own custom movement types if you need to, but in general you should try to use the pre-defined options. Currently-available movement types are:

  • armoredfoot
  • deepsea
  • drakefly
  • drakefoot
  • dwarvishfoot
  • elusivefoot
  • float
  • fly
  • largefoot
  • lizard
  • mountainfoot
  • mounted
  • naga
  • orcishfoot
  • scuttlefoot
  • smallfoot
  • swimmer
  • treefolk
  • undeadfly
  • undeadfoot
  • undeadspirit
  • woodland
  • woodlandfloat


  cost=1

The cost in gold to recruit the unit.


  level=1

The unit's level. Usually in the range 0-4. Determines how many experience points another unit would receive for fighting or killing this unit.


  experience=1

The number of experince points for the unit to advance to the next level or receice an 'AMLA' award.


  advances_to=Advanced Unit

The unit ID of another unit; the unit this one becomes when it gains a level. Be sure to match the unit ID exactly, or you will encounter a crash whenever this unit gains a level.

Abilities

  [abilities]
    {ABIILITY_MACRO}
  [/abilities]

You can custom-write your own unit abilities, but the abilities tag as provided here has been set up to use the standard ability macros that have already been defined:

  • ABILITY_AMBUSH
  • ABILITY_CURES
  • ABILITY_HEALS
  • ABILITY_ILLUMINATES
  • ABILITY_LEADERSHIP_LEVEL_1
  • ABILITY_LEADERSHIP_LEVEL_2
  • … up to ABILITY_LEADERSHIP_LEVEL_5
  • ABILITY_NIGHTSTALK
  • ABILITY_REGENERATES
  • ABILITY_SKIRMISHER
  • ABILITY_STEADFAST
  • ABILITY_SUBMERGE
  • ABILITY_TELEPORT

See AbilitiesWML for further details. . (Version 1.13.5 and later only) ABILITY_LEADERSHIP_LEVEL_X are deprecated.

Attacks

This section considers the bare-bones information needed for a unit to have an attack.


    name= _ "melee attack"

The name of the attack. Free-text, translatable.


    icon=attacks/sword-human.png

The attack icon. There are a large number of attack icons stored in /images/attacks/.


    type=blade

The attack type. These are standardised. The available options are:

  • arcane
  • blade
  • cold
  • fire
  • impact
  • pierce


    range=melee

Wesnoth currently allows two attack types:

  • melee
  • ranged

When a unit is attacked, it must respond with an attack with a matching range, if it has one.


    damage=1
    number=1

Weapon damage per strike, and the number of attacks.

Specials

    [specials]
      {WEAPON_SPECIAL_MACRO}
    [/specials]

An ability affects the unit it has been applied to at all times. A 'special' is a weapon special, and applies when a unit uses a specific attack. You can custom-write your own weapon specials if desired, but the standard macros available are:

  • {WEAPON_SPECIAL_BACKSTAB}
  • {WEAPON_SPECIAL_BACKSTAB}
  • {WEAPON_SPECIAL_BERSERK}
  • {WEAPON_SPECIAL_CHARGE}
  • {WEAPON_SPECIAL_DRAIN}
  • {WEAPON_SPECIAL_FIRSTSTRIKE}
  • {WEAPON_SPECIAL_MAGICAL}
  • {WEAPON_SPECIAL_MARKSMAN}
  • {WEAPON_SPECIAL_PLAGUE_TYPE (Walking Corpse)}
  • {WEAPON_SPECIAL_POISON}
  • {WEAPON_SPECIAL_SLOW}
  • {WEAPON_SPECIAL_SWARM}

See AbilitiesWML for further details.

Attack animations - melee

    [animation]
      hits=no

This animation triggers if the attack misses.


      start_time=-200

The animation starts 200 milliseconds before the blow is attempted. By convention, the actual blow is always struck at time=0. Before time=0, the attacker is winding up, nocking an arrow and drawing his bow, or otherwise swinging into action, and after time=0 he is recovering from his swing.


      [frame]
        duration=100
        image=units/custom-unit-attack-1.png
      [/frame]

The first frame of this animation is displayed for 100 milliseconds. As that's still before time=0, this must still be part of the attacker's wind-up. The image displayed is units/custom-unit-attack-1.png


      [frame]
        duration=200
        image=units/custom-unit-attack-2.png
        sound={SOUND_LIST:MISS}
      [/frame]

The second frame of the animation is displayed for 200 milliseconds. Because the attack missed, we also play a 'miss' sound effect from the list of available options. The {SOUND_LIST:MISS} macro will have at least one suitable sound effect, and possibly more, and will play one of them at random as the attack is executed and fails to connect.

If you have more than two frames of attack animations, or if the above timings don't work, you would have to adjust the start_time= and duration= parameters accordingly, and make extra copies of the [frame] … [/frame] code to accomodate your extra animation frames.


    [animation]
      hits=yes

This version of the animation triggers if the attack hits.


      start_time=-200
      [frame]
        duration=100
        image=units/custom-unit-attack-1.png
      [/frame]
      [frame]
        duration=200
        image=units/custom-unit-attack-2.png
        sound={SOUND_LIST:SWORD_SWISH}
      [/frame]

The start_time=, duration= and image= paramaters are the same as before; the only difference is that this time we have a suitable sound sample macro for a hit.The {SOUND_LIST:SWORD_SWISH} macro will have at least one suitable sound effect, and possibly more, and will play one of them at random as the attack strikes home.

Attack animations - ranged

The ranged attack animation works in the same way as the melee attack animation, with one extra complication; a missile attack generally involves a projectile of some kind moving between hexes. So not only do you have to animate the unit performing its attack, you have to handle the missile separately. Once again we use two near-identical animation blocks, one where the attack misses, and the other where it hits.


      start_time=-250
      missile_start_time=-150

In this example, the attacker begins his missile attack at time=-250 milliseconds. At time=-150 milliseconds, he has fired, and a new missile appears as part of the animation. The missile is then animated separately.


      [missile_frame]
        duration=150
        image=projectiles/missile-n.png

The missile is controlled by the [missile_frame] tag. This works in the same way as a normal [frame] tag, but has its own separate duration= and image= tags.


        image_diagonal=projectiles/missile-ne.png

[missile_frame] tags also have a new image_diagonal= tag. This is needed so that the arrow can fly in a straight line towards a diagonally-placed target. Otherwise the arrow might look like it hit its target sideways-on. Melee attacks with piercing weapons also require this treatment, otherwise it can look like the attack has missed when it actually hit.

As these examples show, Wesnoth animation is becoming increasingly sophisticated. The above template only uses some of the basic animation features. See AnimationWML for more details.

Defense animations

  {DEFENSE_ANIM_RANGE "units/custom-unit-defend.png" "units/custom-unit.png" {SOUND_LIST:HUMAN_HIT} melee }
  {DEFENSE_ANIM_RANGE "units/custom-unit-bow-defend.png" "units/custom-unit.png" {SOUND_LIST:HUMAN_HIT} ranged }

If you draw a sophisticated defense animation, your unit's defense will require similar treatment to the attack animations given above. But for a single-frame defense animation, the above macro is suitable. The first line gives a defense animation frame for use against melee attacks. The second line gives a different defense frame for use against ranged attacks. If your unit uses the same animation for both, just repeat the units/custom-unit-defend.png image. The second filename in each macro is the image to switch back to after the attack has finished. The {SOUND_LIST:HUMAN_HIT} should then be customised for your unit.

Death animations

  [death]
    [animation]
      start_time=0
      [frame]
        duration=150
        image=units/custom-unit-die-1.png
        die_sound={SOUND_LIST:HUMAN_DIE}
      [/frame]
      [frame]
        duration=150
        image=units/custom-unit-die-2.png
      [/frame]
    [/animation]   
  [/death]

Death animations work in a similar way to all other animations. In this example we have a two-frame death animation, with each frame displayed for 150 milliseconds while the {SOUND_LIST:HUMAN_DIE} macro handles the sound effects.

Scenario files

Note: This template refers to macros defined in the example macro files given above, utils.cfg, deaths.cfg, story.cfg and route.cfg. That's why you have to set up those files first. If you want either side to be able to use custom units (and it's very common to have a custom hero at the very least) then you have to set them up too. To use this template, make copies of it as 01_First_Scenario.cfg, 02_Second_Scenario.cfg and so on for each scenario you have planned, store them in the /Example_Campaign/scenarios/ folder, then customise each one in turn.

[scenario]
  name= _ "The First Scenario"
  id=01_First_Scenario
  next_scenario=02_Second_Scenario

{MAP 01_First_Scenario.map} {SCENARIO_MUSIC "gameplay01.ogg"} {TURNS 20 18 15}
{MORNING} {AFTERNOON} {DUSK} {FIRST_WATCH} {SECOND_WATCH} {DAWN}
victory_when_enemies_defeated=yes disallow_recall=no
{AEC_STORY_01} {AEC_ROUTE_01}
[side] side=1 controller=human fog=no shroud=no team_name=good description=Hero Name type=Custom Hero canrecruit=yes recruit=Archer,Bowman,Custom Unit {GOLD 150 125 100} [/side]
[side] side=2 team_name=evil description=Enemy Name type=Horseman canrecruit=yes recruit=Draug,Elvish Archer,Fencer {GOLD 150 200 250} [/side]
{AEC_DEATHS}
[event] name=start [recall] id= [/recall] [message] speaker= message= _ "" [/message] [objectives] side=1 [objective] description= _ "Victory Condition" condition=win [/objective] [objective] description= _ "Death of Hero" condition=lose [/objective] [objective] description= _ "Death of Sidekick" condition=lose [/objective] [objective] description= _ "Turns run out" condition=lose [/objective] [/objectives] [/event]
[event] name= [filter] [/filter] [message] speaker= message= _ "" [/message] [/event]
[/scenario]

See Also

This page was last edited on 17 February 2017, at 14:14.