Skip to main content

Scripting your levels

While levels can be nice to look at, they remain a bit dull if nothing ever happens. To get a bit of action going, we need to do a little bit of level scripting.

HPL implements a scripting language called AngelScript. This can be used for writing functionality into your level, by calling specific pre-defined functions. While the game engine itself is written in C++, you do not need to know anything of C++ to learn scripting in AngelScript.

A list of all available functions for ATDD can be found here.

Add a script file to your level

Scripts are simple text files with a .hps extension. The file name must match the name of the level you want to attach it to.

In our example, since we created the first_level.map level, we would name our script file first_level.hps. It should also exist in the same maps folder as where the level is found.

Next up we just need to open this text file with a code editor. While the default Notepad in Windows works, it isn't recommended. A good and simple option is Notepad++.

Let's write some scripts

If you've never done any programming or scripting before, check out this guide to learn more about the absolute basics. For now, we will just briefly go over some introductory content.

Let's add one of the most common functions to our script file – the OnStart hook.

first_level.hps
void OnStart()
{

}

This is one of 5 functions that the engine will look for and attempt to automatically run when a level is being played. As you can imagine, this particular function will run a single time when the level is first started. It normally never runs more than 1 time per playthrough, so it's a good place to add code that will only happen once.

Let's use this opportunity to add some music to our level.

first_level.hps
void OnStart()
{
PlayMusic("main_menu.ogg", true, 1.0f, 1.0f, 1, false);
}

PlayMusic is one of the pre-defined functions available for use. With this in the level script, upon starting the map you should hear some music start to play. If you're a little confused what all the different values mean, let's have a look at the function signature:

void PlayMusic(string& asMusicFile, bool abLoop, float afVolume, float afFadeTime, int alPrio, bool abResume);

A function signature has 2 components; a name (in this case "PlayMusic"), and a list of parameters (everything between the parentheses). This combination must always be unique, and is how the game will know which particular function you're trying to call. This means it's possible to have multiple functions with the same name if they have a different set of parameters.

In addition to this, each function also has a return type signified by a keyword at the start of the line. In this case this is void which is the keyword used when there's nothing being returned.

This function has a list of 6 parameters, which are as follows:

  • The first argument is a string type, and tells the game which sound file to play. This should match one of the .ogg files somewhere in the game folders, or you can try to add your own custom .ogg file.
  • The second argument is a boolean type, which says whether or not to loop the music file when it finishes.
  • The third argument is a floating point type, which specifies the volume to use for the music. 0.0f would be no volume, and 1.0f would be 100%.
  • The fourth argument is also a float. This one determines the time, in seconds, to use for fading the volume in from 0 to the target volume. Keeping this as 0.0f would instantly play the music at the volume given.
  • The fifth argument is an integer type, which just gives a simple priority to the music. Since only one music track can play at a time, the priority is used in case you have multiple PlayMusic calls. If you have only one, it doesn't really do much.
  • Lastly, the sixth argument is another boolean that says, in the case that you stop the music, whether it should resume from where it stopped (true), or resume from the start (false).