WML for Complete Beginners: Chapter 4

From The Battle for Wesnoth Wiki

Chapter 4: Creating Your First Scenario

Now that you have your _main.cfg file, it's time to create your first scenario.

Creating the Scenario Map

All scenarios require a map in order to work. Open the Battle for Wesnoth application. On the mainmenu, you should see an option labeled "Map Editor". Actually you can use the editor not only to create maps, but it also has some scenario-editing capabilities. More on that in a later chapter, for the time being let us just focus on simple map editing. Click this option and wait for the editor to load.

By default, Wesnoth creates a blank map with the dimensions 44 x 33 (43 wide and 33 tall). These dimensions will work fine for our purposes, so we won't change them. Hover your cursor over the map and look at the center of the upper edge of the Battle for Wesnoth application window. You should see two numbers separated by a comma.

(screenshot)

These numbers are the X and Y coordinates of the hex over which your cursor is currently hovering. If you move your cursor to another hex, the coordinates will change to show the new location of your cursor. This is a fast and convenient way to locate coordinates on the map.

So we have a map, but let's face it: it's rather dull and uninteresting. Time to add some new terrain. Locate the terrain palette (the area at the far right of your Battle for Wesnoth window that displays the terrains you can use in the editor).

(screenshot)

Towards the top of this window, you should see the terrain category selection buttons. From here you can change what category of terrain is displayed in the terrain palette.

(screenshot)

First, let's add some terrain, for example, hills. Click on the "rough" category button. You should see all available rough terrain types, namely hills, mountains, impassable high mountains and the like. Left click one to assign it to the left mouse button. Now the bottom of the map area shows your chosen terrain. You can do it for the right button too, so you always have 2 types of terrain ready. Go to the map area. Click one hex, or click and hold the left mouse button and swipe the mouse through several hexes. Your terrain is now painted, using the chosen type from the palette. If you accidentally clicked a hex where you don’t want your chosen terrain to expand to, just choose any other type of terrain (grassland, forest, swamp, etc.) and paint it over. You can add grassland, waters, roads, deserts the same way. If you already have a certain terrain type applied on your map, you can assign it to the mouse buttons by Ctrl-clicking on them, instead of finding them again on the palette.

Now let's add some forest to our newly placed hills. Choose the "forest" category button, and then for example "Summer Deciduous Forest". Now click on the hex you want to put your hillside forest to. The forest is inserted, but the hillside is gone! Now the forest stands on grassland. This brings us to one important aspect: the layers of the map.

In the Wesnoth maps there are two layers. The "base" layer and the "overlay" layer. Base is the terrain that is below, and the overlay is the plants, buildings, bridges, etc. on it. To help you to understand better: the same forest can stand on grassland, hills, dry hills, mountains, even sand. And the same hillside can foster deciduous forests, mixed forests, summer forests, even desert forests. Something similar goes for buildings: the same bridge can span over shallow water, tropical water, swamp, even grassland, should the river be dried up.

How to draw that on the map? Easy: with the Shift key. Choose a forest, building, etc., and put it down while holding the Shift key. As you shall see, the stuff you have chosen shall be put on top of the existing base terrain, leaving it unchanged. Or try the other way around: choose a terrain, and put it under an existing bridge, forest, etc., with the Shift key pressed and held down. Experiment a little, you shall get the hang if it pretty quick.

When you judge your environment be finished, let's add a castle for the leader of the player's side to recruit from in the first scenario. Click on the "castle" category button. Then paint your castle the same way you paint any other terrain.

(screenshot of the castle terrain category button)

Don’t forget to add a keep to your castle. That’s where your leader shall be positioned at the start of the scenario, and that’s where he (or she) can recruit his/her army from.

Draw a castle with a keep for the opposite party too. (Unless of course if you want to build a scenario without an enemy.)

As for villages: You can place villages the same way as any other type of terrain. Assigning the villages to sides in another matter, we shall discuss the topic of assigning the villages to either side in a later chapter.

We are almost done with the map, but in order to use it, we have to assign our leaders to the keeps. This is done by using the Starting Positions Tool.

(screenshot of the Starting Positions Tool)

Click on the flag, then choose Player 1 (usually the human player) or Player 2 (usually the AI). Now click on the preferred keep. That's it, now you have your leader assigned to the castle. A label with the player name should also appear.

Finally, save your new map. You may save it to the Editor default location (data folder/editor/maps) and copy it over later to the data folder. Instead let us save it directly where our scenario needs it, i.e. the scenario’s map location (add-ons/my_first_campaign/maps/my_first_map.map).

