WML for Beginners (Updated): Part 1
In the first part of this tutorial series, we are going to talk about the basics of how WML code works and learn fundamental aspects of the language. Use the navigation tab at the end of the page to go between pages and the index.
What is WML?
In order to create add-ons, including campaigns, custom units, and even collections of maps with advanced scenario features (such as dialogues and custom functionality), you will need to, at least, know the fundamentals of WML. In case you are wondering, WML stands for Wesnoth Markup Language. For more information on what Markup Languages are, please go to this link.
WML is then used inside Configuration Files (files with the .cfg extension) which is then read by Wesnoth in order to create the wonderful singleplayer campaigns available to you when you download the game or even the incredible single-map scenarios with custom functionality which you can play by yourself or with friends.
Tags, Attributes and Values
Tags, attributes, and values define the base structure of WML and when used together compose elemental aspects of code files in Wesnoth Markup Language. The following sections describe each of these in more detail as well as their relation to each other (and more concepts).
Tags are used to define things in WML. They tell Wesnoth you are willing to work with specific areas of the game and also define them. They usually (probably around 253.6% of the time) appear around attributes and values (see below). There are two types of tags: opening tags and closing tags. With very intuitive names, they describe, respectively, when you want to start working with some specific aspect and when you want to stop working with it. To indicate a tag, simply enclose a name (lower case only) in square brackets ("[" and "]"). Opening and closing tags are written the exact same way with the exception that closing tags always have a forward-slash ("/") immediately after the opening square bracket ("["). Here is an example of the unit tag:
Best practice statements: from time to time you will see these bold "best practice" statements. While they are not part of the actual WML syntax and aren't a requirement for WML code to work, they are recommendations designed to ease your life and of those who might read your code in the future (this includes yourself). Thus, while not extremely necessary, they are extremely recommended.
Best practice: always put tags (whether opening or closing) on their own lines for improved readability of code.
Attributes and Values
Using tags you can tell the game which area of it you want to work with. Using attributes and values, you can tell the game how you want to do it. Suppose the following situation: a friend comes to you and says "Buy". You will be confused because you don't know what to buy, when or where. Now, if he says "Could you buy me chocolate at that store right there?" you will know exactly what to buy and exactly where to do it. Note, however, he did not tell you when to buy it, but because of context, you can tell he wants it soon.
When you give Wesnoth empty tags such as our last example with the unit tag, it's the same as saying "Buy" to the code. In there, you tell the game you want to have a unit. You don't tell it, however, which unit you want, where it is, etc. He knows what you want it to do, but has no further information about it. Using attributes and values you can specify how it should be done and cease the game's confusion. Attributes and tags are always used together and have a very simple syntax:
attribute_name = value
Where attribute_name determines the name of the attribute and value which value you want to give it. This is very simple but may have sounded confusing. Let's take a look at our previous example with the unspecified unit tag and make it less confusing to the code:
[unit] type = Orcish Grunt [/unit]
As you can see, we now specify that the unit's type attribute has the value Orcish Grunt. Attributes and values are always used together, and always come enclosed in tags as the previous example shows.
For advanced readers: keep in mind attributes are not the same as variables, forgetting this is a very common mistake. Variables are explained further in this tutorial.
To be simple, comments are the part of the code which is ignored by the game. You may be wondering how ignored code can be of any use, right? Do not worry, I can explain. As the name suggests, comments are... well, comments! They help describe specific sections of the code or explain the reason behind certain implementations, not for the game, but for other people and yourself! They are also an elegant way to organize sections of your code. The following example uses code previously seen in this page but features comments:
# This tag is placing an Orcish Grunt in the scenario. [unit] type = Orcish Grunt [/unit]
As you can see, a comment's syntax is very simple. You only need to use a hashtag ("#") and from the starting hashtag to the end of the line, all will be considered a comment. Having that in mind, you can also insert comments in the middle of code, take a look at this example:
[unit] type = Orcish Grunt # The name of this Grunt is Bob. [/unit]
- - tags define specific areas for the game to work with.
- - attributes and values specify how to work with the area mentioned in their enclosing tags.
- - comments can be used to better describe regions of the code, embellish it or simply organize different sections demarking them with titles, for example.