View Full Version : How to Create Your Own Custom Include Functions!

07-05-2014, 07:55 AM
How to Create Your Own Custom Include



Hey Guys, It's been a little too long since my last tutorial so I wanted to throw together a quick tutorial on how to create your own personal custom include.

Or in other words, show you how to create your own custom functions that will show up in the Functionlist in Simba for you to use in any and all of your future scripting projects.

This Tutorial will help with, Old School, and RS3, or even nonRSBots.

This tutorial will use Old School for any examples, so it should most likely belong in the "OSR Intermediate Scripting Tutorials" section if masterBB or someone wants to move it there for me :) (I'm not yet qualified to post there).


All you need is a firm grasp on the basics of scripting. I'm going to go out on a limb and say if you are curious about writing your own custom include additions, it's more than likely you're qualified to do so.


Educational Benefits:

Understanding how to write your own include will give you a much better understanding as to how and why Simba works the way it does.

Functional Benefits:

If there's a certain task you find yourself coding into multiple scripts that requires the use of multiple Procedures/Functions, writing your own include will allow you to more efficiently complete that task in future scripts, allowing you to write better, cleaner looking scripts in less time.

If you see a small adjustment you can make to an already created function that will make it work better for your specific needs, being able to add your own function will allow you to make your own adjustments to that function and add it to your own custom include.


Newbie Warning

I am writing this tutorial having just worked out how to do this a day before starting this tutorial.
The upside: I am able to relate to people who are trying to learn, having just learned how to do it myself.
The downside: Having just taught myself how to do it, I may not do things the most efficient way. If you see any errors or inefficiencies in this tutorial, I'm sure you'll let me know : )

Compatibility Warning

Using functions from your own custom Include will break your script for anyone who doesn't have your include, this can be overcome by just copying and pasting any of the custom functions you create into the top of your script. The functions should be added in after Global Variables, but before the functions are actually used.

Getting Started

Alright, If you're still reading I applaud your natural endurance for reading useless information, so let's get to the good stuff before you realize you're 300+ words in and haven't actually learned anything yet!

What is an Include

An include is a .simba file that contains 1 or multiple functions/procedures that you can reuse in any of your scripts, you get the ability to reuse these functions/procedures in your script by adding a path pointing to this .simba file at the top of your script.
ex. {$I SRL-OSR/SRL.Simba}

If that doesn't make sense to you yet, that's fine, read it again after you go through the tutorial, if it makes sense then, that might just mean ya learned something :)

Note: Technically I'm not sure if it's the path at the top of your script (ex. {$I SRL-OSR/SRL.Simba}) or the file containing all the functions that's technically the include. Being that you need both a path and a file, I will be referring to the combination of the 2 as the include.

I'll be referring to just the path as the include path.

and I'll be referring to the file as the include file.

How to create an include

Creating your own personal include is a pretty simple 2 step process.

1. you need to write your own functions (Easy-Med If you have some basic scripting abilities)
2. you need to add a path to your script to point to those functions (Easy)

Understanding the include

To understand how to create your own include, it helps to understand how a current include works, I'll use the Old School include as an example.

As you may likely know, to add the old school include to your script, you just need to add the include path:

{$I SRL-OSR/SRL.Simba}

To the top of your script.

Let's take a look at what's going on here.

This appears to be a path to opening up the SRL.Simba file found here:


