Special encounters
It's one of the most common experiences while playing an Avernum game (you have played them, right?): your party steps on a certain space, causing something to happen. This something could be anything: a message appears, the party is damaged, monsters are spawned, or a cutscene begins. How is it possible for a scenario designer to choose between all these possibilities within the Editor? The answer is you can't; you need the power of scripts to handle this complexity.
Let's start with a basic example. When the party walks past a certain point, a message appears telling the player about the merchant and her guard. Use the special encounter tool to place a special encounter; it looks like a dot. The tool works much the same way as the bounding walls tool. Let's select the upper left corner to be beyond the north wall of the tunnel, and the lower right corner to be beyond the south wall. That way the party must pass through the special encounter, and thus will always see the message. After you select both corners, a dialog box will appear, asking you for a number. Just enter 10 and click 'OK'; you'll find out why in a moment. The two buttons to the right of the special encounter tool are also useful. The one with the eraser on it allows you to delete an existing encounter rectangle, while the one with a pencil on it allows you to modify the number you chose.
![[IMAGE]](/static/tutorial/specials/set-number.jpg)
So what is the significance of the 'special number' chosen above? This number indicates the state that will be run when the special encounter is triggered. The previous sentence might be confusing jargon right now, so I'll explain. Scripts consist of many different 'states' — blocks of code that are identified by a number. Through the Editor, we determine where each state will run. In the above example, you told the Editor that state 10 of the town script should run when the party steps on the blue rectangle. Now that we've specified all we can in the Editor, it's time to create the town script, and then write state 10. First, create a new .txt file in the pesky folder:
![[IMAGE]](/static/tutorial/specials/add-script.jpg)
You'll notice that there are a number of default scripts already added to the pesky folder. These are scripts that are used in almost every scenario, such as a script controlling town guards, or a script for opening and closing doors. Feel free to read these scripts if you want; they'll give you a good idea of what scripting involves. Don't worry if you can't understand any of the code yet. A note to Windows users: I recommend viewing the preinstalled scripts with a text editor like Wordpad instead of the simpler Notepad. The preinstalled scripts use Macintosh line endings instead of Windows line endings. This means that simpler text editors like Notepad won't make any line breaks. 'Smarter' text editors like Wordpad will, though. Just right-click a script and choose Open With, and then pick the editor of your choice (if Wordpad doesn't appear, click Choose Default Program).
![[IMAGE]](/static/tutorial/specials/open-with.jpg)
But let's focus on the script you just created. You can pick any filename you want for the new script. I picked z0tunnel.txt: 'z' for zone (a town or dungeon), '0' because it's for town 0, and 'tunnel' as a reminder that this is for the merchant's tunnel. I recommend picking a consistent naming scheme for your scripts, for when you have more than one or two. The majority of scenarios out there use 't' instead of 'z' for town scripts. Personally, I prefer to use 'z', and use 't' to indicate a terrain script. Open the new script with the text editor of your choice, and enter in the following:
begintownscript; body; beginstate INIT_STATE; break; beginstate EXIT_STATE; break; beginstate START_STATE; break; beginstate 10; message_dialog( "You see a cart ahead, with a man in leather armour standing guard over a merchant by her wares.", "She seems upset about something." ); break;
Let's go through the parts of this script, section by section. Don't worry if you don't understand everything right away; it will become clear soon enough.
- begintownscript; This is the first line of the script, and it tells Blades of Avernum that this is a town script, rather than some other type of script.
- body; This line tells Blades of Avernum that all following lines of code are states. A state begins with the line beginstate STATE_NAME_OR_NUMBER;, and ends with the line break;. Everything between those lines is code that is run whenever the state is triggered.
- beginstate INIT_STATE; All town scripts require three states to be present. The first required state is the INIT_STATE. This state is triggered whenever the party enters the town. Since there is no code between the beginstate and the break, nothing extra happens when this town is entered.
- beginstate EXIT_STATE; The second required state is the EXIT_STATE, which is triggered whenever the party leaves the town. Again, there isn't any code in this state, so nothing extra happens whenever the party leaves the town.
- beginstate START_STATE; This state is triggered every single turn the party stays in the town. Once again, there's no code here, so nothing extra happens.
- beginstate 10; Finally, a state that has some code in it. Remember choosing the number 10 when you placed that special encounter rectangle? Whenever the party steps on that rectangle, this state is triggered, which means all the code inside it is run.
- message_dialog( ... ); Code inside a state is usually a list of function calls. What is a function? Functions are the main way scripts tell Blades of Avernum what to do in the game. There are many different functions that be called in a script; you can find them all listed in the Appendix (linked on the resources page). One such function is message_dialog, which when called displays a short message to the player. How does the game know what message to display? You have to put two strings (text surrounded by quotation marks) inside parentheses after the function name. For more information about the message_dialog function, look at its entry in the Appendix.
Alright, cool. You've written the code that will display the message to the player. But if you were to play the scenario right now, you wouldn't see the message you wrote appear. You still need to tell Blades of Avernum where to find the script you just wrote. Open your scenario in the Editor, then go to the Edit Town mode. Open the Town Details window (which you used in a earlier section). Here you will record the name of your town script. I used z0tunnel.txt as the filename for the town script, so I entered z0tunnel in the field.
![[IMG]](/static/tutorial/specials/set-script.jpg)
Now the game knows where to find the town script. Let's add a couple more special encounters to the game. First, place one covering the east exit of the town (the bottom right corner) with state number 11:
![[IMG]](/static/tutorial/specials/state-11.jpg)
We need a way for the party to leave the scenario. Write state 11 so that when the party enters the encounter rectangle, they leave the scenario. You'll need to use the end_scenario function, which is documented here. Add this state to your town script:
beginstate 11; // Using 0 means that the party won't increase its scenarios won count. end_scenario(0); break;
Wondering what the line starting with // is? That's a comment. Use comments to describe what your scripts are doing; comments have no impact on what your scripts do. However, putting comments into your scripts will make it easier for others to read your code. In fact, they'll help you read your own code too. Sometimes you'll have trouble understanding code you wrote months ago, and comments will help you remember.
Finally, we want to stop the party from leaving the tunnel until they've talked to the merchant. Put another special encounter rectangle across the western exit of the tunnel (the upper left corner) with state number 12:
![[IMG]](/static/tutorial/specials/state-12.jpg)
Now write state 12. Display a message to the player saying not to leave the town until after talking to the merchant, and prevent the party from leaving the town. You'll need to use the message_dialog function, and also the block_entry function.
beginstate 12; message_dialog("The merchant looks like she has something to say to you.", "(Talk to the merchant before leaving.)"); block_entry(1); break;
Congratulations! You've written your first script! Scripting may seem intimidating at first, but most of your code will be this simple; no more than half a dozen lines of code in each state. It's time to save your work (both the scenario itself and the town script), play your scenario, and see your script in action. Once you've played with it for a bit and seen the effects of your changes it's time to move ahead to the next section.