Difference between revisions of "WML for Complete Beginners: Chapter 5"

From The Battle for Wesnoth Wiki
("last breath" and "die" Events)
(Nested Events)
 
(5 intermediate revisions by the same user not shown)
Line 15: Line 15:
 
  [event]
 
  [event]
  
As mentioned before, there are quite a few events available to you in WML. Of these, the most commonly used are the ''prestart'' event, the ''start'' event, and the ''moveto'' event.
+
As mentioned before, there are quite a few events available to you in WML. Of these, the most commonly used are the ''prestart'' event, the ''start'' event, and the ''moveto'' event. In our example here we shall also mention the ''last breath'' event, the ''die'' event, and the ''time over'' event.
  
  
Line 186: Line 186:
 
A rather typical time over event would look like this:
 
A rather typical time over event would look like this:
 
  [event]
 
  [event]
 +
    name=time over
 
     [message]
 
     [message]
 
         speaker=MyLeader
 
         speaker=MyLeader
Line 192: Line 193:
 
     [endlevel]
 
     [endlevel]
 
         result=defeat
 
         result=defeat
     [/endelevel]
+
     [/endlevel]
 
  [/event]
 
  [/event]
  
Line 314: Line 315:
 
             [objective]
 
             [objective]
 
                 description= _ "Death of your leader"
 
                 description= _ "Death of your leader"
 +
                condition="lose"
 +
            [/objective]
 +
            [objective]
 +
                description= _ "Turns run out"
 
                 condition="lose"
 
                 condition="lose"
 
             [/objective]
 
             [/objective]
Line 344: Line 349:
 
         [/message]
 
         [/message]
 
         [message]
 
         [message]
              speaker=unit
+
            speaker=unit
 
             message= _ "Hah! You missed!"
 
             message= _ "Hah! You missed!"
 
         [/message]
 
         [/message]
Line 375: Line 380:
 
         [/endlevel]
 
         [/endlevel]
 
     [/event]
 
     [/event]
  [/scenario]
+
    [event]
Congratulations!  You have now written your first functional scenario!  When you're ready to keep going, head to [[WML for Complete Beginners: Chapter 6]]
+
        name=time over
 +
        [message]
 +
            speaker=MyLeader
 +
            message= _ "I give up. This is taking too long..."
 +
        [/message]
 +
        [endlevel]
 +
            result=defeat
 +
        [/endlevel]
 +
    [/event]
 +
  [/scenario]
 +
Congratulations!  You have now written your first functional scenario!  Go, give it a try! Play it! When you're ready to keep going, head to [[WML for Complete Beginners: Chapter 6]]
  
 
or head back to [[WML for Complete Beginners: Chapter 4]]
 
or head back to [[WML for Complete Beginners: Chapter 4]]

Latest revision as of 14:48, 21 May 2018

Chapter 5: Events

Let's walk through an average morning. When your alarm clock goes off, you wake up. You go downstairs and put some bread in the toaster for breakfast. When the toaster pops, you butter the toast and eat it. When you have eaten breakfast, you go outside and wait for the schoolbus to arrive. When the bus arrives, you get on it. When it stops at your destination, you get off of the bus.

Notice that you do everything “when” something else happens. These are all “events”. The alarm going off caused you to wake up. The toaster popping causes you to butter the toast and eat it. Finishing breakfast go outside. The bus stopping causes you to get on or off. These are all like events in WML.

To give you examples of the real thing, i.e. playing Wesnoth: When you move somewhere, it’s an event. When you attack somebody, it’s an event. When you are hit, it’s an event. When a new turn starts, it’s an event. When you kill, or get killed, these are too - obviously – events.

It’s up to your decisions, which of these events you want to “catch”, to make them a turning point in the storyline.

The syntax for writing an event goes like this:

[event]
    name=name_of_the_event
    #do something
[event]

As mentioned before, there are quite a few events available to you in WML. Of these, the most commonly used are the prestart event, the start event, and the moveto event. In our example here we shall also mention the last breath event, the die event, and the time over event.


Common Events

Now, I'm not going to supply you with an exhaustive list of every kind of predefined event and what each does, that's what the EventWML page is for. I will, however, provide you with a list of the most frequently used predefined events and what they do, since we will be using these events in our campaign scenarios later on.

The "prestart" Event

This event fires before anything is shown on the screen for your scenario. This event is commonly used to recall loyal heroes for the player and to create loyal defenders. Anything you want to happen before the user can even see the map goes within this event. Think of it this way: everthing in the prestart event is done during the loading-screen before the scenario begins. To create this event, we use the following WML:
[event]
    name=prestart
    #do stuff here
[/event]
The prestart event does not require any additional keys (besides name=prestart) in order to function. However, we will not use this event in our sample scenario.

