Facebook Twitter YouTube Frictional Games | Forum | Newsletter | Dev Blog | Dev Wiki | Support


Post Reply 
 
Thread Rating:
  • 4 Votes - 4.25 Average
  • 1
  • 2
  • 3
  • 4
  • 5
A very basic scripting tutorial
Author Message
Russ Money Offline
Senior Member

Posts: 360
Joined: Dec 2010
Reputation: 3
Post: #1
A very basic scripting tutorial

Scripting Tutorial

Scripting and modding in Amnesia is probably the easiest practice that I have come across in my modding career. Every event is simply a set up and a call back which you will be able to (hopefully) comprehend after reading this tutorial. Not much coding experience is even needed to script for your custom story! These are the very basics and when you're finished with this tutorial you should be able to being writing your own events.

Setup

To start scripting, you'll first need a map to work from. Since this is not a mapping tutorial, we will not go over a lot of the level editor's functions, but will use some of them to help us script. For this tutorial we are going to pretend our map's name is Test_Map.map.

To create the script's file for that map, simply create a new text file with any text editor of choice then, open and save the file as Test_Map.hps. Make sure to spell and capitalize the file's name exactly as the map file's name.
This is also true for any future scripting.

Example: Your map's name happens to be dungeon.map, the script's name will be dungeon.hps

Now, to start scripting.

We are given three choices on how to set up our events for our map and we will be able to create more events within those functions once certain criteria is met. Those three choices are as follows:

void OnStart()
{

}

This is used to set up functions or callbacks when the player first starts the map.

void OnEnter()
{

}

This is used to set up functions or callbacks when the player enters the map.

void OnLeave()
{

}

This is used to set up functions or callbacks when the player leaves the map.

You can choose to use all three functions but, for this tutorial, we will only be using one: void OnStart(). As you can see, this command is followed by some curly brackets. { } The first curly bracket is the starting point of a list of commands we will be adding to OnStart where the other bracket is the end. You will want to place your functions/commands between these two symbols if you want them to happen when the player starts the map.

Callback Functions/Commands:

There are many commands that include callbacks in their function, but right now we're going to focus on a few that are commonly used when scripting. If you look at the command, you'll probably be able to guess what that command is used for. If you want a more detailed description, please check: http://wiki.frictionalgames.com/hpl2/amn..._functions

SetEntityPlayerInteractCallback(string& asName, string& asCallback, bool abRemoveOnInteraction);

This is used when the player interacts with an object, be it picking it up or grabbing a lever/door.

AddEntityCollideCallback(string& asParentName, string& asChildName, string& asFunction, bool abDeleteOnCollide, int alStates);

This is used when an object, the player, a monster (entities) collides/touches another entity, even a script area.

AddTimer(string& asName, float afTime, string& asFunction);

This is the command to add a timer to your map and begin a process of commands once the time is up.


There are many more ways to call a function when scripting in Amnesia, please check the HPL2 wiki for those functions and callbacks: http://wiki.frictionalgames.com/hpl2/amn...functions.


Putting It Together

Now that we have our map and script ready, let's begin with a simple script setup and event.
Copy and paste the following into your .hps file.

void OnStart()
{

}

Given, if you've played Amnesia, you've noticed that when you picked up a particular item, a monster appeared to slash your face off, so let's script just that.

This will take a bit of setup on your map; so add a enemy entity to your map. By default, the Brute's entity name is "servant_brute_1" You can see the entity's name by selecting (clicking on) the entity and looking under the general tab on the right-hand side. Under the Name, is a checkbox called Active, meaning the entity appears in the map without any callback. Uncheck this box, making the Brute into a fuzzy looking entity in the editor. We will also need an item that the player will be picking up to activate the Brute. For this tutorial, we'll use a tinderbox. Place a tinderbox in your map and select it. You might have some tinderboxs in your map already so rename this particular tinderbox to "monster_tinderbox". Make sure this tinderbox is active, else the player will not be able to interact with it.

Back to scripting; So, the plan for this script will be, once the player picks up, or interacts, with the "monster_tinderbox" the Brute will become active. We'll need to add the callback for the Brute to become active.

Change your script accordingly:
void OnStart()
{

SetEntityPlayerInteractCallback(string& asName, string& asCallback, bool abRemoveOnInteraction);

}

All I did was simply look for the command in the script function's wiki and pasted it BETWEEN the curly brackets. Now it's time to change some variables to the callback to match what we have in our map. Inside the ( ) of the SetEntityPlayerInteractCallback command, it's asking for those variables, each variable is separated by a comma.

string& asName, this is will be name of the Entity that the player will interact with, thus starting the callback.

string& asCallback, this will be the name of our callback function.

bool abRemoveOnInteraction, this is asking will the interact be removed on interaction with the particular entity.

Change your script accordingly:
void OnStart()
{

SetEntityPlayerInteractCallback("monster_tinderbox", "Spawn_Monster", true);

}

Looking at this command might not make sense to a lot of people so, let's break it down once again.

When the player interacts with "monster_tinderbox", the function "Spawn_Monster" will become active. The 'true' at the end will remove the interaction callback from happening again. The "Spawn_Monster" function was something I made up off the top of my head, the function's string can be named anything you like, just like we renamed the tinderbox.

Now we will need to add the function and command to set the Brute active. If you look at the script function's wiki, the syntax, or follow up for the callback, is in bold. void MyFunc(string &in entity)

