https://wiki.wesnoth.org/api.php?action=feedcontributions&user=Salocin&feedformat=atomThe Battle for Wesnoth Wiki - User contributions [en]2024-03-29T12:03:26ZUser contributionsMediaWiki 1.31.16https://wiki.wesnoth.org/index.php?title=BuildingScenariosAdvanced&diff=25598BuildingScenariosAdvanced2008-05-10T16:57:00Z<p>Salocin: /* Variables */</p>
<hr />
<div>{{BuildingScenariosNav}}<br />
<br />
= Building scenarios: Advanced =<br />
<br />
== '''TODO:''' ==<br />
This contained a repetition of what was already inside [[BuildingScenariosIntermediate]]<br />
This should contain: <br />
* (more) information about making & using preprocessors ([[PreprocessorRef]])<br />
* information on guidelines concerning the general layout of a scenario file<br />
* advanced filtering<br />
* ...<br />
<br />
Ayone who feels like writing something, go ahead<br />
<br />
== Advanced Events ==<br />
<br />
===Internal Actions===<br />
See [[InternalActionsWML]] for a complete list of all tags and values. In what folows, the basics of variable creation and manipulation is explained.<br />
<br />
====Variables====<br />
(This can be skipped if you're familiar with the concept of variables)<br />
<br />
(See [[VariablesWML]] for more)<br />
<br />
What are variables? Variables are basicly names. And with those names, we associate a certain value. You can compare this with the words, because words are associated with (several) objects, people, feelings, ... So a variable is just a way of communication: you and the computer (the Wesnoth engine really) are communicating with each other!<br />
<br />
The most important aspect of variables is that they can change with time. (If they don't we call them constants.) Because they change, we can use them to trigger events, or to detect something has happened. You did this already in [[BuildingScenariosIntermediate]], using the [event] tag. We only wanted to trigger the actions inside the [event] when Konrad moved onto tile 4,8. To do so we had to make use of the variables x,y and description.<br />
<br />
Most variables provided by the engine are associated with a certain tag and can thus only be used inside them.<br />
<br />
====Manipulating====<br />
These three actions can be executed in one single tag: ''''[set_variable]''''<br />
Say we wanted to store 'Hello World' in a variable named ''message_to_the_world''. This is how we would do this:<br />
[event]<br />
.<br />
.<br />
.<br />
[set_variable]<br />
#The name of our variable:<br />
name=message_to_the_world<br />
#The value of message_to_the_world, notice the underscore!<br />
value= _ "Hello World!"<br />
[/set_variable]<br />
.<br />
.<br />
.<br />
[/event]<br />
Now, if we want to change the value to something else later on, e.g. 'Goodbye World', we can use the exact same code as above. <br />
If we want to add something to our message we need to use this:<br />
<br />
[event]<br />
.<br />
.<br />
.<br />
[set_variable]<br />
name=message_to_the_world<br />
value= _ "$message_to_the_world Have a nice day!"<br />
[/set_variable]<br />
.<br />
.<br />
.<br />
[/event]<br />
We've been using text variables (called strings) for now. But we can also store numbers and do some basic math with them. The following example clarifies this:<br />
<br />
[event]<br />
.<br />
.<br />
.<br />
[set_variable]<br />
name=number_x<br />
value=10<br />
[/set_variable]<br />
[set_variable]<br />
name=number_x<br />
add=-9<br />
[/set_variable]<br />
[set_variable]<br />
name=number_x<br />
multiply=200<br />
[/set_variable]<br />
[set_variable]<br />
name=number_x<br />
multiply=0.5<br />
[/set_variable]<br />
.<br />
.<br />
.<br />
[/event]<br />
In the above, we set a variable named ''number_x'' to the value of 10. We substract 9 (=1), multiply with 200 (=200) and divide by two (or multiply with 0.5) resulting in 100.<br />
<br />
====Using Variables====<br />
Now that we know how to create and manipulate variables, we'll learn how to use them.<br />
First of all, you need to know what variables you always have at your disposal! In an event tag, these variables are <br />
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)<br />
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)<br />
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered<br />
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered<br />
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event<br />
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event<br />
* '''unit''': inside an event, this is the unit at $x1,$y1<br />
* '''second_unit''': inside an event, this is the unit at $x2,$y2<br />
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match.<br />
<br />
Some of these are only containers for other variables. The ''unit'' variable is an example. You can acces those 'sub'-variables by using dots:<br />
unit.hitpoints<br />
unit.side<br />
...<br />
<br />
We will use $unit in an example to show you how you can use all this:<br />
[scenario]<br />
.<br />
.<br />
.<br />
[event]<br />
#A unit moves onto a tile:<br />
name=moveto<br />
[filter]<br />
x,y=25,26<br />
[/filter]<br />
<br />
<br />
[set_variable]<br />
name=unit.hitpoints<br />
add=-5<br />
[/set_variable]<br />
[set_variable]<br />
name=unit.status.poisoned<br />
value=yes<br />
[/set_variable]<br />
<br />
#After we have changed the values, we need to apply them.<br />
#We do this by using the unstore_unit tag like this:<br />
[unstore_unit]<br />
variable=$unit<br />
find_vacant=no<br />
[/unstore_unit]<br />
[/event]<br />
#We're finished!<br />
.<br />
.<br />
.<br />
[/scenario]<br />
<br />
There's one tag you don't know yet, and that's the '''[unstore_unit]''' tag. To explain this tag I'll explain it's counterparts; '''[store_unit]'''. [store_unit] stores a unit, or several units, in a variables you choose. You can then manipulate those variables as described above. However, you will need to apply these changes, and this is done by using the [unstore_unit] tag. For more see [http://www.wesnoth.org/wiki/InternalActionsWML#.5Bevent.5D InternalActions].<br />
<br />
<br />
<!-- ====Conditionals: [if] and [while]====<br />
<br />
<br />
<br />
===Direct Actions===<br />
===Interface Actions===<br />
//--><br />
<br />
== [[GetText]] & Translations ==<br />
[http://www.wesnoth.org/forum/viewtopic.php?t=11445 As Viliam pointed out] (reordered his words):<br />
<br />
Translating programs has two steps. The first step is making [...] scenarios that are<br />
<b>possible</b> to translate; <b>preferably easy</b> to translate. [...] The second <br />
step is the translating of the texts... leave this to translators.<br />
<br />
So, as a campaign/scenario developer you have to make sure your campaign will be easy to translate. You can achieve this very easily by preceding all text the user might see on the screen with an underscore. This indicates it is a translatable string. [[GetText]] will then be able to look up a translation, based on your localisation settings.<br />
To make it ever more clear, here's an example:<br />
.<br />
.<br />
.<br />
[message]<br />
description=Konrad<br />
message= <b>_</b> "I am mighty Konrad! I fought many dummies and now I will fight you!"<br />
[/message]<br />
.<br />
.<br />
.<br />
<br />
The message key contains the words that will be displayed when Konrad speaks. So this is a translatable string. So it is preceded with an underscore.<br />
<br />
Viliam also said:<br />
<br />
The most important rule of all is: <b>Do not split sentences.</b><br />
In some languages placing a word in a sentence requires more than mere string concatenation.<br />
Some languages use [http://en.wikipedia.org/wiki/Declension declension].<br />
<br />
== Quick Tag Index ==<br />
'''[[ScenarioWML]]''' the top level tags [scenario], [multiplayer], [test], and [tutorial]<br />
:* [[EventWML]] how to describe an event<br />
:** [[FilterWML]]<br />
:** [[DirectActionsWML]], [[InterfaceActionsWML]], [[InternalActionsWML]]<br />
:* [[SideWML]] how to describe a side<br />
:** [[SingleUnitWML]]<br />
:** [[BuildingScenariosShroudData]]<br />
:* [[MapGeneratorWML]] the random map generator<br />
:* [[TimeWML]] how to describe a day<br />
:* [[IntroWML]] how to describe the intro screen <br />
:* [[UtilWML]] a set of preprocessors you can use<br />
<br />
== See Also ==<br />
* [[ScenarioWML]], [[SyntaxWML]] & [[ReferenceWML]]<br />
* [[BuildingScenarios]]<br />
<br />
[[Category:Create]]</div>Salocinhttps://wiki.wesnoth.org/index.php?title=BuildingScenariosSimple&diff=25597BuildingScenariosSimple2008-05-10T16:52:43Z<p>Salocin: /* Second part */</p>
<hr />
<div>{{BuildingScenariosNav}}<br />
<br />
= Learning things step by step =<br />
<br />
This will show you a very simple scenario file, explaining each line of it.<br />
The file is not fully functional, but it will show the basics needed to describe what a scenario is all about.<br />
<br />
'''Before reading this, it might prove useful to read something about the syntax used in the Wesnoth Markup Language: [[SyntaxWML]]'''<br />
<br />
== First part ==<br />
[scenario]<br />
<br />
id=test-1<br />
next_scenario=2_test-more<br />
<br />
name=A Simple Test Scenario<br />
map_data="{campaigns/Test_Campaign/testmap}{~campaigns/Test_Campaign/testmap}"<br />
turns=20<br />
<br />
{DAWN}<br />
{MORNING}<br />
{AFTERNOON}<br />
{DUSK}<br />
{FIRST_WATCH}<br />
{SECOND_WATCH}<br />
<br />
music=wesnoth-1.ogg<br />
<br />
[event]<br />
name=prestart<br />
[objectives]<br />
side=1<br />
[objective]<br />
description= _ "Defeat Enemy Leader"<br />
condition=win<br />
[/objective]<br />
[objective]<br />
description= _ "Death of Konrad"<br />
condition=lose<br />
[/objective]<br />
[/objectives]<br />
[/event]<br />
. continued below<br />
. ||<br />
. \/<br />
<br />
Every scenario must be enclosed in a tag;<br />
the '''[scenario]''' tag is used for campaign scenarios.<br />
The first set of keys in the scenario tag<br />
describe the very basics of this scenario:<br />
* The ''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 on 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 used as reference in other tags and files, eg inside a '''[campaign]''' tag using the ''first_scenario'' key(see [[BuildingCampaignsTheCampaignFile]]) or inside a '''[scenario]''' tag using the ''next_scenario'' key (see below).<br />
<br />
* The value of the ''next_scenario'' key 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.<br />
<br />
* The value of the ''name'' key is shown on the introduction screen before each scenario is played. (This can contain a picture of a map, or anything else you fancy. See [[BuildingScenariosIntermediate]] for an explenation on how to do that.) It's also the default name for saves on the level.<br />
<br />
* The next key, ''map_data'', is a link to the map file. You can create map files using the Wesnoth Map Editor (see [[WesnothMapEditor]] and [[BuildingMaps]] for more information). Since we may not know exactly where this campaign will be located we'll write two possible locations of the map file. The quotes are necessary because Wesnoth map data takes up multiple lines, so quotes are used to indicate where the data begins and ends. If you don't do this, it will break the scenario.<br />
<br />
* Finally, the last key in the top set of keys is ''turns''. This is the amount of turns a player is given to finish the scenario. (It can be changed during the game, but again, that is stuff for later.) When the player fails to finish the secnario in the given time, he has lost. (Said otherwise: the ''defeat'' event is trigered. See [[EventWML]] for more.)<br />
<br />
The next section is a set of preprocessors (see [[PreprocessorRef]]). Preprocessors are essentially WML shortcuts. They allow you to define certain pieces of code and re-use it whenever it is needed. Wesnoth provides you with a whole serie of standard preprocessors to make life more easy, but you yourself can define them too (again stuff for later). <br />
Lets get back to this example! The preprocessors used here, describe how a day in this scenario should progress. This listing above is the normal day used throughout Wesnoth. If you want the entire scenario to take place at night, remove all the preprocessors except for '''{SECOND_WATCH}'''. This could be useful if you have Konrad<br />
fighting the Undead and want the Undead to have the upper hand the whole time. Remember though, by setting this to a single tme of day and not the normal progress listed above, your scenario will effectively be taking place during one day or night, not many days as most scenarios are.<br />
<br />
The ''music'' key is a filename pointing to the music which plays. (See [[MusicListWML]] for more.)<br />
This music file must be in the ''music/'' directory and '''must''' be in .ogg format.<br />
<br />
A tag you'll get to know very good when making scenarios shows up: '''[event]...[/event]'''.<br />
Event tags are used to describe what should be done if an 'event' takes place. What this event is, is described by ''name''key. In this case we're describing the so-called 'prestart' event. This one takes place just ''before'' the game starts and just ''after'' all of the introductions screens were shown.<br />
Here we have limited the contents of the tag to another important tag: '''[objectives]''' (plural) containing any number of '''[objective]''' (singular) tags.<br />
For each '''[objective]''' (singular) tag, if ''condition'' is set to "win", the text of ''description'' will be displayed in green after "Victory" in the Scenario Objectives. If ''condition'' is set to "lose", the text of ''description'' will be displayed in red after "Defeat" in the Scenario Objectives. Because we've placed this tag inside a prestart event, this will be shown at the very first turn of the scenario.<br />
The ''side'' key indicates that these conditions are for side 1 (see below).<br />
The ' _ ' (underscore) facilitates translation using Gettext (see [[GetText]]).<br />
<br />
Note that ''ANY'' Victory or Defeat objective can be met to win or lose the scenario,<br />
but a single Victory objective may have multiple parts.<br />
Also note that the '''[objective]''' tag only describes what the objectives are. You will still need to set the appropiate events before they will work. (But that's again stuff for later)<br />
<br />
== Second part ==<br />
So far so good! The last necessary part describes what the players (Human and<br />
Computer) start with, what they can do and what they can't do. Each of the players is described in a '''[side]''' tag.<br />
<br />
. /\ <br />
. ||<br />
. continued from above<br />
[side]<br />
side=1<br />
controller=human<br />
team_name=2<br />
user_team_name= _ "Konrad's forces"<br />
<br />
type=Commander<br />
description=Konrad<br />
canrecruit=yes<br />
<br />
recruit=Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman<br />
<br />
{GOLD 100 50 0}<br />
{INCOME 10 5 0}<br />
[/side] <br />
[/scenario]<br />
<br />
Above you can see a sample '''[side]''' for the human player, Konrad. We wll describe every key more in detail below:<br />
* ''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.<br />
* ''controller'': possible values are 'human' or 'ai' (artificial intelligence, meaning your computer). If you don't specify this key, 'ai' is used as the default.<br />
* ''team_name'' describes which team the side is on. It defaults to the same number as ''side'', so setting it to ''2'' allies this side with side 2, if you haven't changed the team_name of side 2.<br />
* ''user_team_name'' is the name displayed when you view the sie stats (by pressing alt+s during gameplay). The underscore facilitates translation using GetText (see [[GetText]]).<br />
<br />
<br />
The next set of keys describe the leader of this side:<br />
* ''canrecruit'': This key can be 'yes' or 'no' (boolean equivalents 1 and 0 and true or false work too). If you no, then the leader won't be able to recruit. (Not much of a leader then, is he?) Any team without a canrecruit=yes unit automatically loses, so be sure to use this key.<br />
* ''type'' describes what type of unit the leader will be. The possible values are listed here: [http://units.wesnoth.org the unit tables].<br />
* ''description'' is the name and description of the leader.<br />
In a campaign, all of these 'leader-describing' keys are ignored for the human player (except ''canrecruit''), since the leader from the previous scenario is used instead. However, the ''type'' key is still neccesary to prevent the scenario from crashing.<br />
<br />
* ''recruit'' is a comma-separated list of types of units. The possible values are listed in [http://units.wesnoth.org the unit tables].<br />
<br />
<br />
Then two more preprocessors are used:<br />
* '''{GOLD easy normal hard}''' takes 3 positive numbers. These indicate the amount of money the player will start with on the EASY, NORMAL and HARD difficulty level.<br />
In a campaign file, inside a human controlled side (''controller=human''), this is the minimum amount. The actual amount the player gets can be larger if the player retained more from previous scenarios.<br />
* '''{INCOME easy normal hard}''' is similar, but indicates the base income.<br />
The defaults for each of these values are 100 gold and 2 base income.<br />
<br />
== Making it all work ==<br />
Now, to make this scenario playable, we need to make a campaign for it. (see [[BuildingCampaignsTheCampaignFile]])<br />
This should NOT be stored inside the main directory '''data/campaigns''' but inside '''userdata/data/campaigns'''. This prevents breaking the mainline campaigns or even worse, the entire game. (see [[BuildingCampaignsDirectoryStructure]])<br />
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).<br />
This is a short example on how to do this:<br />
<br />
[campaign]<br />
name= _ "Test Campaign"<br />
first_scenario=test-1<br />
difficulties=EASY,NORMAL,HARD<br />
<br />
difficulty_descriptions= _ "&elvish-fighter.png=Easy;*&elvish-hero.png=Medium;&elvish-champion.png=Hard"<br />
icon=elvish-fighter.png<br />
[/campaign]<br />
<br />
Campaigns are described in the '''[campaign]''' tag. The first key is ''name'', which is<br />
displayed on the campaign selector box. The second key is ''first_scenario'', which is<br />
the ID of the first scenario of the campaign. Scenarios following after this one are referenced inside the first scenario using ''next_scenario'' (see above).<br />
<br />
The key '''difficulties=EASY,NORMAL,HARD''' tells the computer to set the macro '''EASY''' if the first difficulty choice is chosen, '''NORMAL''' if the second is chosen, and '''HARD''' if the third is chosen.<br />
The expression '''#ifdef''' can be used later to test these macros. (see [[PreprocessorRef]])<br />
It is recommended that you do not use other names than '''EASY''', '''NORMAL''', and '''HARD''' for your macros, because if you do then the standard macros, such as '''{GOLD}''' and '''{INCOME}''', won't work properly.<br />
<br />
Two optional keys are ''difficulty_descriptions'' and ''icon''.<br />
''icon'' has value equal to an image, displayed inside the campaign list.<br />
''difficulty_descriptions'' must have the same number of inputs as '''difficulties''', most commonly three, separated by semicolons.<br />
These inputs then map on to the difficulties, so that if you have set difficulties to:<br />
"difficulties=EASY,NORMAL,HARD"<br />
the first input will specify the display on EASY, the second on NORMAL and the third on HARD.<br />
Each difficulty display description starts opens with an ampersand (''&''), then the image to display (eg ''elvish-fighter.png''),<br />
then an equals (''='') sign, then the text to display (eg ''Easy'').<br />
Optionally you can place an asterisk (''*'') before one of the ampersands, and the corresponding difficulty will be selected by default (here NORMAL is default).<br />
<br />
== See Also ==<br />
* [[BuildingMaps]] & [[WesnothMapEditor]]<br />
* [[ScenarioWML]] & [[SyntaxWML]]<br />
* [[BuildingScenarios]]<br />
<br />
[[Category:Create]]</div>Salocin