Creating the Scenario .cfg File

Create a new text file in the "scenarios" folder inside your campaign folder. Name this new text file "my_first_scenario.cfg". Open the "my_first_scenario.cfg" file in your text editor, if you haven't already. Since it is a new file, it should be completely empty right now. It won't be when we're done with it, however!

The Toplevel Tagset and Attributes

First, on the very first line of the file, tell the game what text domain this file belongs to. In case you forgot, the text domain for this campaign is " wesnoth-my_first_campaign". So you would write:

#textdomain wesnoth-my_first_campaign


Now let's add the [scenario] tagset:

[scenario]
[/scenario]

The [scenario] tagset is a toplevel tagset (i.e., it is not the child of any other tagset) and tells the game where the scenario begins and where it ends. All the information for your scenario goes within this tagset.

Next, inside the [scenario] tagset, include the following keys:

    id=
    next_scenario=
    name=
    map_data=
    turns=

Now the contents of the "my_first_scenario.cfg" file should look like this:

#textdomain wesnoth-my_first_campaign
[scenario]
    id=
    next_scenario=
    name=
    map_data=
    turns=
[/scenario]

We have provided keys for these attributes, so now it's time to assign them their values.


  • The "id" Key
Assign the value "my_first_scenario" to the "id" key, like so:
id=my_first_scenario
Do you remember the value we assigned to the "first_scenario" key in the "_main.cfg" file? If you followed the instructions given in this tutorial, the value of that key should be "my_first_scenario". It is absolutely imperative that the value of the "first_scenario" key and the "id" key of the first scenario are exactly the same. If you misspelled either of them, introduced an incorrect capitalization into either of them, or made a typo of any kind in either of them, the game will return an error message when it tries to load the scenario. This is because the value of the "first_scenario" key refers to the id of your first scenario. If there is no scenario with an "id" key whose value exactly matches the value of the "first_scenario" key in the "_main.cfg", the game won't be able to find the first scenario and will tell you so by giving you an error message when you try to play your campaign.


  • The "next_scenario" Key
We are going to assign the value "null" to the "next_scenario" key. Example:
next_scenario=null
The "next_scenario" key is a close cousin of the "first_scenario" key found in the "_main.cfg" file. Just as the "first_scenario" tells the game to look for a scenario with an id key whose value matches the value of the the "first_scenario" key, the "next_scenario" key tells the game which scenario to load after the player completes the current scenario. Just like with the "first_scenario" key, make sure the value of the "next_scenario" key exactly matches the id of the next scenario (including underscores, capitalization, spelling, etc.), otherwise you'll get an error message. If there is no next scenario, you would assign the value "null" to the "next_scenario" key, as we did here. This means that when the player completes the current scenario, the game knows that there is no next scenario to go to, and the campaign will end.


  • The "name" Key
For this attribute, we are going to give it this translatable string:
 _ "My First Scenario." 

As you should recall from our previous discussion about translatable strings, the value we give should be enclosed in double quotes and should have a whitespace, an underscore, and then another whitespace immediately before the first double quote. So now your "name" attribute should look like this:

name= _ "My First Scenario"
Technically, the name of the scenario doesn't have to resemble the scenario's id at all. But it's a good idea to have the scenario id and the scenario name be as similar as possible to avoid any confusion later on.


  • The "map_data" or "map_file" Key
In Wesnoth 1.12, we use the "map_data" key, and are going to assign the value "{~add-ons/my_first_campaign/maps/my_first_map.map}". Map filepaths must always be within surrounded by double quotes, otherwise error messages will occur. Now it should look like this:
map_data="{~add-ons/my_first_campaign/maps/my_first_map.map}"
We can use either "map_data" or the new "map_file" key. If you've added the previous chapter's binary_path, the following line will automatically look in the ~add-ons/my_first_campaign/maps/ directory.
map_file=my_first_map.map
  • The "turns" Key
We are going to assign the number "30" to this key:
turns=30
This attribute specifies how many turns the player will have to complete the scenario. If the player does not complete the scenario objective before the turns run out, then the player will lose the scenario. Since we have assigned the value "30" to this key, that means that if the player hasn't won the scenario by the end of thirty turns, he or she will lose.


Now that we have assigned values to all our keys, the entire contents of the "my_first_scenario.cfg" file should now look like this:

#textdomain wesnoth-my_first_campaign
[scenario]
    id=my_first_scenario
    next_scenario=null
    name=_"My First Scenario."
    map_data="{~add-ons/my_first_campaign/maps/my_first_map.map}"
    turns=30