MyFunc will be "Spawn_Monster" as it is asking for the name of the function we created.


Change your script accordingly:
void OnStart()
{

SetEntityPlayerInteractCallback("monster_tinderbox", "Spawn_Monster", true);

}

void Spawn_Monster(string &in entity)
{


}

Now that we have the structure for the function, we'll need to add a command to set the Brute to true to make him appear. Looking at the script wiki once again, there is such a command:

SetEntityActive(string& asName, bool abActive);

string& asName, this is asking which entity will be changed, for this tutorial, the name of our Brute.

bool abActive, this is asking if the entity is activated or deactivated.


Change your script accordingly:
void OnStart()
{

SetEntityPlayerInteractCallback("monster_tinderbox", "Spawn_Monster", true);

}

void Spawn_Monster(string &in entity)
{

SetEntityActive("servant_brute_1", true);

}


Save your changes, remove any .cache files and start your custom story. If everything has been done correctly, when the map starts, the "monster_tinderbox" has been given the callback for the function "Spawn_Monster" and the interaction is removed when picked up. Once this happens, "Spawn_Monster" will become true and set the "servant_brute_1" to true, making him active. He will not move, unless he hears or sees the player. To make him move, you will need to add path nodes which is not covered in this tutorial.

Tips for Scripting

I cannot stress enough that the wiki will hold all the answers you are looking for when trying to understand what command/function does what. Please search it (ctrl+f), for any function that will assist you in making your event. The folks here in the Frictional Game's community made it a lot simpler for everyone to understand, giving brief descriptions of what each string, bool, int and float does for that command.

http://wiki.frictionalgames.com/hpl2/amn..._functions

string - a variable that contains letters, or is a name, make sure to use quotes around strings
bool - true or false, no quotes needed
int - the state of a callback, normally a whole number, 1, 0 or, -1
float - a number that can be used with a decimal or whole number. When using a decimal, include a "f" after it, this is not needed for whole numbers. Example: 4 will be fine. 4.5 will be needed to be written as 4.5f. No quotes are needed.

Tools that will help you script:

Notepad++ - http://notepad-plus-plus.org/

There are other notepad tools used for scripting but I find this the easiest. But, this just a matter of taste.

TL;DR: READ THE WHOLE POST

Please post any questions you have about this tutorial.

06-28-2011 03:10 PM
Find all posts by this user Quote this message in a reply
TheDavenia Offline
Member

Posts: 223
Joined: Jun 2011
Reputation: 0
Post: #2
RE: A very basic scripting tutorial

Nice Russ,
You have helped me a lot lately on my custom story
I have seen your videos on youtube and they are noob friendly Tongue

Current Project: Nightmare's End(Project Director, Scripter, boss >:D)
06-28-2011 03:12 PM
Find all posts by this user Quote this message in a reply
Russ Money Offline
Senior Member

Posts: 360
Joined: Dec 2010
Reputation: 3
Post: #3
RE: A very basic scripting tutorial

(06-28-2011 03:12 PM)TheDavenia Wrote:  Nice Russ,
You have helped me a lot lately on my custom story
I have seen your videos on youtube and they are noob friendly Tongue

I help because I didn't have a lot of material when I started out. I'm just glad someone is reading/watching this stuff, haha.

06-28-2011 03:13 PM
Find all posts by this user Quote this message in a reply
Kyle Offline
Posting Freak

Posts: 910
Joined: Sep 2010
Reputation: 7
Post: #4
RE: A very basic scripting tutorial

Support. The more the better. This should get pinned so everyone can see it so they don't ask about how to do the stuff described in this thread. Smile

06-28-2011 03:35 PM
Find all posts by this user Quote this message in a reply
TheDavenia Offline
Member

Posts: 223
Joined: Jun 2011
Reputation: 0
Post: #5
RE: A very basic scripting tutorial

(06-28-2011 03:13 PM)Russ Money Wrote:  
(06-28-2011 03:12 PM)TheDavenia Wrote:  Nice Russ,
You have helped me a lot lately on my custom story
I have seen your videos on youtube and they are noob friendly Tongue

I help because I didn't have a lot of material when I started out. I'm just glad someone is reading/watching this stuff, haha.
Its nice you help out the noobs like me on the forums so much Tongue

Current Project: Nightmare's End(Project Director, Scripter, boss >:D)
06-28-2011 05:27 PM
Find all posts by this user Quote this message in a reply
Koen666pwnd Offline
Junior Member

Posts: 1
Joined: Sep 2012
Reputation: 0
Post: #6
RE: A very basic scripting tutorial

Hey, I'm sorry, I'm a real noob in this. I understand much of the scripts. what I don't understand (and maybe I'm just stupid) is the "{" and "}" part. When do u have to put an enter and when do u have to put 2 enters or none between a line and the "{ }" signs. And, when can I put more lines between one { }
09-03-2012 05:44 PM
Find all posts by this user Quote this message in a reply
Zaffre Offline
Posting Freak

Posts: 891
Joined: Jul 2012
Reputation: 30
Post: #7
RE: A very basic scripting tutorial

What about the "if" and "else" statements? I've gotten the rest down but I'm not sure I understand how this works.

:D
09-03-2012 06:11 PM
Find all posts by this user Quote this message in a reply
Post Reply 




User(s) browsing this thread: