Table of Contents

Scripting Basics for Amnesia Mapping Beginners

So you want to map some stuff for Amnesia. Great! The world needs more custom Amnesia content. The first thing you will note when you try to pick up Amnesia and whip out really cool maps for it is one thing. The whole Amnesia map idea is intricately woven in script. Now some of you may know scripting, and the lucky of you even know the programming language this particular script is based on, C++.

This tutorial is designed to give complete program and script newbies a crash course, and might be helpful to some others, too.

Some Helpful Tips

Here are a set of tips for anyone who is going to try mapping and scripting for this game. First tip: Do not take this whole thing here as a first step! You're going to want to do some other things first. Grab the tools, set up a dev environment, set up a custom story, set up a small map, you know, the usual pre-script things. These tips are, of course, based on personal experience, so may be entirely bunk in some cases. Take with a grain of salt.


Addendum To Dev Setup

If you're mapping for Amnesia, likelihood is that you are mapping under a custom story, in the custom story folder in the Amnesia directory. You followed the custom story setup and the dev environment setup word for word, and that means there's a few mixups.

When you follow the dev environment setup word for word, it seems to cancel out the custom story effort. Loading something that you are working on in the custom story folder through the debug menu alone does not appear to load the custom story content, such as the extra language file and any entities in the custom stories folder. This forces you to work in the main game folders, and pack up everything you need when everything is complete. Or, you have to test frequently outside of dev mode. That is inefficient and prone to mistakes for me, so I found a quick fix for it, so the game will read the custom story content despite debug mode.

Towards the start of the development environment setup, you set some things in main_settings.cfg, in your user settings directory (My Documents for us Windows folk – and ~/.frictionalgames/Amnesia/Main for us Linux folks ). Open that file up again. We need to make just one change, I have found, to make custom story content load perfectly fine. Right after the start, of the file, you have a setting called 'ShowMenu'. If it says 'ShowMenu=“false”', change it to say 'ShowMenu=“true”'. That's it.

The main menu will pop up as if on a standard game. Pick the dev user profile, and check the custom story button. If your story is not in there, something went awry, but you caught it early. Check your story settings configuration file, and your language file, and make sure both don't have any issues. If your story is in there, you will load it up and be in debug mode, and all the custom story content will also load properly, so there is much less fidgeting amongst directories.

I haven't found anything to show that this is a bad idea, but if it is, feel free to edit a note in about it.


Use Something Better than Notepad

This may sound like a silly suggestion, but trust me, it is worth it. When a map picks up in size and complexity, a script file can lead into having 800, 1000, maybe even up to 2000 lines of script. Even the most sane programmer in the world would quickly lose his mind trying to work out 1000 lines of code in standard notepad.

The features of Notepad++ will literally save you sanity. In the least, download it, open your script files, and hit the 'Language' tab and set it to C++. It is worth the extra download.

End of story.


Open the Map in Amnesia BEFORE you Edit Script!

There is one universal about scripting and programming. You will make mistakes. You WILL make mistakes.

This tip makes it such that mistakes in scripting, rather than having the entire game come to its knees and crash, merely bark an error at you so you can fix it and try again really quick. The title of this tip? It says it all. If you change a script and it is wrong, two things can happen:

One, you did not have Amnesia open on the map, and you try to load the map. You will get a popup error which complains of some specific form of issue, often semi-descriptive as to where you messed your script up. Hitting the 'OK' on that prompt closes Amnesia. Obviously, this will drive you insane if you have numerous errors, because no one likes repeatedly starting and shutting down the game.

Two, you were in the map and made the change in script, and hit the 'Recompile Language and Script' button in the debug menu. It gives you a more polite little message with the same semi-descriptive issue as before. The difference here is this time, you can close that little message and stay right where you are, script away, and just hit the compile button again. Incredibly useful.

Scripting Syntax for Beginners

This section focuses on the syntax and flow of the scripting, for those who don't want to break into learning C++ before trying to script for Amnesia. If you are skilled in scripting and/or programming, and especially if you know enough C++ to know how functions look and work under it, you can likely skip the rest of this tutorial. This is to give beginners a fighting chance of actually understanding what they are doing, and becoming self-sufficient at the craft.

Lets jump right into this! Lets say you have a simple map already made… if you don't, head on back and check out the level editor tutorial, and whip up a nice small map, just a single room, and save it somewhere you can load it up easily in-game. Once you have that, open up your text editor of choice, and save a file in the same folder as your map, called “<YOURMAPNAMEHERE>.hps” (of course, without the quotes or <>'s. Make SURE that you don't save it as a 'text file', but that the file type saves as .hps). This is now a script file, and it is blank, and it does nothing. The following is what you might expect such an empty map's script file to look like, so feel free to copy and paste it in there:

Basic Example File

     //===========================================
     // Starter's Script File!
     //===========================================
 
     //===========================================
     // This runs when the map first starts
     void OnStart()
     {
          if(ScriptDebugOn())
          {
               GiveItemFromFile("lantern", "lantern.ent");
               SetPlayerLampOil(100.0f);
 
               for(int i = 0;i < 10;i++)
               {
                    GiveItemFromFile("tinderbox", "tinderbox.ent");
               }
          }
     }
 
     //===========================================
     // This runs when the player enters the map
     void OnEnter()
     {
     }
 
     //===========================================
     // This runs when the player leaves the map
     void OnLeave()
     {
     }

If you are new to scripting, you will likely catch wind of what some of that means, but other things be totally lost on. Lets take a look at it piece by piece.

Comment

First thing I have there, with the slashes, is a comment. That is just there to be readable to you, the writer of the script. It is not needed, it doesn't perform a function, it is completely ignored by the game.

OnStart

Going on down the line, we have 'void OnStart()' as the next meaningful line. This here is the 'definition' of a function, a special one. This one is called whenever the game sees the map and script file are first loaded. What shows us that it is a function? First, we have a data type, 'void', which basically is fancy program talk for 'nothing', or rather, 'when the function is used, don't expect anything back' (in programming C++, functions often return something, like a number; void does not do that). Next we have 'OnStart', which is just the name of the function, so nothing fancy there. Then we have '()', which is the argument list. There is nothing in it, because OnSt