The "start" Event

The "start" event fires after the user can see the map and the screen, but before the user can actually do anything. To declare a start event, simply use
name=start
  • Objectives

A common use of the start event is to declare the objectives (The little window you can access by pressing CTRL + J) for the scenario.

One very important distinction here: The [objectives] tag only serves to display the objectives at the start of the scenario, NOT to program them into the game logic. The actual logic of defining the defeat/win outcome is written into other events, using the [endlevel] tag, as we shall see later. Now, back to the initial display of the objectives.

Declaring the objectives is done using two tags: [objectives] and [objective] like this:

[event]
    name=start
    [objectives]
        [objective]
            description= _ "Defeat the enemy leader"
            condition="win"
        [/objective]
        [objective]
            description= _ "Death of your leader"
            condition="lose"
        [/objective]
    [/objectives]
[/event]
Notice how the [objectives] tag encloses all the [objective] tags. Basically the [objectives] tag tells WML that you are going to start declaring objectives for the scenario, which are then represented by [objective] tags. Notice that the [objective] tag has two keys
description= _ "Describe the Objective Here"
condition= #put either "win" or "lose" here--win objectives are grouped together in green and lose objectives are grouped together in red.
  • [message]

Of course, the start event is also a good place to create an initial dialogue. This is done using the [message] tag. This tag has two keys:

speaker=
message= _ ""

The speaker tag contains the id of the unit who is going to talk. Remember in the last chapter how I gave our example leader an id of 'MyLeader'? Well, now he's going to give a short speech:

speaker=MyLeader

The message key represents what the speaker is actually going to say. This should be marked translatable:

message= _ "I see the orcs!"

I'm going to put this (and another) message into our example start event:

[event]
    name=start
    [message]
        speaker=MyLeader
        message= _ "I see the orcs!"
    [/message]
    [message]
        speaker=EnemyLeader
        message= _ "Grrrr!"
    [/message]
    [objectives]
        [objective]
            description= _ "Defeat the enemy leader"
            condition="win"
        [/objective]
        [objective]
            description= _ "Death of your leader"
            condition="lose"
        [/objective]
    [/objectives]
    
[/event]

While it doesn't matter to WML where you put events, it is good form to put them below the [side] tags so that others can read your WML more easily:

  1. 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]
    [event]
        name=start
        [message]
            speaker=MyLeader
            message= _ "I see the orcs!"
        [/message]
        [message]
            speaker=EnemyLeader
            message= _ "Grrrr!"
        [/message]
        [objectives]
            [objective]
                description= _ "Defeat the enemy leader"
                condition="win"
            [/objective]
            [objective]
                description= _ "Death of your leader"
                condition="lose"
            [/objective]
        [/objectives]
    
    [/event]
[/scenario]

The "moveto" Event

As you might have guesses, the "moveto" event covers when a unit moves. This event triggers after any unit moves and matches a given [filter]. What is this '[filter]' you ask? Let's take a quick look:

  • [filter]

The [filter] tag tells WML to apply this event only to units which match the filter. For example, what if I wanted to run my moveto event only when side 1 moves a unit onto hex 1,1? In that case, I would use:

[filter]
    side=1
    x,y=1,1
[/filter]

Simple, huh? Other common keys for a filter tag include:

id=MyLeader #id of a specific unit, such as our leader.
type="Elvish Shaman" #only Elvish Shamans would pass this filter.

To learn more about [filter]s, check out FilterWML. Now we could add a very simple moveto event to our example scenario:

[event]
    name=moveto
    first_time_only="no"
    [filter]
        side=1
        x,y=1,1
    [/filter]
    [message]
        speaker=unit #unit means the unit triggering this event--in this case the guy who just moved
        message= _ "Look at me!  I'm on hex 1,1!"
    [/message]
[/event]

"But you added a new key without explaining it...I'm confused!" Hang in there, I'm just getting to explaining that first_time_only key.

  • first_time_only

The "first_time_only" key has two possible values "yes" and "no". This key is actually present in every event, even if you don't type it in. In that case, it contains a value of "yes" (this is also called a default value). If first_time_only="yes", the event will only run the first time its conditions are met. In our example, this means that only the first unit to move onto hex 1,1 will announce his presence to the world. If, however, first_time_only="no" then every time a unit moves onto hex 1,1 will cause it to speak. This is what the example event does.

The "time over" Event

This event fires after all turns have run out. It is usually used to give a brief message before causing the player to lose the scenario. By the way, forcing a win/loss using WML is accomplished like this:

[endlevel]
    result=victory #or result=defeat to force a loss.
[/endlevel]

A rather typical time over event would look like this:

[event]
    name=time over
    [message]
        speaker=MyLeader
        message= _ "I give up.  This is taking too long..."
    [/message]
    [endlevel]
        result=defeat
    [/endlevel]
[/event]

"last breath" and "die" Events

These two events are very similar. Both events trigger when a unit (specified by [filter], known as 'unit') is killed by another unit (can be specified by [filter_second], known as 'second_unit'). However there is one, crucial difference. "last breath" occurs before a unit's death-animation is shown (before the unit visibly dies, but has <= 0 hitpoints) whereas "die" occurs immediately after the unit's death-animation. As a result, use "last breath" when you want the dying unit to give a last-breath message, and "die" for anything which occurs as a result of that death. Here is an example of using both of these events. See if you can figure out what exactly is happening:

[event]
    name="last breath"
    first_time_only=no
    [filter]
        side=2
    [/filter]
    [filter_second]
        side=1
    [/filter_second]
    [message]
        speaker=second_unit
        message= _ "Take that!"
    [/message]
    [message]
        speaker=unit
        message= _ "Hah! You missed!"
    [/message]
[/event]
[event]
    name=die
    first_time_only=no
    [filter]
        side=2
    [/filter]
    [filter_second]
        side=1
    [/filter_second]
    [message]
        speaker=second_unit
        message= _ "Wrong!"
    [/message]
[/event]

These two events fire every time side 1 kills one of side 2's units. When these events fire, here is what the player will see: "Take that!" -> "Hah! You missed!" -> Death animation -> "Wrong!"

Nested Events

Have you ever wondered what would happen if you did this (pseudocode example):

[event]
    name=event1
    (...)
    [event]
        name=event2
        (...)
    [/event]
[/event]

This is called nesting events because one event is "nested" inside the other. What happens here is that when event1 is triggered, in addition to whatever else event1 does, event2 is created. This prevents event2 from occurring before event1. Suppose we wanted to display a message after defeating the enemy leader (id=EnemyLeader) and moving our leader (id=MyLeader) to the enemy's keep (x,y=20,7). We could do that like this:

[event]
    name=die
    [filter]
        id=EnemyLeader
    [/filter]
    [event]
        name=moveto
        [filter]
            id=MyLeader
            x,y=20,7
        [/filter]
        [message]
            speaker=unit
            message= _ "Haha! I captured the enemy keep!"
        [/message]
    [/event]
[/event]
  • Further Information

For more information on events, how to write them, and how they work, go to the page on EventWML.

I'm going to insert a few of these sample events into our example scenario (and write a new "die" event for the enemy leader), which now looks like:

#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]
    [event]
        name=start
        [message]
            speaker=MyLeader
            message= _ "I see the orcs!"
        [/message]
        [message]
            speaker=EnemyLeader
            message= _ "Grrrr!"
        [/message]
        [objectives]
            [objective]
                description= _ "Defeat the enemy leader"
                condition="win"
            [/objective]
            [objective]
                description= _ "Death of your leader"
                condition="lose"
            [/objective]
            [objective]
                description= _ "Turns run out"
                condition="lose"
            [/objective]
        [/objectives]
    [/event]
    [event]
        name=moveto
        first_time_only="no"
        [filter]
            side=1
            x,y=1,1
        [/filter]
        [message]
            speaker=unit #unit means the unit triggering this event--in this case the guy who just moved
            message= _ "Look at me!  I'm on hex 1,1!"
        [/message]
    [/event]
    [event]
        name="last breath"
        first_time_only=no
        [filter]
            side=2
        [/filter]
        [filter_second]
            side=1
        [/filter_second]
        [message]
            speaker=second_unit
            message= _ "Take that!"
        [/message]
        [message]
            speaker=unit
            message= _ "Hah! You missed!"
        [/message]
    [/event]
    [event]
        name=die
        first_time_only=no
        [filter]
            side=2
        [/filter]
        [filter_second]
            side=1
        [/filter_second]
        [message]
            speaker=second_unit
            message= _ "Wrong!"
        [/message]
    [/event]
    [event]
        name=die
        [filter]
            id=EnemyLeader
        [/filter]
        [message]
            speaker=second_unit
            message= _ "Yeah! I killed him!"
        [/message]
        [endlevel]
            result=victory
        [/endlevel]
    [/event]
    [event]
        name=time over
        [message]
            speaker=MyLeader
            message= _ "I give up.  This is taking too long..."
        [/message]
        [endlevel]
            result=defeat
        [/endlevel]
    [/event]
 [/scenario]

Congratulations! You have now written your first functional scenario! Go, give it a try! Play it! When you're ready to keep going, head to WML for Complete Beginners: Chapter 6

or head back to WML for Complete Beginners: Chapter 4

Return to Main Index: WML for Complete Beginners

This page was last edited on 21 May 2018, at 14:48.