Note: While I'm not sure where the instructions are that tell the path to start in the Includes folder, just keep in mind when we're writing the include path to your own custom include file that the folder named Include is where the path starts (I'll mention it again when we get to that part.)

So for curiosity sake, let's crack open that file and scroll down to ~ line 54.

As you can see, we have a whole lot of include paths:

{$include SRL-OSR/SRL/core/globals.simba}
{$include SRL-OSR/SRL/core/math.simba}
{$include SRL-OSR/SRL/core/mouse.simba}
{$include SRL-OSR/SRL/core/color.simba}
{$include SRL-OSR/SRL/core/players.simba}

//-- SRL Level 2 Includes --//
//-- --//
//-- Interface and OCR routines. --//

{$include SRL-OSR/SRL/core/text.simba}
{$include SRL-OSR/SRL/core/timing.simba}
{$include SRL-OSR/SRL/core/SRLlog.simba}
{$include SRL-OSR/SRL/core/chat.simba}
{$include SRL-OSR/SRL/core/bitmaps.simba}
{$include SRL-OSR/SRL/core/amount.simba}
{$include SRL-OSR/SRL/core/gametab.simba}

What's happening here is a kind of 2 step, multi-tiered include process.

When you add {$I SRL-OSR/SRL.Simba} to the top of your script, what you're really doing is adding this SRL.Simba include file into your script.

The SRL.Simba include file contains include paths to all of the other include scripts that are in the old school Includes (These can be seen on the left side of simba). in other words, every single function in the includes functionlist on the left side of simba is actually in your script, you just don't see it, and it's all added thanks to this SRL.Simba file.

If it didn't work that way, you would need to be adding an include to the top of your script for every group of functions you wanted to use.

Making Your Own Include Path

While technically step 1 was to create our Include file, in order to make the file, we should know where to save it first, so I'm going to start with explaining how to make the include path.

Your custom include file should be saved in your own folder created directly inside the Includes folder (C:\Simba\Includes).

If you save your includes folder inside one of the other folders already contained within the Includes folder (ex. SPS, SRL, SRL-6, or SRL-OSR) an update may remove your functions!
(Special Thanks to masterBB for bringing this to my attention, I was originally saving my includes within the SRL-OSR Folder!)

First, lets run through a theoretical example seeing as we don't actually have our own includes file yet.

Let's pretend we have our include file saved here: C:\Simba\Includes\MysteryIncludes\mysteryfunctions .simba

Now we need a way to tell our script where that mysteryfunctions.simba includes file is saved at.

There are 2 ways to accomplish this:

1. You can add an include path directly to the top of your script to tell your script exactly where your include file is located
{$I MysteryIncludes/mysteryfunctions.simba}

This method is nice and easy, This is what I'll be demonstrating in this tutorial.

2. Create an include file that points to any number of other include files. This is the multi-tiered method used by Simba shown in the previous section, doing this is beyond the scope of this tutorial, if you want to figure out how, try to reproduce what the SRL.Simba file is doing but with your own set of Include files.

This is the best solution for anyone who has a large amount of custom functions as it gives you the ability to create multiple include files allowing for better organization of your functions while only needing to add 1 include path to the top of your scripts.

Action Time

Now that we have all that theory nonsense down, let's take some action and put it altogether. For best learning results, follow along to create your own custom include.

Action Steps

Step 1
Open up Simba, delete everything so you have a completely blank script, Include files don't require a main loop or program name.

Step 2
Save that file anywhere under the Includes folder as whateveryouwant.Simba (replace whateveryouwant with whatever you want your include to be called)

Note: Whatever you name this file is what will show up in the functionlist in Simba.

I'm going to go with the example from the previous section and save mine as mysteryfunctions.simba in a folder I made named MysteryIncludes.

C:\Simba\Includes\MysteryIncludes\mysteryfunctions .simba

Step 3
Now that we've created our includes file, now lets make our includes path.

Starting from the include folder I have MysteryIncludes\mysteryfunctions.simba so my path will be:

{$I MysteryIncludes/mysteryfunctions.simba}

Note: For whatever reason when people write include paths they seem to always use forward slashes as opposed to the backslash windows uses, I'm not sure why, but I'll follow suit.

Step 4
Add whatever path you created to the top of any script after the program name (I usually add mine right after
{$I SRL-OSR/SRL.Simba} ) I'll be using my path: {$I MysteryIncludes/mysteryfunctions.simba}

Step 5
If you did everything correctly, take a look at the functionlist in your script.

Expand the Includes and look around, you should see your includes file name, in my case, mysteryfunctions.

you'll notice there's no arrow to expand the include, that's because we gots no functions in our include.

What you can do is double click on the name of your include in the functionlist and it will open up that empty include file we made, do that now (or just open it how you normally would open any simba file), next were gonna learn a little bit about writing our own functions with a pretty awesome custom function!

Writing Your Own Includes Function

Now for the good stuff!


Writing your own functions for your include is very similar to writing functions in any script you write, I'm going to assume you know basic scripting so I'm just going to go over the things you don't usually do in everyday scripting that are required when writing an includes function or procedure.

For this demonstration I'm going to use my FindColorsToleranceCTS2 Function:

function FindColorsToleranceCTS2(var Points: TPointArray; Color, x1, y1, x2, y2, Tolerance: Integer; HueMod, SatMod: Extended) : Boolean;

DefaultCTS: Integer;
DefaultHueMod, DefaultSatMod: Extended;

DefaultCTS := GetToleranceSpeed;
GetToleranceSpeed2Modifiers(DefaultHueMod, DefaultSatMod);

SetToleranceSpeed2Modifiers(HueMod, SatMod);
Result := FindColorsTolerance(Points, Color, x1, y1, x2, y2, Tolerance);

SetToleranceSpeed2Modifiers(DefaultHueMod, DefaultSatMod);

By default FindColorsTolerance uses CTS1 which is a much less accurate way to find colors as opposed to CTS2.

When using AutoColorAid you can set it to use CTS2 but you will get 2 extra values, HueMod and SatMod with nowhere to input them in the standard FindColorsTolerance function.

the way you use CTS2 in your script is a 5 step process:

1. Grab the default Color Tolerance Speed and the default HueMod and SatMod values. This is done with the GetToleranceSpeed and GetToleranceSpeed2Modifiers procedures, these will be save in variables for later use.

2. Then you need to set the color Tolerance Speed to 2 using the SetColorToleranceSpeed Procedure.

3. Then you set the HueMod and SatMod by using the ToleranceSpeed2Modifiers prodeure.

4. Then you run the standard FindColorsTolerance function which will now use CTS2 and the mods.

5. Finally you should always reset the color tolerance speed and the Hue and Sat Mods back to their default values.

Kind of a lengthy process to do over and over again every time you want to call a color using CTS2, luckily we're writing our own functions so we only have to do all that once!

Getting Started

The first thing you'll probobly notice that's very different to how you normally script is the first line.

function FindColorsToleranceCTS2(var Points: TPointArray; Color, x1, y1, x2, y2, Tolerance: Integer; HueMod, SatMod: Extended) : Boolean;

As you can see, up until, "function FindColorsToleranceCTS2" everything looks rather familiar, like the many functions you've likely written before, but things start to get interesting after that.

To my understanding, everything within the () is referred to as Parameters.

When you're using a function in your script, for example, say you use FindColorsTolerance.

You'll see FindColorsTolerance(var Points: TPointArray; Color, xs, ys, xe, ye, Tolerance: Integer): Boolean

While I was always under the impression that the parameters were just there to tell you how you use that function and what kind of values should go in each parameter, there's actually a bit more to it.

It turns out the parameters are the actual variables used in the include function.

For example, say in your script you enter:

FindColorsTolerance(ColorLocations, 764503, MSX1, MSY1, MSX2, MSY2, 5);

What's really happening is FindColorsTolerance is taking those values you entered in your script and making them equal to the variables displayed in the Parameters so they can be used in the include.

See if this makes any more sense:

FindColorsTolerance(var Points: TPointArray; Color, xs, ys, xe, ye, Tolerance: Integer): Boolean; // The FindColorsTolerance Function
FindColorsTolerance(ColorLocations, 764503, MSX1, MSY1, MSX2, MSY2, 5); //Using that FindColorsTolerance in your script

Points := ColorLocations
Color := 764503
xs := MSX1
ys := MSY1
xe := MSX2
ye := MSY2
Tolerance := 5

So now when you're working with the include function you will be working with the variables: Points, Color, xs, ys, xe, ye, Tolerance, and they will automatically be equal to whatever is put into the corresponding place in the function input in the script.

Back to the Function

So now that (hopefully) you have a halfway decent idea of how all that works, let's get back to the example:

function FindColorsToleranceCTS2(var Points: TPointArray; Color, x1, y1, x2, y2, Tolerance: Integer; HueMod, SatMod: Extended) : Boolean;

Those of you who are a little more observant may see a similar syntax with setting up parameters and setting up variables, just all on 1 line as opposed to one line for each data type, and you would be right, as that's pretty much exactly what we're doing.

In fact, setting your parameters is viewed the same as declaring variables, if you try to declare these variables in the var section of your include function you will get an error stating you are declaring the same variable twice.

Parameters are what you use to tell whoever may be looking at your function, what values you need in order to make your function work.

If you go back to the steps required for making a CTS2 Color Finder, you will see the unique values we will need in order to make this function run are:

All of the variables required for FindColersTolerance, as well as the hue and Sat Mods, which as you can see is what the function is looking for in the parameters.

One last thing I need to bring attention to is the the var at the beginning:
FindColorsToleranceCTS2(var Points: TPointArray; Color, x1, y1, x2, y2, Tolerance: Integer; HueMod, SatMod: Extended) : Boolean;

Adding this var is what allows the function to return the TPA created in the function to the ColorLocations (or whatever you decide to name the TPA Variable) variable, if you don't have that var in there, this function will not be able to pass the TPA back to your script:

Visual Representation:

ColorLocations > Points > ColorLocations

without the Var
ColorLocations > Points

When you run the function without the var it will still run, but the TPA will be empty.

The Rest of the script

Now the rest of the script is just a matter of writing a function how you normally would and just inputting your function variables wherever the values are required.

So in my case, my whole Includes file will just be (I threw in some comments to make it a bit easier to understand):

function FindColorsToleranceCTS2(var Points: TPointArray; Color, x1, y1, x2, y2, Tolerance: Integer; HueMod, SatMod: Extended) : Boolean;

var //these variables are required for resetting the CTS, we don't need any user interaction with these variables that's why they are in the var section as opposed to the funtion parameters.
DefaultCTS: Integer;
DefaultHueMod, DefaultSatMod: Extended;

DefaultCTS := GetToleranceSpeed; // grabbing the default CTS So we can switch back to it when we done using our CTS2 Color
GetToleranceSpeed2Modifiers(DefaultHueMod, DefaultSatMod); // grabbing the default Hue and Sat Mods
SetColorToleranceSpeed(2); // Setting the color Tolerance Speed to 2
SetToleranceSpeed2Modifiers(HueMod, SatMod); // Setting the hue and Sat Mods to whatever was put in the huemod, and satmod parameters
Result := FindColorsTolerance(Points, Color, x1, y1, x2, y2, Tolerance); // Grabbing all this info from the parameters then setting the Boolean of our function to be the result of the FindColorsTolerance Boolean

SetColorToleranceSpeed(DefaultCTS);//Now that "Points" contains our TPA it's time to set the CTS back to what it originally was
SetToleranceSpeed2Modifiers(DefaultHueMod, DefaultSatMod); // same goes for hue and sat mod

Now all you have to do is save it and it will automatically show up in the includes of any script that has your include path (Restarting Simba may be required for changes to include file to show up)

So to use this include all you would need to use this new function the same way you use any other function, so just enter something along the lines of:

FindColorsToleranceCTS2(ColorLocations, 764503, MSX1, MSY1, MSX2, MSY2, 5, 0.46, 0.22);

And you have yourself your own custom CTS2 Color finder.

Note: All in all I'm guessing this all sounds quite a bit more complicated than it actually is, once you do this once or twice I'm sure you will realize just how easy it is and you'll be writing your own massive custom functions list to speed up and clean up your scripting in no time!

Thanks For Reading!

I appreciate you guys taking the time to read this.

If you enjoyed the tutorial or found it useful at all, nice comments always make the time to write the tutorial feel like time well spent :)

