Difference between revisions of "BuildingScenariosSimple"

From The Battle for Wesnoth Wiki
m (Reverted edit of GrabberBot, changed back to last version by CrazyTerabyte)
 
(56 intermediate revisions by 17 users not shown)
Line 1: Line 1:
I will show you a very simple scenario file,
+
{{BuildingScenariosNav}}
then explain each line of it.
 
This file is not fully functional, but it shows you
 
the basics needed to describe what this scenario is all about.
 
  
[scenario]
+
Here we will show you a very simple scenario file and explain each line of it.
 +
The file is not fully functional, but it will show the basics needed to describe what a scenario is all about.
 +
 
 +
'''Before reading this, it might prove useful to read something about the syntax of the Wesnoth Markup Language: [[SyntaxWML]]'''
 +
 
 +
== First part ==
 +
 
 +
<blockquote>
 +
<pre>
 +
<nowiki>
 +
#textdomain wesnoth-Simple_Campaign
 +
[scenario]
 +
 
 +
  id=01_test-1
 +
  next_scenario=02_test-more
 
   
 
   
id=test-1
+
  name= _ "A Simple Test Scenario"
next_scenario=test-2
+
  map_data="{~add-ons/Test_Campaign/maps/testmap.map}"
 +
  turns=20
 
   
 
   
name=A Simple Test Scenario
+
  {DAWN}
map_data="{campaigns/Test_Campaign/testmap}{~campaigns/Test_Campaign/testmap}"
+
  {MORNING}
turns=20
+
  {AFTERNOON}
 +
  {DUSK}
 +
  {FIRST_WATCH}
 +
  {SECOND_WATCH}
 
   
 
   
{DAWN}
+
  music=battle.ogg
{MORNING}
 
{AFTERNOON}
 
{DUSK}
 
{FIRST_WATCH}
 
{SECOND_WATCH}
 
 
   
 
   
music=wesnoth-1.ogg
+
  [event]
+
    name=prestart
[event]
+
    [objectives]
name=prestart
+
      side=1
  [objectives]
+
      [objective]
  side=1
+
        description= _ "Defeat Enemy Leader"
  [objective]
+
        condition=win
    description= _ "Defeat Enemy Leader"
+
      [/objective]
    condition=win
+
      [objective]
  [/objective]
+
        description= _ "Death of Konrad"
  [objective]
+
        condition=lose
    description= _ "Death of Konrad"
+
      [/objective]
    condition=lose
+
      [objective]
  [/objective]
+
        description= _ "Turns run out"
   [/objectives]
+
        condition=lose
  [/event]
+
      [/objective]
 +
    [/objectives]
 +
   [/event]
 +
</nowiki>
 +
</pre>
 +
 
 +
''continued below''
 +
<br>&nbsp;&nbsp;&nbsp; <font size=5>↓ ↓ ↓</font>
 +
</blockquote>
 +
* <code>#textdomain</code> must be provided at the start of your scenario file if you want it to be translated. Format is <code>#textdomain wesnoth-Name_of_your_campaign</code>, as defined in your _main.cfg file.
 +
 
 +
 
 +
Every scenario must be enclosed in a tag; the <code>[scenario]</code> tag is used for campaign scenarios. The first set of attributes in the scenario tag describe the very basics of this scenario:
 +
 
 +
* <code>id</code> (short for ''identifier'') is the computer's name for your scenario and is not displayed during the game. However, it will be used to display game statistics (they will be graphed at http://stats.wesnoth.org in numerical order, so it's also a good idea to give the <code>id</code>'s a number). This name is also referenced in other tags and files, ''e.g.,'' inside a <code>[campaign]</code> tag using the <code>first_scenario</code> attribute (see [[BuildingCampaignsTheCampaignFile]]) or inside a <code>[scenario]</code> tag using the <code>next_scenario</code> attribute (see below).
 +
 
 +
