BuildingScenariosAdvanced

From The Battle for Wesnoth Wiki
Revision as of 21:25, 23 December 2011 by Bumbadadabum (talk | contribs)

Building scenarios: Advanced

TODO:

This contained a repetition of what was already inside BuildingScenariosIntermediate This should contain:

  • (more) information about making & using preprocessors (PreprocessorRef)
  • information on guidelines concerning the general layout of a scenario file
  • advanced filtering
  • ...

Ayone who feels like writing something, go ahead

Advanced Events

Internal Actions

See InternalActionsWML for a complete list of all tags and values. In what follows, the basics of variable creation and manipulation are explained.

Variables

(This can be skipped if you're familiar with the concept of variables)

(See VariablesWML for more)

What are variables? Variables are basically 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!

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.

Most variables provided by the engine are associated with a certain tag and can thus only be used inside them.

Manipulating

These three actions can be executed in one single tag: '[set_variable]' Say we wanted to store 'Hello World' in a variable named message_to_the_world. This is how we would do this:

[event]
.
.
.
  [set_variable]
    #The name of our variable:
    name=message_to_the_world
    #The value of message_to_the_world, notice the underscore!
    value= _ "Hello World!"
  [/set_variable]
 .
 .
 .
[/event]

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. If we want to add something to our message we need to use this:

[event]
.
.
.
  [set_variable]
    name=message_to_the_world
    value= _ "$message_to_the_world Have a nice day!"
  [/set_variable]
 .
 .
 .
[/event]

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:

[event]
.
.
.
  [set_variable]
    name=number_x
    value=10
  [/set_variable]
  [set_variable]
    name=number_x
    add=-9
  [/set_variable]
  [set_variable]
    name=number_x
    multiply=200
  [/set_variable]
  [set_variable]
    name=number_x
    multiply=0.5
  [/set_variable]
 .
 .
 .
[/event]

In the above, we set a variable named number_x to the value of 10. We subtract 9 (=1), multiply with 200 (=200) and divide by two (or multiply with 0.5) resulting in 100.

Using Variables

Now that we know how to create and manipulate variables, we'll learn how to use them. First of all, you need to know what variables you always have at your disposal! In an event tag, these variables are

  • side_number: the number of the current player's side (may be empty during start or prestart events)
  • turn_number: the number of the current turn (may be empty during start or prestart events)
  • x1: this is the x-coordinate of the location where the most recent event was triggered
  • y1: this is the y-coordinate of the location where the most recent event was triggered
  • x2: this is the x-coordinate of the location that assisted in triggering the most recent event
  • y2: this is the y-coordinate of the location that assisted in triggering the most recent event
  • unit: inside an event, this is the unit at $x1,$y1
  • second_unit: inside an event, this is the unit at $x2,$y2
  • this_unit: inside a standard unit filter, this is the unit currently being considered for a possible match.

Some of these are only containers for other variables. The unit variable is an example. You can acces those 'sub'-variables by using dots:

unit.hitpoints
unit.side
...

We will use unit in an example to show you how you can use all this:

[scenario]
.
.
.
  [event]
    #A unit moves onto a tile:
    name=moveto
    [filter]
      x,y=25,26
    [/filter]
    
    
    [set_variable]
      name=unit.hitpoints
      add=-5
    [/set_variable]
    [set_variable]
      name=unit.status.poisoned
      value=yes
    [/set_variable]

    #After we have changed the values, we need to apply them.
    #We do this by using the unstore_unit tag like this:
    [unstore_unit]
      variable=unit
      find_vacant=no
    [/unstore_unit]
  [/event]
  #We're finished!
.
.
.
[/scenario]

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 variable 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 InternalActions.

As of version 1.9, this can also be done much easier:

  [event]
    #A unit moves onto a tile:
    name=moveto
    [filter]
      x,y=25,26
    [/filter]
    #modify the unit   
    [modify_unit]
        [filter]
            x,y=25,26  
        [/filter]
        hitpoints=$($unit.hitpoints - 5)
        status.poisoned=yes
    [/modify_unit]
  [/event]
  #We're finished!
[/scenario]

You also might have seen that there's sometimes a Dollar sign ($) in front of a variable name. This indicates that the engine will replace the '$your_variable_name' with the exact value of this variable. Example:

[set_variable]
  name=my_variable   # here you refer to the variable itself
  value=5
[/set_variable]
[message]
  speaker=narrator
  message= _ "Your variable's value: $my_variable"  # will be showed as "Your variable value: 5"
[/message]


GetText & Translations

As Viliam pointed out (reordered his words):

Translating programs has two steps. The first step is making [...] scenarios that are
possible to translate; preferably easy to translate. [...] The second 
step is the translating of the texts... leave this to  translators.

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 localization settings. To make it ever more clear, here's an example:

.
.
.
[message]
  speaker=Konrad
  message= _ "I am mighty Konrad! I fought many dummies and now I will fight you!"
[/message]
.
.
.

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.

Viliam also said:

The most important rule of all is: Do not split sentences.
In some languages placing a word in a sentence requires more than mere string concatenation.
Some languages use declension.

Quick Tag Index

ScenarioWML the top level tags [scenario], [multiplayer], [test], and [tutorial]

See Also