May 4, 2015

Tutorial: Making a Telepath Tactics Campaign, Part 17

<< Continued from Part 16

A. Creating a script

The time has come for us to learn about scripts! For those of you who already know how to program: scripts are basically just functions. For those of you who don’t: you know how we can add script actions to branches of dialogue? A script is basically just a free-standing bundle of script actions. It isn’t attached to any one conversation or branch of dialogue; it exists out in the ether, waiting to be called to action, at which point it’ll run all of its actions in order.

This is basically what a script looks like:

<Script>The name of the script
<Action>action name/action parameters</Action>
<Action>action name/action parameters</Action>
<Action>action name/action parameters</Action>
</Script>

As you can see, each script consists of <Script></Script> XML tags, with a script name and a bunch of actions inside it. The dialog tree editor will eventually have support for creating these, but for now we have to place them by hand.

Giving the script a name is important. We can use the Run action with the script’s name as a parameter to run the script from inside any conversation. This is a handy way to avoid having to type out script actions over and over again in different conversations–we can just bundle them into a single script, then call that script whenever we need it!

For example: suppose that we have a level filled with locked doors, and multiple conversation branches in the level that will unlock them all. Rather than using an Unlock action for every door in every branch that unlocks the doors, we can create a script to unlock all of the doors…

<Script>Unlock Doors
<Action>Unlock/4,8</Action>
<Action>Unlock/5,5</Action>
<Action>Unlock/6,12</Action>
<Action>Unlock/10,3</Action>
</Script>

…and simply run it whenever it’s needed:

<Action>Run/Unlock Doors</Action>

This saves us a whole lot of typing! Even better, if we change something later–like the coordinates of one of the doors–we then only need to edit the Unlock parameters in the script, rather than finding and editing every single Unlock action referencing those coordinates spread throughout one or more conversations.

B. Tying a script to an item

Scripts are not just useful for dialogue–you can trigger scripts using items and objects in the game world. We’ll discuss how to tie scripts to items now.

Tying a script to an item is easy: just stick the script name in between the <Item> tags. Items that are useableWith triggered or automatic will then run the named script whenever they are used or grabbed off the battlefield, respectively.

For example: I use a script with the game’s various coin bags to represent the acquisition of money. Here is “25 Coins,” the game’s lowest-tier money item:

<Item name=”25 Coins” useableWith=”automatic”…>Gain25Coins</Item>

This runs the Gain25Coins script every time that item is grabbed off the battlefield. The Gain25Coins script, in turn, is kept in PersistentDialog.xml so the game can access it no matter what scene the coin bag appears in.

And here’s the script that it runs:

<Script>Gain25Coins
<Action>SetVal/Money,+,25</Action>
<Action>SpawnFloatingTextAt/Got 25 aura!,-Y-,-X-,0xFFFF00,45</Action>
<Action>PlaySound/Coins Jingle</Action>
</Script>

As you can probably ascertain, it increases the custom Money value by 25, spawns yellow floating text at the Y and X coordinates where the item was grabbed, and plays the sound of coins jingling.

Another example–I use scripts for the game’s battle primers:

<Item name=”Expert Battle Primer” useableWith=”triggered”…>Use Greater Exp Tome</Item>

This tells the game to run the script Use Greater Exp Tome whenever the Expert Battle Primer is used. (I keep the Use Greater Exp Tome script in PersistentDialog.xml as well.)

C. Using scripts to run scripts

Scripts can run other scripts. For instance, the Use Greater Exp Tome script that we just discussed looks like this:

<Script>Use Greater Exp Tome
<Action>SetString/CurrChar,-FNAME-</Action>
<Action>Run/Gain100XP</Action>
<Action>PlaySound/Paper</Action>
</Script>

As you can see, it first sets a custom string called CurrChar to the full name of the character who triggered the script (that is what the -FNAME- special character stands in for). It then runs a second script called Gain100XP. This, in turn, is the Gain100XP script:

<Script>Gain100XP
<Action>GiveExp/-STR:CurrChar-,100</Action>
<Action>SpawnFloatingText/Gained 100 experience!,-STR:CurrChar-,0xFFFF00</Action>
</Script>

Notice how Gain100XP relies on the custom string CurrChar for the parameters of both its actions; we had to set CurrChar in Use Greater Exp Tome before we ran Gain100XP, or it wouldn’t have been available to use. As you can see, the order in which we run our actions is important!

You aren’t just limited to the “Run” action when you want to run a script, either. Remember those script actions we used to change the current dialogue branch based on custom variables: IfValGoTo, IfStringGoTo, and IfStatGoTo? All of these have variants that are exactly the same, except that they run a script instead of changing the dialogue branch: IfValRun, IfStringRun, and IfStatRun.

 

We’ve covered enough for now. Try creating your own scripts. In the next part of the tutorial, we’ll learn about creating destructible objects and triggering scripts with them. See you next time!

 


Continued in Part 18 >>