* The value of the <code>next_scenario</code> attribute is the <code>id</code> (see above) of the scenario that is played after this one is won. Units from this scenario will be available for recall (unless you modify the recall list, but that's stuff for later). If your scenario is not part of a campaign, or if this is the last scenario you should either skip this line or put <code>next_scenario=null</code> inside the file. This will tell the game to display the ''End'' screen when this scenario is won.
 +
 
 +
* The value of the <code>name</code> attribute is shown on the introduction screen before each scenario is played (this may contain a picture of a map or anything else you fancy. See [[BuildingScenariosIntermediate]] for an explanation on how to do that). It's also used to generate the default names of saved files for the level. The underscore before the name marks it as translatable.
 +
 
 +
* The next attribute, <code>map_data</code> is a little tricky.  Normally, the map data (the text that is used to generate a map) goes directly inside of the quotation marks.  However, it is often useful to keep that map data in a separate file, and then include that file (still inside the quotation marks) using a [[PreprocessorRef|preprocesser]] command.  The code <code>{~add-ons/Test_Campaign/maps/testmap.map}</code> does just that, telling the wesnoth engine to look in the file <code>add-ons/Test_Campaign/maps/testmap</code> for the map data.  The <code>~</code> symbol tells Wesnoth to search for the map file in the ''userdata'' directory (see [[EditingWesnoth]] and [[PreprocessorRef]] for more information). You can create and edit map files using Wesnoth's built-in map editor (see [[BuildingMaps]] for more information).
 +
 
 +
* Finally, the last attribute in the top set of keys is <code>turns</code>. This is the number of turns a player is given to finish the scenario (it can be changed during the game, but again, that is stuff for later). If the player fails to finish the scenario in the given time, he has lost (''i.e.,'' the ''defeat'' event is triggered. See [[EventWML]] for more.)
 +
 
 +
The next section is a group of macros which will be processed by Wesnoth's [[PreprocessorRef|preprocesser]]. Macros are essentially [[WML]] shortcuts. They allow you to define certain pieces of code which can be re-used whenever they are needed. Wesnoth provides you with a whole series of standard, pre-written macros to make life easier, but you yourself can write them too (again, stuff for later).
 +
Let's get back to this example! The macros listed above describe how a day in this scenario will progress. The list of macros above is the normal day used throughout Wesnoth. If you want the entire scenario to take place at night, remove all the macros except for <code>{SECOND_WATCH}</code>. Doing this might, for example, be useful if you've set Konrad to fight the Undead and also want the Undead to have the upper hand throughout the scenario. Remember, though, by setting this to a single time of day rather than the normal diurnal progression shown above, your scenario will effectively take place during one day (or night) rather than across many days as most scenarios do.
 +
 
 +
The <code>music</code> attribute takes for its value the name of a music file (see [[MusicListWML]] for more). This file must be in the <code>music/</code> directory and <b>must</b> be in [http://en.wikipedia.org/wiki/Ogg Ogg] format.
 +
 
 +
A tag you'll get to know very well when making scenarios is <code>[event]...[/event]</code>. <code>event</code> tags are used to describe what should be done when various sorts of ''events'' take place. The specific type of event is stated in the <code>event</code>'s <code>name</code> attribute. In this case we're describing the so-called <code>prestart</code> event. This event occurs just ''after'' all the introduction screens for the scenario have been shown but just ''before'' the map itself is displayed. This prestart event is used to set the scenario's objectives, i.e. the contents of the ''Scenario Objectives Dialog'' that will appear once the scenario begins. The purpose of the Scenario Objectives Dialog is to inform the player what must be accomplished to win the scenario and what circumstances bring about defeat. These winning and losing circumstances are defined using the <code>[objectives]</code> tag (N.B. that <code>objectives</code> is plural). Further, each circumstance is defined in its own <code>[objective]</code> (N.B. the singular here) tag with winning circumstances setting <code>condition</code> to <code>win</code>, and with losing circumstances setting it to <code>lose</code>. In the example above, <code>objectives</code> states victory to be "Defeat Enemy Leader". For defeat, however, <code>[objectives]</code> gives the player ''two'' possibilities: either "Death of Konrad" or "Turns run out" (any number of either winning or losing <code>[objective]</code> tags may be given). Accordingly, the Scenario Objectives Dialog will look vaguely like:
  
First, every scenario must be enclosed in a tag;
+
<table border=1><tr><td>
the '''[scenario]''' tag is used for campaign scenarios.
+
'''<font size=e>A Simple Test Scenario</font>'''
The first set of keys in the scenario tag
+
<br>'''Victory:'''
describe the very basics of this scenario.
+
<br><font color=green>Defeat Enemy Leader</font>
The ''id'' is the computer's name for your scenario,
+
<br>'''Defeat:'''
and is not displayed during the game.
+
<br><font color=red>Death of Konrad
It is neccesary to put this name somewhere else,
+
<br>Turns run out</font>
such as a campaign tag, as well, in order to actually play the scenario.
+
<br>
Where you put the ID for the scenario
+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
indicates how you would play this scenario in-game.
+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
For example, if your scenario is for a campaign,
+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ OK ]
you need to list it as the scenario following another scenario in the campaign.
+
</td></tr></table>
  
The ''next_scenario'' key lists the scenario
+
Note that the <code>[objectives]</code> tag doesn't define the circumstances of victory or defeat to the game engine. It merely tells the player what they are. Special victory or defeat conditions will have to be coded into the scenario using various [event]s.
that is played after this one is won,
 
with units from this scenario available for recall.
 
The value of this key should be the same
 
as the value of the '''id''' key in the scenario following it.
 
If your scenario is not part of a campaign,
 
putting '''next_scenario=null''' or skipping this line
 
will cause the "End" screen to be displayed when you win.
 
  
The ''name'' key is shown on the introduction screen(which usually contains the
+
The <code>side</code> attribute in <code>[objectives]</code> indicates that the conditions defined here by the <code>[objective]</code> tags are for the faction or alliance ''side 1'' alone (see below). In a single-player game, side 1 would usually indicate the player's faction or alliance). The underscore ("_") facilitates translation using [[GetText|Gettext]].
map graphic) before each scenario is played.
 
It is also the default name for saves on the level.
 
The next key, ''map_data'', is a link to the map file.
 
Since we may not know exactly where this campaign will be installed we write
 
two possible locations of the map data.
 
The quotes are necessary because Wesnoth map data takes up multiple lines,
 
so quotes are used instead to determine where the data begins and ends.
 
The map file must be a valid Wesnoth map file; see [[BuildingMaps]].
 
Finally, the last key in the top set of keys is ''turns''.
 
This sets an event on the specified turn causing the player to lose.
 
  
The next section is a set of IDs. This section tells the game how a day should
+
== Second part ==
progress. This listing above is the normal day used throughout Wesnoth. If you
+
So far so good! The last necessary part describes what the players (both human and
want the entire scenario to take place at night, remove all the IDs except for
+
computer) start with, what they can do, and what they can't do. Each of the players is described in a <code>[side]</code> tag with the word ''side'' referring to a player's faction, band, or horde.
'''{SECOND_WATCH}'''. This can be useful if you have Konrad
 
fighting against the Undead and wanted the Undead to have the upper hand the
 
whole time. Remember though, by setting this to a single ID and not the normal
 
day listed above, your scenario will effectively be taking place during one day
 
or night, not many days as the majority currently are.
 
  
The ''music'' key is a filename pointing to the music which plays.
+
<blockquote>
This music file must be in the ''music/'' directory and must be in .ogg format.
+
&nbsp;&nbsp;&nbsp; <font size=5>↑ ↑ ↑</font>
 +
<br>''continued from above''
 +
<pre>
 +
<nowiki>
 +
  [side]
 +
    side=1
 +
    controller=human
 +
    team_name=2
 +
    user_team_name= _ "Konrad's forces"
  
The next part sets the objectives for the scenario. This is done inside an '''[event]''' tag, and to have the objectives set before the scenario starts, we must specify '''name=prestart'''. Inside the [event] tag, we have an '''[objectives]''' (plural) tag, which contains any number of '''[objective]''' (singular) tags.
+
    type=Commander
For each tag, if ''condition'' is "win", the text of ''description'' will be displayed in green after "Victory" in the Scenario Objectives. If ''condition'' is "lose", the text of ''description'' will be displayed in red after "Defeat" in the Scenario Objectives.
+
    id=Konrad
 +
    name= _ "Konrad"
 +
    canrecruit=yes
  
The ' _ ' facilitates translation using Gettext (see [[GetText]]).
+
    recruit=Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman
  
Note that ''ANY'' Victory or Defeat objective can be met to win or lose the scenario,
+
    {GOLD 100 50 0}
but a single Victory objective may have multiple parts.
+
    {INCOME 10 5 0}
 +
  [/side]
 +
[/scenario]
 +
</nowiki>
 +
</pre>
 +
</blockquote>
  
So far so good. The last necessary part of a scenario describes what the players (Human and
+
Above you can see a sample <code>[side]</code> for the human player, Konrad. The first group of attributes in the <code>[side]</code> tag pertains to the side generally:
Computer) start with and can do. Each of the players is described through
+
* <code>side</code>: the leader of this side is placed on the tile represented by this digit (see [[BuildingMaps]]). It's a number from 1 to 9.
the '''[side]''' tag.
+
* <code>controller</code> takes either of two possible values: <code>human</code> or <code>ai</code> (''i.e.,'' ''artificial intelligence'', meaning your computer). If you don't specify this attribute, <code>ai</code> is the default.
 +
* <code>team_name</code> describes which team the side is on. It defaults to the same number as <code>side</code>, but setting it to <code>2</code> allies this side with side 2 (if you haven't changed the <code>team_name</code> of side 2).
 +
* <code>user_team_name</code> is the name displayed when you view the side stats (by pressing <tt>alt+s</tt> during gameplay). The underscore ("_") facilitates translation using [[GetText|Gettext]].
  
.
+
The next group of attributes describe the leader of this side:
.
+
* <code>canrecruit</code>: This attribute can be set to <code>yes</code> or <code>no</code> (the boolean equivalents <code>1</code> and <code>0</code> or <code>true</code> and <code>false</code> also work). If this is set to <code>no</code>, the leader won't be able to recruit (not much of a leader then, is he?). Any side without a <code>canrecruit=yes</code> attribute statement automatically loses, so be sure to include this attribute.
.
+
* <code>type</code> describes what type of unit the leader will be. The possible values are listed in [http://units.wesnoth.org the Wesnoth unit tables].
+
* <code>id</code> is the identifier of the leader, as used by the engine, and is not visible by the player.
[side]
+
* <code>name</code> is the name of the leader, as visible to the player. The underscore marks it as translatable.
side=1
 
controller=human
 
team_name=2
 
 
type=Commander
 
description=Konrad
 
canrecruit=1
 
 
recruit=Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman
 
 
{GOLD 100 50 0}
 
{INCOME 10 5 0}
 
  [/side]
 
 
[/scenario]
 
  
From the above example above you can see
+
In a campaign, all of these "leader-describing" attributes are ignored for human players (except <code>canrecruit</code>), since the leader from the previous scenario is carried over into the current one. The exception to this is, of course, the first scenario, because there is no leader from previous scenarios. However, the <code>type</code> attribute is still necessary to prevent the scenario from crashing, so be sure to include it.
a sample '''[side]''' for the human player, Konrad.
 
The first key, ''side'',
 
is the location where this player starts on the map,
 
and is also the ID for this side.
 
It is a number from 1 to 9.
 
The next key that describes this player is ''controller''.
 
The possible values are 'human'
 
and 'ai', with 'ai' as the default.
 
After this, the ''team_name'' key describes which team the side is on.
 
In this example Konrad is on team "2", which by default contains side 2.
 
However, if you change the team_name of side 2,
 
Konrad will no longer be allied with it.
 
  
The next set of keys describe the player's leader.
+
The last attribute, <code>recruit</code>, is a comma-separated list of [http://units.wesnoth.org unit types]. These types will become the side's recruitment listThis too is only necessary in a human player's first scenario, because the recruit list is carried over from one scenario to the next.
First we have ''canrecruit''.
 
This key can be '0' or '1', which is "no" or "yes" respectively.
 
If you say no, then the player's leader will not be able to recruit.
 
And if he can't recruit, he's not really a leader, is he?
 
Any team without a canrecruit=1 unit automatically loses, so be sure to use this key.
 
The next key, ''type'', is the type of unit the leader will be.
 
The possible values are listed at [[UnitTables]].
 
The ''description'' is the name and description of the leader.
 
All of these keys are ignored for the human player on all campaign scenarios except the first,
 
since the leader from the previous scenario is used instead.
 
However, the ''type'' key is still neccesary to prevent the scenario from crashing.
 
  
Next we have the '''recruit''' key which is a comma-separated
+
Finally, two macros are called. The first, <code>GOLD</code> takes three positive numbers. These indicate the amount of money the player will start with on the <var>easy</var>, <var>normal</var>, and <var>hard</var> difficulty levels, respectively. For a human-controlled side (<code>controller=human</code>), this specifies only the <i>minimum</i> amount of gold.  The actual amount the player starts with can be larger if the player has retained gold from previous scenarios. The second macro, <code>INCOME</code>, is analogous to <code>GOLD</code> but for the base income. The defaults values for <code>GOLD</code> and <code>INCOME</code> are 100 gold and 2 base income, respectively.
list of units. The possible values are listed in [[UnitTables]].
 
  
The last two things are IDs.
+
== Making it all work ==
'''{GOLD}''' inputs any 3 positive numbers.
+
To make this scenario playable, we need to make a campaign for it (see [[BuildingCampaignsTheCampaignFile]]).
These indicate the amount of money the player will start with.
+
This should '''not''' be stored in the main directory <tt>data/campaigns</tt> but rather inside <tt>userdata/data/campaigns</tt>. This prevents the breaking of mainline campaigns or, even worse, the entire game.
The first value indicates the value on the EASY difficulty level;
+
Please note that all files (''i.e.'', the campaign file and the scenario files for each level) must be saved with the file extension <tt>.cfg</tt> (''e.g.'', <tt>_main.cfg</tt>).
second NORMAL, third HARD.
+
The following is a short, example campaign file:
When this is inside the ''controller=human'' in a campaign file
 
then the actual gold the player gets will be the maximum of this value,
 
and the amount of gold the player retained from the previous scenario.
 
The '''INCOME''' id is similar, but indicates the base income instead of the base gold.
 
The defaults for each of these values are 100 gold and 2 base income.
 
  
Now, to make this scenario playable, we need to make a campaign for it.
 
This should usually be stored in its own file in '''data/campaigns/'''.
 
Note: All files, the campaign file and the scenario file, one for each scenario level, must be saved with the ending
 
.cfg (for example: testcampaign.cfg, level1.cfg).
 
 
  [campaign]
 
  [campaign]
name= _ "Test Campaign"
+
  name= _ "Test Campaign"
first_scenario=test-1
+
  first_scenario=test-1
difficulties=EASY,NORMAL,HARD
+
  define=CAMPAIGN_TEST_CAMPAIGN
+
  difficulties=EASY,NORMAL,HARD
difficulty_descriptions= _ "&elvish-fighter.png=Easy;*&elvish-hero.png=Medium;&elvish-champion.png=Hard"
+
  difficulty_descriptions={MENU_IMG_TXT2 "units/elves-wood/fighter.png" _"Fighter" _"(Beginner)"} +
icon=elvish-fighter.png
+
    ";*" + {MENU_IMG_TXT2 "units/elves-wood/hero.png" _"Hero" _"(Normal)"} +
 +
    ";" + {MENU_IMG_TXT2 "units/elves-wood/champion.png" _"Champion" _"(Hard)"}
 +
  icon="units/elves-wood/hero.png"
 
  [/campaign]
 
  [/campaign]
 +
#ifdef CAMPAIGN_TEST_CAMPAIGN
 +
{~add-ons/test_campaign/scenarios}
 +
#endif
 +
 +
The <code>[campaign]</code> tag describes the campaign. The first attribute, <code>name</code>, is displayed in the campaign selector box during gameplay. The second, <code>first_scenario</code>, is set to the ID number of the first scenario of the campaign. Subsequent scenarios are referenced by the <code>next_scenario</code> attribute of their immediately preceding scenarios (see above in the first part of this tutorial). Since the first scenario, obviously, doesn't have a predecessor, it is referenced here in the <code>campaign</code> tag. To allow wesnoth to actually find the first scenario we need to include the scenarios directory of our campaign. The last statement of the campaign file does that. The inclusion is best guarded by a preprocessor symbol ([[PreprocessorRef]]) that is unique to this campaign so all the scenarios get only included when this campaign is actually selected by the player. The preprocessor symbol for a campaign is given by the <code>define</code> key.
 +
 +
The attribute <code>difficulties=EASY,NORMAL,HARD</code> tells Wesnoth to use the value <code>EASY</code> if the first difficulty choice is chosen during gameplay, <code>NORMAL</code> if the second is chosen, and <code>HARD</code> if the third is chosen.
 +
The expression <code>#ifdef</code> can be used later to test the value of this attribute (see [[PreprocessorRef]]).
 +
It is recommended that you do not use any names other than <code>EASY</code>, <code>NORMAL</code>, or <code>HARD</code> for your macros because doing so will cause some standard macros, such as <code>{GOLD}</code> and <code>{INCOME}</code>, to not work properly.
  
Campaigns are enclosed in the '''[campaign]''' tag. The first key is ''name'', which is
+
Two optional attributes are <code>difficulty_descriptions</code> and <code>icon</code>.
displayed on the campaign selector box. The second key is ''first_scenario'', which is
+
As its value, <code>icon</code> holds the filename of an image to represent this campaign which will be displayed in the campaign list during gameplay.
the ID of the first scenario of the campaign (Other scenarios are indicated using
 
''next_scenario'').
 
  
The attribute '''difficulties=EASY,NORMAL,HARD'''
+
The <code>difficulty_descriptions</code> uses a standard syntax. You provide an image, difficulty name, and a level. Unsurprising, in our example during gameplay <tt>elvish-fighter.png</tt> would display associated with the <i>easy</i> level, <tt>elvish-hero.png</tt> with <i>normal</i>, and <tt>elvish-champion.png</tt> with <i>hard</i>. You can use whatever names you want, and don't need to stick with easy, normal and hard here. You do need to do this in the <code>difficulties</code> section, because many macros are based off this.
tells the computer to give the macro '''EASY''' a value
 
if the first difficulty choice is chosen,
 
'''NORMAL''' if the second is chosen, and '''HARD''' if the third is chosen.
 
The expression '''#ifdef''' can be used later to test these macros.
 
It is recommended that you do not use any names other than
 
'''EASY''', '''NORMAL''', and '''HARD''' for your macros,
 
because if you do then the macros '''{GOLD}''' and '''{INCOME}''' will not work properly.
 
  
Two optional keys in '''[campaign]''' are ''difficulty_descriptions'' and ''icon''.
+
Each list item in <code>difficulty_description</code> begins with the macro <code>MENU_IMG_TEXT2</code> which simplifies the syntax (see [[DescriptionWML]]). This is followed by the filename of the image, then an equal sign ("="), and finally the text to display (<i>i.e.</i>, "Easy". Take note that text displayed for the easy level is not "EASY": the text used is that in <code>difficulty_descriptions</code>, not <code>difficulties</code>. Similary, the normal level's text is "Medium").  
''icon'' has value equal to an image.
+
 
''difficulty_descriptions'' must have the same number of inputs as  '''difficulties''', most commonly three, separated by
+
Optionally you may place an asterisk ("*") before one of list items of <code>difficulty_desciptions</code> which will cause that corresponding difficulty level to be selected as the default during gameplay. In the example above, the normal level (along with its elvish hero) is selected as the default.
semicolons.
 
These inputs then map on to the difficulties, so that if you have set difficulties to
 
"difficulties=EASY,NORMAL,HARD",
 
the first input will specify the display
 
on easy, the second on normal and the third (and last) on hard.
 
Each difficulty display is an '''&''' sign, then the image to display,
 
then an equals sign, then the text to display.
 
Place an '''*''' sign before the display which you wish to be default difficulty, and it will be selected when the player
 
has chosen the campaign.
 
  
 
== See Also ==
 
== See Also ==
 
* [[BuildingMaps]]
 
* [[BuildingMaps]]
* [[ScenarioWML]]
+
* [[ScenarioWML]] & [[SyntaxWML]]
 
* [[BuildingScenarios]]
 
* [[BuildingScenarios]]
 +
 +
[[Category:Create]]

Latest revision as of 22:06, 10 October 2018

Here we will show you a very simple scenario file and explain each line of it. The file is not fully functional, but it will show the basics needed to describe what a scenario is all about.

Before reading this, it might prove useful to read something about the syntax of the Wesnoth Markup Language: SyntaxWML

First part


#textdomain wesnoth-Simple_Campaign
[scenario]

  id=01_test-1
  next_scenario=02_test-more
 
  name= _ "A Simple Test Scenario"
  map_data="{~add-ons/Test_Campaign/maps/testmap.map}"
  turns=20
 
  {DAWN}
  {MORNING}
  {AFTERNOON}
  {DUSK}
  {FIRST_WATCH}
  {SECOND_WATCH}
 
  music=battle.ogg
 
  [event]
    name=prestart
    [objectives]
      side=1
      [objective]
        description= _ "Defeat Enemy Leader"
        condition=win
      [/objective]
      [objective]
        description= _ "Death of Konrad"
        condition=lose
      [/objective]
      [objective]
        description= _ "Turns run out"
        condition=lose
      [/objective]
    [/objectives]
  [/event]

continued below
    ↓ ↓ ↓

  • #textdomain must be provided at the start of your scenario file if you want it to be translated. Format is #textdomain wesnoth-Name_of_your_campaign, as defined in your _main.cfg file.


Every scenario must be enclosed in a tag; the [scenario] tag is used for campaign scenarios. The first set of attributes in the scenario tag describe the very basics of this scenario:

  • id (short for identifier) is the computer's name for your scenario and is not displayed during the game. However, it will be used to display game statistics (they will be graphed at http://stats.wesnoth.org in numerical order, so it's also a good idea to give the id's a number). This name is also referenced in other tags and files, e.g., inside a [campaign] tag using the first_scenario attribute (see BuildingCampaignsTheCampaignFile) or inside a [scenario] tag using the next_scenario attribute (see below).
  • The value of the next_scenario attribute is the id (see above) of the scenario that is played after this one is won. Units from this scenario will be available for recall (unless you modify the recall list, but that's stuff for later). If your scenario is not part of a campaign, or if this is the last scenario you should either skip this line or put next_scenario=null inside the file. This will tell the game to display the End screen when this scenario is won.
  • The value of the name attribute is shown on the introduction screen before each scenario is played (this may contain a picture of a map or anything else you fancy. See BuildingScenariosIntermediate for an explanation on how to do that). It's also used to generate the default names of saved files for the level. The underscore before the name marks it as translatable.
  • The next attribute, map_data is a little tricky. Normally, the map data (the text that is used to generate a map) goes directly inside of the quotation marks. However, it is often useful to keep that map data in a separate file, and then include that file (still inside the quotation marks) using a preprocesser command. The code {~add-ons/Test_Campaign/maps/testmap.map} does just that, telling the wesnoth engine to look in the file add-ons/Test_Campaign/maps/testmap for the map data. The ~ symbol tells Wesnoth to search for the map file in the userdata directory (see EditingWesnoth and PreprocessorRef for more information). You can create and edit map files using Wesnoth's built-in map editor (see BuildingMaps for more information).
  • Finally, the last attribute in the top set of keys is turns. This is the number of turns a player is given to finish the scenario (it can be changed during the game, but again, that is stuff for later). If the player fails to finish the scenario in the given time, he has lost (i.e., the defeat event is triggered. See EventWML for more.)

The next section is a group of macros which will be processed by Wesnoth's preprocesser. Macros are essentially WML shortcuts. They allow you to define certain pieces of code which can be re-used whenever they are needed. Wesnoth provides you with a whole series of standard, pre-written macros to make life easier, but you yourself can write them too (again, stuff for later). Let's get back to this example! The macros listed above describe how a day in this scenario will progress. The list of macros above is the normal day used throughout Wesnoth. If you want the entire scenario to take place at night, remove all the macros except for {SECOND_WATCH}. Doing this might, for example, be useful if you've set Konrad to fight the Undead and also want the Undead to have the upper hand throughout the scenario. Remember, though, by setting this to a single time of day rather than the normal diurnal progression shown above, your scenario will effectively take place during one day (or night) rather than across many days as most scenarios do.

The music attribute takes for its value the name of a music file (see MusicListWML for more). This file must be in the music/ directory and must be in Ogg format.

A tag you'll get to know very well when making scenarios is [event]...[/event]. event tags are used to describe what should be done when various sorts of events take place. The specific type of event is stated in the event's name attribute. In this case we're describing the so-called prestart event. This event occurs just after all the introduction screens for the scenario have been shown but just before the map itself is displayed. This prestart event is used to set the scenario's objectives, i.e. the contents of the Scenario Objectives Dialog that will appear once the scenario begins. The purpose of the Scenario Objectives Dialog is to inform the player what must be accomplished to win the scenario and what circumstances bring about defeat. These winning and losing circumstances are defined using the [objectives] tag (N.B. that objectives is plural). Further, each circumstance is defined in its own [objective] (N.B. the singular here) tag with winning circumstances setting condition to win, and with losing circumstances setting it to lose. In the example above, objectives states victory to be "Defeat Enemy Leader". For defeat, however, [objectives] gives the player two possibilities: either "Death of Konrad" or "Turns run out" (any number of either winning or losing [objective] tags may be given). Accordingly, the Scenario Objectives Dialog will look vaguely like:

A Simple Test Scenario
Victory:
Defeat Enemy Leader
Defeat:
Death of Konrad
Turns run out

                        [ OK ]

Note that the [objectives] tag doesn't define the circumstances of victory or defeat to the game engine. It merely tells the player what they are. Special victory or defeat conditions will have to be coded into the scenario using various [event]s.

The side attribute in [objectives] indicates that the conditions defined here by the [objective] tags are for the faction or alliance side 1 alone (see below). In a single-player game, side 1 would usually indicate the player's faction or alliance). The underscore ("_") facilitates translation using Gettext.

Second part

So far so good! The last necessary part describes what the players (both human and computer) start with, what they can do, and what they can't do. Each of the players is described in a [side] tag with the word side referring to a player's faction, band, or horde.

    ↑ ↑ ↑
continued from above


  [side]
    side=1
    controller=human
    team_name=2
    user_team_name= _ "Konrad's forces"

    type=Commander
    id=Konrad
    name= _ "Konrad"
    canrecruit=yes

    recruit=Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman

    {GOLD 100 50 0}
    {INCOME 10 5 0}
  [/side] 
[/scenario]

Above you can see a sample [side] for the human player, Konrad. The first group of attributes in the [side] tag pertains to the side generally:

  • side: the leader of this side is placed on the tile represented by this digit (see BuildingMaps). It's a number from 1 to 9.
  • controller takes either of two possible values: human or ai (i.e., artificial intelligence, meaning your computer). If you don't specify this attribute, ai is the default.
  • team_name describes which team the side is on. It defaults to the same number as side, but setting it to 2 allies this side with side 2 (if you haven't changed the team_name of side 2).
  • user_team_name is the name displayed when you view the side stats (by pressing alt+s during gameplay). The underscore ("_") facilitates translation using Gettext.

The next group of attributes describe the leader of this side:

  • canrecruit: This attribute can be set to yes or no (the boolean equivalents 1 and 0 or true and false also work). If this is set to no, the leader won't be able to recruit (not much of a leader then, is he?). Any side without a canrecruit=yes attribute statement automatically loses, so be sure to include this attribute.
  • type describes what type of unit the leader will be. The possible values are listed in the Wesnoth unit tables.
  • id is the identifier of the leader, as used by the engine, and is not visible by the player.
  • name is the name of the leader, as visible to the player. The underscore marks it as translatable.

In a campaign, all of these "leader-describing" attributes are ignored for human players (except canrecruit), since the leader from the previous scenario is carried over into the current one. The exception to this is, of course, the first scenario, because there is no leader from previous scenarios. However, the type attribute is still necessary to prevent the scenario from crashing, so be sure to include it.

The last attribute, recruit, is a comma-separated list of unit types. These types will become the side's recruitment list. This too is only necessary in a human player's first scenario, because the recruit list is carried over from one scenario to the next.

Finally, two macros are called. The first, GOLD takes three positive numbers. These indicate the amount of money the player will start with on the easy, normal, and hard difficulty levels, respectively. For a human-controlled side (controller=human), this specifies only the minimum amount of gold. The actual amount the player starts with can be larger if the player has retained gold from previous scenarios. The second macro, INCOME, is analogous to GOLD but for the base income. The defaults values for GOLD and INCOME are 100 gold and 2 base income, respectively.

Making it all work

To make this scenario playable, we need to make a campaign for it (see BuildingCampaignsTheCampaignFile). This should not be stored in the main directory data/campaigns but rather inside userdata/data/campaigns. This prevents the breaking of mainline campaigns or, even worse, the entire game. Please note that all files (i.e., the campaign file and the scenario files for each level) must be saved with the file extension .cfg (e.g., _main.cfg). The following is a short, example campaign file:

[campaign]
  name= _ "Test Campaign"
  first_scenario=test-1
  define=CAMPAIGN_TEST_CAMPAIGN
  difficulties=EASY,NORMAL,HARD
  difficulty_descriptions={MENU_IMG_TXT2 "units/elves-wood/fighter.png" _"Fighter" _"(Beginner)"} +
   ";*" + {MENU_IMG_TXT2 "units/elves-wood/hero.png" _"Hero" _"(Normal)"} +
   ";" + {MENU_IMG_TXT2 "units/elves-wood/champion.png" _"Champion" _"(Hard)"}
  icon="units/elves-wood/hero.png" 
[/campaign]
#ifdef CAMPAIGN_TEST_CAMPAIGN
{~add-ons/test_campaign/scenarios}
#endif

The [campaign] tag describes the campaign. The first attribute, name, is displayed in the campaign selector box during gameplay. The second, first_scenario, is set to the ID number of the first scenario of the campaign. Subsequent scenarios are referenced by the next_scenario attribute of their immediately preceding scenarios (see above in the first part of this tutorial). Since the first scenario, obviously, doesn't have a predecessor, it is referenced here in the campaign tag. To allow wesnoth to actually find the first scenario we need to include the scenarios directory of our campaign. The last statement of the campaign file does that. The inclusion is best guarded by a preprocessor symbol (PreprocessorRef) that is unique to this campaign so all the scenarios get only included when this campaign is actually selected by the player. The preprocessor symbol for a campaign is given by the define key.

The attribute difficulties=EASY,NORMAL,HARD tells Wesnoth to use the value EASY if the first difficulty choice is chosen during gameplay, NORMAL if the second is chosen, and HARD if the third is chosen. The expression #ifdef can be used later to test the value of this attribute (see PreprocessorRef). It is recommended that you do not use any names other than EASY, NORMAL, or HARD for your macros because doing so will cause some standard macros, such as {GOLD} and {INCOME}, to not work properly.

Two optional attributes are difficulty_descriptions and icon. As its value, icon holds the filename of an image to represent this campaign which will be displayed in the campaign list during gameplay.

The difficulty_descriptions uses a standard syntax. You provide an image, difficulty name, and a level. Unsurprising, in our example during gameplay elvish-fighter.png would display associated with the easy level, elvish-hero.png with normal, and elvish-champion.png with hard. You can use whatever names you want, and don't need to stick with easy, normal and hard here. You do need to do this in the difficulties section, because many macros are based off this.

Each list item in difficulty_description begins with the macro MENU_IMG_TEXT2 which simplifies the syntax (see DescriptionWML). This is followed by the filename of the image, then an equal sign ("="), and finally the text to display (i.e., "Easy". Take note that text displayed for the easy level is not "EASY": the text used is that in difficulty_descriptions, not difficulties. Similary, the normal level's text is "Medium").

Optionally you may place an asterisk ("*") before one of list items of difficulty_desciptions which will cause that corresponding difficulty level to be selected as the default during gameplay. In the example above, the normal level (along with its elvish hero) is selected as the default.

See Also

This page was last edited on 10 October 2018, at 22:06.