[/scenario]

Defining Sides

In any scenario, you will always need at least one side (the player's), and usually at least one other side as well. For this scenario, we need to define two sides: the player's side and the enemy's side.

Haven't we just done it on the map? Yes, but we shall need to define those sides in detail here in the scenario's configuration file too. Player 1 and 2 on the map shall be called Side 1 and 2 here respectively.

Let's start with the player's side. In order to define a side, we need to include the [side] tagset as a child of the [scenario] tagset. All the keys we add to define a side go inside this [side] tagset.

[scenario]
    [side]
        #keys go here
    [/side]
[/scenario]
  • The "side" Key
The "side" key is used to keep track of the side (or player) number of this side. Normally, the player is side 1.
side=1
  • The "controller" Key
The "controller" key is used to tell WML whether this side belongs to a 'human' or to the 'ai'. This side belongs to a human.
controller=human
  • The "team_name" Key
The "team_name" key is an internal variable (the user never gets to see its value) which WML uses to keep track of teams. All sides with the same team_name are considered allies.
team_name="good"
  • The "user_team_name" Key
The "user_team_name" key contains the text for the team name to display to the user. Since this will be seen, it should be marked as translatable using an underscore '_'. Note that user_team_name does not need to be the same as team_name, and that sides with the same team_name need not have the same user_team_name.
user_team_name= _ "My Team"
  • The "id" Key
The "id" key contains the id (identifier) for this side's leader, and is not seen in-game. Use this id to access the leader from within WML.
id="MyLeader"
  • The "name" Key
The "name" key represents the name of this side's leader. Since this will be seen in-game, it should be marked as translatable.
name= _ "My Leader"
  • The "type" Key
The "type" key contains the unit-type of this side's leader. In this example, the leader is an Elvish Ranger.
type="Elvish Ranger"
  • The "unrenameable" Key
The "unrenameable" key, if set to 'yes' prevents the user from being able to change the name of the leader in-game. For most scenarios, this should be set to 'yes'.
unrenameable=yes
  • The "canrecruit" Key
The "canrecruit" key, if set to 'yes' allows this leader to recruit units.
canrecruit=yes
  • The "recruit" Key
The "recruit" key is a comma-separated list of all the units this leader is allowed to recruit. Our example Elvish Ranger is able to recruit Elvish Fighters, Elvish Archers, and Elvish Shamans by the following statement:
recruit="Elvish Fighter, Elvish Archer, Elvish Shaman"
  • The "gold" Key
The "gold" key is set to the starting gold amount for this side. This fictional side is given 100 gold to start. (Note that it is possible to give a side a differing amount of starting gold based upon the difficulty level, but that is not covered at this time.)
gold=100
Repeat this process for every side you wish to create. I'm going to add a simple ai side:
[side]
    side=2
    controller=ai
    team_name="bad"
    user_team_name= _ "Bad Guys"
    id="EnemyLeader"
    name= _ "My Villain"
    type= "Orcish Warrior"
    unrenameable=yes
    canrecruit=yes
    recruit="Orcish Grunt, Orcish Archer, Orcish Assassin, Wolf Rider"
    gold=100
[/side]

Now the entire contents of the "my_first_scenario.cfg" file should look something like this:

#textdomain wesnoth-my_first_campaign
[scenario]
    id=my_first_scenario
    next_scenario=null
    name=_"My First Scenario."
    map_data="{~add-ons/my_first_campaign/maps/my_first_map.map}"
    turns=30
    [side]
        side=1
        controller=human
        team_name="good"
        user_team_name= _ "My Team"
        id=MyLeader
        name= _ "My Leader's Name"
        type="Elvish Ranger"
        unrenameable=yes
        canrecruit=yes
        recruit="Elvish Fighter, Elvish Archer, Elvish Shaman"
        gold=100
    [/side]
    [side]
       side=2
       controller=ai
       team_name="bad"
       user_team_name= _ "Bad Guys"
       id="EnemyLeader"
       name= _ "My Villain"
       type= "Orcish Warrior"
       unrenameable=yes
       canrecruit=yes
       recruit="Orcish Grunt, Orcish Archer, Orcish Assassin, Wolf Rider"
       gold=100
    [/side]
[/scenario]

Now we are just one final step away from finishing it, and finally playing it at last. The next step in creating your first scenario is to add the events which trigger in-game. To learn how to create events, continue to the next chapter.

Navigation
Chapter 3
The _main.cfg
WML for Complete Beginners: Chapter 4 Chapter 5
Events
This page was last edited on 29 January 2023, at 20:09.