If you see any mistakes or room for improvement, constructive criticism is always welcome.

The best way to show your appreciation is to write your own tutorial to share with others.

More Good Tutorials = Lower Learning Curve for Beginners = Less Freeloaders = More Experienced Scripters = Better Functions and Scripts for Everyone

Not to mention trying to teach someone how to do something is one of the best ways to go from knowing how to do it, to understanding how it's done.

"To teach is to learn twice" - Joseph Joubert

~Mystery Muffin

Important Compatibility Warning (Again)

This is super important and I don't want to accidentally create a bunch of help threads because you skimmed over this warning at the beginning of the tutorial!

Using functions from your own custom Include will break your script for anyone who doesn't have your include, this can be overcome by just copying and pasting any of the custom functions you create into the top of your script. The functions should be added in after Global Variables, but before the functions are actually used.

Your script should work without your custom include path added to the top of the script before sharing it with others!

07-05-2014, 05:05 PM
I suggest putting the include files in a sibling folder instead of a child folder of srl-osr.


instead of


actually I am a bit confused. Is it part of srl-osr?

07-05-2014, 05:15 PM
Personally I put the include files in the srl-osr folder just so down the road I know those are my functions that I built to be used with old school, your way works good too as technically I'm pretty sure that function would work with both old school and RS3.

07-05-2014, 05:40 PM
It was more meant like this:

When you create your own include it is neither SRL nor SRL-osr. Though it might require one or both. But since you added includes in srl.simba you probably just want to extend srl?

You should extent srl when:
- You add non-script specific functions
- You intent to push them to github

You should create your own include when one of those two statements is false. If you edit SRL-OSR it will be very dificult for users to install your script with your include. Also note how updates remove some of your changes.

I think it would be better to not edit any of the srl files without the intention of pushing it to the git.

07-05-2014, 09:07 PM
Oh that's cool, I don't really know anything about github, I had no idea you could attempt to push your functions.

Also I didn't even think about updates removing your functions, though technically I'm not sure that it would with the functions being in a completely separate folder being called separately, I don't think an update would actually remove your folder, would it? I could definitely be mistaken.

Just to verify, if you add your own include file or folder directly in the Includes folder it will be safe from any updates?

Now that I think about it, I do see the errors in my ways, if it's not a part of the Simba Resource Library, it shouldn't be in one of the SRL folders, that's just plain old logical :p , sometimes the acronym SRL gets tossed around so much, you actually forget what it stands for.

Thanks a bunch for your help making the tutorial better and more accurate, I'll make the changes right away :)