THE Beginner's Tutorial
This tutorial was last updated on September 23rd, 2012.
Introduction
Hello, and welcome to the first of three of my all-in-one scripting tutorials. This is a rewrite of the beginner's section of my
All-In-One SCAR Scripting Tutorial. Throughout this tutorial, you will learn many different scripting techniques, commands, and habits I’ve picked up during my time here at SRL.
As well as learning how to script in Simba, you will be learning the programming basics which will help you learn other, more complicated programming languages such as Java, Python or C/C++ (there are many more). Simba allows programming in the
Pascal programming language so naturally, that is the language I'll be teaching you.
I will be taking you through the different concepts step by step, starting with the basics. Keep in mind that no prior programming knowledge is required for you to understand this guide (but of course, it would be helpful).
Before continuing through this guide, you need to make sure you have installed Simba and SRL properly. If you don't know how to do this, you can follow this tutorial to do so ->
How to install/setup Simba! This is
very important: I highly suggest that as you read this tutorial, you
do the examples as they are taught to you. This way you will have a much better understanding of the concept.
I would also like you to please post any spelling/grammar/formatting mistakes I will probably make somewhere throughout the guide. If you want, this tutorial can be downloaded as a PDF,
new link coming soon
Table of Contents
- Simba - The Basics
- Knowing Simba
- The Basic Types
- Procedures and Functions
- Constants and Variables
- Putting it all Together
- Standards
- Scripting Tips/Hints
- Codehints/Simba Library
- Simba and SRL Documentation
- HotKeys
- The "Tab" Button
- Programming Statements
- If..Then..Else Statements
- Cases
- Loops
- Repeat..Until
- While..Do
- For..To..Do
- Internal Commands
- Try..Except..Finally Statements
- Putting it all Together
- The SRL Include
- DeclarePlayers & S.M.A.R.T.
- Failsafes
- Antiban and AntiRandoms
- Conclusion
Simba - The Basics
Knowing Simba
- When you open Simba, you will notice a blank script that looks like this:
- The program New; part is what your script will be called. The program can be changed to whatever fits your interest. For example, you could change it to "Bobs_Amazing_Woodcutter" or "JoesMiner". Notice the "_" used instead of " ", this is because in any programming language, there cannot be spaces in names. This includes the names of procedures and functions (more on that later).
- The begin..end. is called your Main Loop. Simba will read the code in your main loop as your script and run is as you please. If you would like Simba to run a function or procedure, you have to include them in your main loop. More on script structure later.
- Over on the left, you have the Functions List. You'll notice that there's several categories to choose from. These are all the built-in Simba functions that you can use at any time you wish.
- Just below the Functions List, you have the Library Search Bar. In my opinion, this is one of the most useful Simba features as it allows you to search for any function/procedure that you wish. Type in "Color" (without quotes), and watch as it narrows the list down to only the functions/procedures that contain the word "Color".
- At the bottom of the window you'll see a white box with some writing in it. This is called the Debug Box. Any errors you may have with yours or someone else's script, will come up in this box.
- Here is an image to better explain the Simba components.
The Basic Types
- This was taken straight out of the SCAR Manual, I couldn't have explained it better myself.
Procedures and Functions
- Procedures and functions are similar, yet different. Functions return a specified type such as a boolean or an integer whereas a procedure doesn't return any type, it just does what it's told.
- To start off, I am going to explain to you the structure of functions and procedures using the following example:
Simba Code:
function IntToStr(i: LongInt): String;
- The function part is where it determines whether a function or a procedure is going to be used. If a procedure was going to be used, it would take place of "function"..
- Following function, is the name of the procedure/function. In this case, the name is "IntToStr", which stands for Integer To String, and simply converts an integer to a string. The name can be anything you want, as long as it contains no spaces (like the program name).
- Inside the parentheses, we have the parameters of the procedure/function. In this example, there is one parameter, i. As you can see, i is declared as a LongInt, which is the same thing as an integer.
- Following the closed brackets is the Result of the function. In this case, the result is a string. However, the result can be whatever fits your needs (i.e. String, Integer, Boolean). Remember that this part is always left out of procedures. When I say "Result", I mean the undeclared variable that needs to be used somewhere in the function.
- The WriteLn procedure is a very useful procedure that can tell you why your script worked or why it didn't work. It is used a lot in a process called "Debugging" which simply means - removing all the bugs from your script so everything works well. All this procedure does is write the string (s) to the debug box.
Simba Code:
procedure WriteLn(s: String);
- Try this:
Simba Code:
program HelloWorld;
procedure WriteInDebugBox;
begin
WriteLn('Hello world!'); // Notice the ';' at the end of the line; make sure you have that at the end of each line, otherwise you will most likely get an error
end;
// Notice the ';' This must be at the end of every procedure/function in your script
// Only the "end" in your main loop should be followed by a '.' to signal the end of the the script
begin
WriteInDebugBox; // See how I call the procedure in my main loop? Without this step, the script wouldn't do anything
end.
- Now when you hit run (the green play button at the top of Simba), do you see the "Hello world!" in the debug box? That is probably one of the simplest scripts you're going to see. You can change "Hello world!" to anything that you want to see in the debug box.
- Try this:
Simba Code:
program HelloWorldFunction;
function GetNumber: Integer;
begin
Result := 10; // Because the function returns an integer, there is a variable "Result" that needs to be used; it needs to be set to an integer
end;
begin
WriteLn(IntToStr(GetNumber)); // Because Result is an integer, and WriteLn requires a string, we use IntToStr
end.
- Now when you hit run, you should see "10" in the debug box. Do you see the difference between a procedure and a function? It may not seem like much of a difference now, but once you get into more advanced scripting techniques, it will make a huge difference in your script.
Constants and Variables:
- Constants are usually declared at the beginning of your script, and remain constant throughout your whole script. They are declared like this, and can be used in any procedure/function throughout your script:
Simba Code:
program new;
// Constants should be in ALL_CAPITALS to easily distinguish what's a constant and what's a variable
const
LOGS = 100;
begin
end.
Pretty simple I'd say.
- Variables can be declared in two different ways:
- Globally - means you would declare it at the top of your script, and can be used throughout all procedures/functions. It can also be reset at any time.
- Locally - means you would declare it inside a procedure/function and would only use it for that procedure/function. It can only be reset in the function/procedure it was declared in.
Simba Code:
program Variables;
// Globally, should start with a capital letter then "camel-capped"
var
NumberOfLogs: Integer;
// Locally, should start with a lowercase letter then "camel-capped"
function WriteInDebugBox: Integer;
var
b: Boolean;
begin
// I can use "b" in this function only
// I can use "NumberOfLogs" in this function as well as other functions/procedures
end;
procedure SayHello;
begin
// I can use "NumberOfLogs" in this procedure as well as in the above function
end;
begin
end.
Not too hard, is it?
Putting it all Together
- Now that you've learned the absolute basics, we are going to make a small script, tying everything together. You'll also learn a few new useful commands in the process.
Simba Code:
program PuttingTogetherBasics;
// Declareing variables globally
var
Logs: Integer;
Exps: Extended;
// Declareing constants
const
NUMBER_OF_LOGS = 500; // Notice the integer
TREE_TO_CUT = 'Magic'; // Notice the string
// Using a procedure
procedure HowManyLogs;
begin
// This is how we ASSIGN a type to a variable; Remember this ;)
Logs := 250; // Notice we can use the variable "Logs" because it's declared globally
Exps := 195.5;
WriteLn('We have chopped ' + IntToStr(Logs) + ' logs this session!'); // Notice the '+', this is required if you are going to WriteLn a constant or variable
Wait(500); // This is new, but don't worry; this is a simple procedure that waits the given time in milliseconds (1000ms = 1s)
WriteLn('We want to chop ' + IntToStr(NUMBER_OF_LOGS) + ' logs.');
Wait(500);
WriteLn('We are chopping ' + TREE_TO_CUT + ' trees!');
Wait(500);
WriteLn('We have gained ' + FloatToStr(Logs * Exps) + ' xp this session!');
//FloatToStr is used to convert extended values to strings; it works the same as IntToStr
end;
// Using a function
function WeAreBored: string;
var // Declareing variables locally
s: String;
begin
Result := 'What are we going to do now?'; // Notice that "Result" is a string because the function returns a string
s := 'We are very bored chopping all these logs!';
Wait(500);
WriteLn(s); // Notice no "IntToStr" because the variable "s" is already a string
end;
begin // Don't forget to put your procedures/functions in the main loop!
ClearDebug; // This procedure just clears the debug box when you click run
HowManyLogs;
WriteLn(WeAreBored); // Since WeAreBored returns a string and WriteLn() takes a string as its parameters, the function itself can be called
end. //Notice the '.', signalling the end of the script
If there is something about that script that you don't understand, don't panic! Try looking back over the section you don't understand.
- You may ask what the point of a function like this would be. Well, this function could be used if you were going to make a progress report for your script. A progress report is something that is usually added to every script that keeps track of what the script has done. For example, how many logs it has chopped, or how many fish it has caught. Here are a couple example of progress reports in scripts I've made in the past.
Progress Report:
[=================================================================]
[ Coh3n's Draynor Chop N' Bank! ]
[============================ Rev.32 =============================]
[ ]
[ Ran For: 85 Hours, 28 Minutes and 38 Seconds ]
[ ]
[ Nick T/F Loads Logs Lvls Exp. Brks ]
[ ¯¯¯¯ ¯¯¯ ¯¯¯¯¯ ¯¯¯¯ ¯¯¯¯ ¯¯¯¯ ¯¯¯¯ ]
[ WC01 T 118 3302 14 222884 19 ]
[ WC02 T 115 3220 3 217350 17 ]
[ WC03 T 114 3192 3 215460 17 ]
[ WC04 T 110 3080 3 207900 17 ]
[ WC05 T 107 2995 6 202162 16 ]
[ WC06 T 96 2688 3 181440 15 ]
[ WC07 T 91 2548 10 171990 13 ]
[ WC08 T 107 2996 11 202230 16 ]
[ WC09 T 88 2463 7 166252 15 ]
[ WC10 T 82 2295 7 154912 13 ]
[ WC11 T 66 1848 5 124740 11 ]
[ WC12 T 65 1820 8 122850 12 ]
[ WC13 T 76 2127 6 143572 13 ]
[ ]
[=================================================================]
/=====================================================================================|
| Coh3n's Draynor Chop N' Bank! |
| - Revision 40 - |
|=====================================================================================|
| |
| Ran For: 34 Hours, 8 Minutes and 49 Seconds |
| Program: SCAR | SMART: Yes |
|______ ________ __________ _______ ________ __________ ________ ____________ ________|
|Alias | Active | Location | Loads | Tree | Logs Cut | Levels | Experience | Breaks |
|¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯|
| WC01 | True | Bank | 49 | Willow | 1,372 | 7 | 92,610 | 5 |
| WC02 | True | Bank | 43 | Willow | 1,204 | 2 | 81,270 | 4 |
| WC03 | True | Bank | 27 | Willow | 756 | 73 | 51,030 | 3 |
| WC04 | True | Willows | 59 | Willow | 1,652 | 73 | 111,510 | 6 |
| WC05 | True | Bank | 52 | Willow | 1,456 | 2 | 98,280 | 6 |
| WC06 | True | Bank | 43 | Willow | 1,204 | 3 | 81,270 | 3 |
| WC07 | True | Bank | 31 | Willow | 868 | 6 | 58,590 | 3 |
| WC08 | True | Willows | 22 | Willow | 616 | 1 | 41,580 | 1 |
| WC09 | True | Bank | 13 | Willow | 364 | 0 | 24,570 | 0 |
| WC10 | True | Willows | 29 | Willow | 809 | 0 | 54,608 | 3 |
| WC11 | True | Bank | 40 | Willow | 1,120 | 65 | 75,600 | 3 |
| WC12 | True | Bank | 51 | Willow | 1,428 | 2 | 96,390 | 5 |
| WC13 | True | Bank | 32 | Willow | 896 | 1 | 60,480 | 3 |
|-------------------------------------------------------------------------------------|
| Totals: | 491 | | 13,745 | 235 | 927,788 | 45 |
|_____________________________________________________________________________________|
|_____________________________________________________________________________________/
- If you successfully made the latter script, when you hit run, your debug box should say this:
Progress Report:
We have chopped 250 logs this session!
We want to chop 500 logs.
We are chopping Magic trees!
We have gained 48875 xp this session!
We are very bored chopping all these logs!
What are we going to do now?
Successfully executed
Congratulations! You have just made your first working script! Yay!
Standards
A simple definition of standards is the
way you write your code. Having good standards is extremely useful for debugging and readability. Anyone that reads your script will thank you for having good standards. I urge you to develop good standards as soon as you start scripting, so you get used to it faster, and don't have to change the way you code later.
There are many different rules you should follow when writing your code. They are as follows:
- When you indent, it will be two spaces. You can do this by hitting the "Tab" button on your keyboard, or simply hitting the space bar twice.
- Your script margins are set to 80 characters and is marked in Simba with a line straight down the right side of the scripting page. Try not to exceed that margin. If you do, no big deal, no one's going to kill you for it.
- The begin statement appears on its own line, and end statement always matches the begin statement by columns. For example:
Simba Code:
begin
if (Condition) then // Notice the intent after a "begin" statement
begin // Notice how the begin lines up with "if" in columns
DoThis;
end else
begin
DoThis;
end;
end;
Notice how all the begins and ends line up in columns. Also, you're probably wondering what the "if (Condition) then" is. Well, don't panic, it's called an if..then..else statement, and you'll learn more on that later. But, notice how the begin after the if statement is lined up with "if" in columns. Most people make the mistake of indenting the "begin" after an if statement, which makes their code harder to read.
- Use semicolons at the end of all your lines. Exceptions would be at the end of var, begin, then, else, repeat, do and before else (see the above example if you don't know what I mean).
- Try not to combine two or more statements on one line. Each statement gets it's own line.
Simba Code:
// Bad
if (Condition) then DoThis;
if (Condition) then begin DoThis; DoThat; end;
// Good
if (Condition) then
DoThis;
if (Condition) then
begin
DoThis;
DoThat;
end;
- Always use spaces after commas and arithmetical signs. This is also a common mistake with most scripts, and it really bugs me when people don't do this. It makes the script much harder to read without the spaces. Here is an example:
Simba Code:
// Bad
i:=(5*4+3);
HowManyLogs(1,5,10);
// Good
i := (5 * 4 + 3);
HowManyLogs(1, 5, 10);
- You should never have a white space on the inside of parenthesis. Example:
Simba Code:
// Bad
if ( i = 100 ) or ( k = 50 ) then
DoThis( DoThat );
// Good
if (i = 100) or (k = 50) then
DoThis(DoThat);
- Simba bolds keywords such as "begin, end, procedure, function, etc." These words should be entirely lowercase as it looks much better, and a lot of people find it easier to read.
- The names of procedures and functions should always begin with a capital letter and be camel-capped (i.e. Pascal case) for easier readability. Example:
Simba Code:
// Bad
procedure walktobank;
// Good
procedure WalkToBank;
- The names of procedures/functions/variables/constants should be given names meaningful to their content. A name like DoStuff is not meaningful, but name WalkToBank is. This includes a function's parameters.
- The layout of programming components should be easily distinguishable between one another.
- Constants should be entirely uppercase.
Simba Code:
LOGS_NORMAL = 0;
LOGS_OAK = 1;
- Global variables should start with an uppercase letter and then camel-capped (Pascal case). This should also be the same for a function's/procedure's parameters (excluding single lettered parameters).
Simba Code:
var
TotalLogs: Integer;
WhichTree: string;
- Local variables should start with a lowercase letter and then camel-capped (Camel case).
Simba Code:
procedure Example;
var
i: Integer;
tempString: string;
begin
end;
You may not like the look of some of these, so you don't have to use them. There are some programming languages out there that have forced standards. Thankfully, you don't have to worry about that as Pascal has no such thing.
- Where possible, parameters/variables of the same type should be combined into one statement. For example:
Simba Code:
// Bad
var
Logs: Integer;
Ores: Integer;
Fish: Integer;
function WalkToBank(i: Integer; j: Integer; l: string; k: string): Boolean;
// Good
var
Logs, Ores, Fish: Integer;
function WalkToBank(i, j: Integer; l, s: String): Boolean;
- Boolean variable names must be descriptive enough so that their meanings of True and False values will be clear.
Simba Code:
// Bad
var
b: Boolean;
// Good
var
DoesBank: Boolean;
- When you declare a variable, they are put on the next line after the var statement, and are indented. Example:
Simba Code:
// Bad
var Logs: Integer;
// Good
var
Logs: Integer;
- Try to declare variables locally as much as possible to avoid confusion within the script.
- The use of white space is highly suggested. It makes your code look neater, it's more readable, and in general I find it to be a good habit. Also, the readers of your script will appreciate it. If you don't know what I mean, don't worry, I'll be pointing out the use of white space as the tutorial goes on.
There, you should now have a good knowledge of Simba standards, and have no excuses for unreadable code.
Scripting Tips/Hints
In this section of the tutorial, you will learn independent ways of answering your scripting questions, so you don't have to post on the forums. You will also learn how to utilize Simba so that you can script faster and more efficient.
Codehints/Simba Library
- In addition to the functions list/library search to the left of your Simba window, we also have codehints and a list of every programming component built into Simba.
- When you open Simba, click the mouse on a blank line and hit Ctrl + Space. A list of EVERY available function, constant, variable, type, etc. will pop up. These are all the programming components you have at your disposal.
- You'll probably notice that the list is extremely long, and it would take forever to scroll through, examining each part. So, as you start typing something, the list will get smaller and only show the functions/procedures that begin with what you typed. Try it yourself.
- Another thing you may be unsure of is just what a function's or procedure's parameter's are. There is also a built in feature for this. Click on any function in the function's list to the left. At the bottom of the Simba window, you should see the function name with all it's parameters.
You've probably noticed this already, but if you type out the function once you hit the opening bracket, a small window should come up, showing the parameters.
Simba and SRL Documentation
- The Simba Documentation is useful for everything Simba related. You don't know exactly what a built-in function does? No problem, just head over to the Simba Documentation and navigate through the menus to where you want to be.
- The SRL Documentation is exactly the same as the Simba documentation, except for SRL, obviously. A lot of functions include examples and explanations, so if you want to know how something works, check out the SRL Documentation.
Hotkeys
- Hotkeys are very simple to understand. They are just keyboard shortcuts that allow you to do certain things in Simba. Here is a list of the most useful hotkeys.
- Run -> F9
- Stop -> F2
- Add Tab -> Ctrl + T
- Save -> Ctrl + S
- Library -> Ctrl + Space
- Undo -> Ctrl + Z
- Redo -> Ctrl + Y
- That is just a list of the most useful hotkeys. To find out what other hotkeys Simba has, just look through the different pull-down menus. By pull-down menus I mean:
The "Tab" Button
- As you continue scripting, the tab button will become your best friend. It allows you to move multiple lines of code incredibly fast. You can move 100s of lines forward or backwards as many lines as you wish.
- Nothing feels worse than when you need to move 300 lines of code ahead 2 spaces and you hit the space bar twice at every line. Say I want to move this code ahead two spaces to squire proper standards:
Simba Code:
procedure HelloWorld;
begin
WriteLn('Hello world!');
Wait(500);
WriteLn('How is the world doing today?');
Wait(500);
end;
I would highlight the code in between the begin..end nest and hit Tab. My code now looks like this:
Simba Code:
procedure HelloWorld;
begin
WriteLn('Hello world!');
Wait(500);
WriteLn('How is the world doing today?');
Wait(500);
end;
- See? Doesn't that look much better? Now, Tab moves the code ahead two spaces, but what if you want to move your code back two spaces? Well, this can be achieved by highlighting the code you want to move, and hitting Shift + Tab. Try it yourself.
Just use these simple tips and you'll learn more, faster. Again, only post on the forums as a last resort. You learn much more if you look for things yourself! For a little more in-depth tutorial on scripting shortcuts see ->
Not-so-well known SCAR shortcuts (yes, it's for SCAR, so not everything will work in Simba).
Programming Statements
There are many many programming statements out there. In this section of the tutorial, I will teach you the most important ones. With these statements, you'll be able to make almost any kind of script.
If..Then..Else Statements
- If..Then..Else statements (if statements for short) are what make scripts, scripts. They can perform checks to make sure the script is doing what it's suppose to do, and if it's on the wrong course, do something else to correct the course. Here is a small breakdown of the statement:
Simba Code:
// Notice the () around Condition, you should always use brackets in if statements for readability
if (Condition) then // Condition can be any variable check, i.e. boolean, integer, string, extended
begin // Notice the 'begin' after the 'if..then'; this is ALWAYS needed if you are going to perform more than 1 action
Action1;
Action2;
end else // 'end' ends Action1/Action2; 'else' means it will do Action3/Action4 IF the Condition is not true
begin
Action3;
Action4;
end;
if (Condition) then
Action1 // Notice there is no ';' and no 'begin'; neither is needed if you are performing ONLY 1 action after an if statement. If you put a ';' it will result in an "Identifier expected" error
else // Notice that there's no 'end', that's because there's no 'begin' we have to end
Action2;
- Now that is a pretty simple example, but you should understand how to write an if statement. Here is a little more complicated example that actually does something:
Simba Code:
program IfThenExample;
procedure RandomFunction;
var
i: Integer;
begin
if (Random(10) < 5) then // Random(10) will generate a random number between 0-9
WriteLn('Less than 5!') // Remember, no semicolon and no begin..end!
else
WriteLn('Greater than or equal to 5!');
i := Random(1000); // See how I assinged i to a random integer between 0 and 999
if ((i < 100) or (i > 500)) then // Will execute if either statement is true
begin
WriteLn('Small or large!'); // See how there's begin..end nests when there's more than one action?
WriteLn('Which is it?');
end else
begin
WriteLn('Somewhere in the middle!');
WriteLn('But where...?');
end;
end;
begin
ClearDebug;
RandomFunction;
end.
- I know that looks like a lot, but examine it line by line. If some part of that is confusing, just look back over that section of the tutorial, or break down the script into sections. If you successfully wrote this script, when you press run, your debug box should read something like:
Progress Report:
Greater than or equal to 5!
Somewhere in the middle!
But where...?
Successfully executed.
- There, it's not so hard, is it? Try playing around with the variables to get a visual of what exactly if statements do. You now fully understand what an if statement is and how to use them!
Cases
- Cases are used for a more efficient way of writing long and confusing code. Here is a simple breakdown of a case:
Simba Code:
// Notice the layout I have for a case; this ensures readability and organization
case Condition of // Like if statements, Condition can be any variable
Option1:
begin // Notice the begin..end nest for more than 1 action
Action1;
Action2;
end;
Option2:
Action3; // Notice a begin..end nest is not needed because it is only one action
else
Action4; // If there is not an option, it will perform Action4
end;
// Notice the white space (remember from earlier?) between the options
Shouldn't be too difficult to understand.
- Here is an example of the long and confusing code I was talking about. Be sure to not skip over this little bit as there is something new in the script.
Simba Code:
// Notice the white spaces I use inbetween statements
procedure WhichSport(Sport: string); // Notice the parameter I added so I can call different "Sports" later on
begin
if Lowercase(Sport) = 'hockey' then
WriteLn('The sport is ' + Sport);
if Lowercase(Sport) = 'soccer' then
WriteLn('The sport is ' + Sport);
if Lowercase(Sport) = 'basketball' then
WriteLn('The sport is ' + Sport);
if Lowercase(Sport) = 'baseball' then
WriteLn('The sport is ' + Sport);
if Lowercase(Sport) = 'rugby' then
WriteLn('The sport is ' + Sport);
if Lowercase(Sport) = 'football' then
WriteLn('The sport is ' + Sport);
end;
begin
WhichSport('Hockey'); //Notice how I called the procedure with the parameter I made; it can be whichever sport you want
end.
- You are probably wondering what "Lowercase" is. Well...
Originally Posted by
SCAR Manual
function Lowercase(s: string): string;
Returns the specified string in lowercase.
This means that if you set the Sport parameter as 'hOcKeY', it will still recognize it as 'hockey'. This is handy to use in parts of your script that other people will fill out, such as DeclarePlayers(more on that later), because no matter how they write it, the script will still run as it should.
- Now, the above script is not very pretty is it? It's also very difficult to read. So, we use a case, which would make the procedure look like this:
Simba Code:
program CaseExample;
// Again, notice the white spaces
procedure WhichSport(Sport: String);
begin
case Lowercase(Sport) of
'hockey':
WriteLn('HOCKEY!');
'soccer':
WriteLn('SOCCER!');
'basketball':
WriteLn('BASKETBALL!');
'baseball':
WriteLn('BASEBALL');
'rugby':
WriteLn('RUGBY!');
'football':
WriteLn('FOOTBALL!');
else
WriteLn('Sport is not in the selection!');
end;
end;
begin
ClearDebug;
WhichSport('HoCkEy'); // Notice how I spelled "hockey" with capital letters, it is still recognized as "hockey"
end.
- Using a case not only makes your code look better, but it shortens it up quite a bit. I suggest playing with the variable Sport, so you get a better understanding of cases. Now, if you successfully made that script, when you hit run, the debug box should read:
Progress Report:
Successfully compiled (4 ms)
HOCKEY!
Successfully executed.
- Congratulations! You now know how to use a case to make your code shorter, more efficient, and and look better!
Loops
- Using loops effectively can make or break a script, whether it is for RuneScape or any other program. I'm going to be teaching you three different kind of programming loops:
- Repeat..Until
- While..Do
- For..To..Do
It shouldn't be too hard to guess what each loop does, just by their name, but if you still have no idea, don't worry... just read on.
- Repeat..Until
- Repeat..Until loops are the easiest loop to understand and use. They will be used many times throughout your scripts. What it does is pretty straight forward - it repeats an action until it is told to stop. Simple as that. Here is a simple breakdown of the repeat..until loop:
Simba Code:
repeat // The 'repeat' acts like a 'begin', so 'begin' isn't necessary here
Action1; // You can have as many actions here as you wish
Action2;
until(Condition(s));
// The 'until' acts like an 'end', 'end' isn't necessary
// You can have more than one Condition; each condition is usually separated by 'and'/'or'
- Here is a nice, simple example that clearly shows what a repeat..until loop is all about:
Simba Code:
program RepeatUntilExample;
// Can you spot when the loop will stop?
procedure RepeatExample;
var
numberOfWaits: Integer;
begin // Although 'repeat' acts like a 'begin', 'begin' is still needed here to signal the start of the procedure
repeat
Wait(500);
Inc(numberOfWaits); // The Inc() command simply increases the var numberOfWaits by 1
WriteLn('We have waited ' + IntToStr(numberOfWaits) + ' times');
until(numberOfWaits = 5);
end;
begin
ClearDebug;
RepeatExample;
end.
- Pretty simple, no? The more you script, the more uses you will find for these loops, and the better you will get with them. If you successfully made the above script, your debug box should look something like this:
Progress Report:
We have waited 1 times.
We have waited 2 times.
We have waited 3 times.
We have waited 4 times.
We have waited 5 times.
Successfully executed
- Congratulations, you have learned what repeat..until loop is, and how to use it! An example of the usage of this loop is when opening a bank. You can repeatedly try to open the bank until your character has logged out, or it has tried more than 10 times.
- While..Do
- While..Do loops act almost exactly the same as repeat..until loops, only they are set up differently. The difference is that repeat..until loops will execute the command at least once, no matter what, whereas a while..do loop may not execute the command at all. To be honest, it doesn't really matter which one you use. There are certain situations where it would be better to use one or the other as you'll discover the more you script. Here is a simple breakdown of the loop:
Simba Code:
while Opposite(Condition) do // For a while..do loop, you have to set the Condition to the OPPOSITE of what you want
begin // Again, notice the begin/end for more than one action
Action1;
Action2;
end;
while Opposite(Condition) do
Action1; // Again, since it's only one Action, no begin..end nest is needed
- Here is an easy example, that should clearly show you how to use a while..do loop.
Simba Code:
program WhileDoExample;
procedure WhileDoExample;
var
count: Integer;
begin
while (Count <> 5) do // See how the condition is the opposite of what you want? You want the script to end when Count = 5, so while Count doesn't equal 5, do this (<> means "doesn't equal")
begin
Inc(Count);
Wait(500);
WriteLn('The count is ' + IntToStr(Count) + '.');
end;
end;
begin
ClearDebug;
WhileDoExample;
end.
- In my opinion, a while..do loop is slightly more advanced than a repeat..until loop, simply because it is a little shorter, and requires some thinking to come up with the opposite condition. If you wrote the above example properly, when you press run, your debug box should look like this:
Progress Report:
Successfully compiled (48 ms)
The count is 1.
The count is 2.
The count is 3.
The count is 4.
The count is 5.
Successfully executed
- Well there you go, you now know how to effectively use a while..do loop. A while..do loop is most commonly used in scripts that require some waiting while the character is doing something such as chopping down a tree or fishing.
- For..To..Do
- For..To..Do loops are the most complicated of the three loops, and can be used in the simplest functions, as well as the most advanced functions. Here is a simple breakdown of the loop:
Simba Code:
for (var Assignment/Start Integer) to (Finish Integer) do // For..To..Do loops increase the variable integer by one each time through the loop
begin
Action1;
Action2;
end;
for (var Assignment/Start Integer) to (Finish Integer) do
Action1;
- Confused? If so, examining the following example should clear things up for you.
Simba Code:
program ForToDoExample;
procedure ForToDoExample;
var
i: Integer;
begin
for i := 0 to 5 do // Notice the assignment mentioned earlier? The assignment is the ":="
begin
Wait(500);
WriteLn('The variable i = ' + IntToStr(i));
end;
end;
begin
ClearDebug;
ForToDoExample;
end.
- The same type of procedure can be written using both repeat..until and while..do loops. However, for..to..do loops are much more advanced and makes for a faster script. If you managed to understand for..to..do loops, you are well on your way to becoming an awesome scripter. Successfully writing the above script results in the debug box looking like this:
Progress Report:
The variable i = 0
The variable i = 1
The variable i = 2
The variable i = 3
The variable i = 4
The variable i = 5
Successfully executed
- If you made it through that, well done! If not, re-read the parts you don't understand because there is no point in moving on to more advanced material if you don't understand the basics. Remember to take things slowly and not to get frustrated!
- Internal Commands
Originally Posted by
Nava2
It is important to remember, that with ALL LOOPS, they will continue till they are done if they are not told to stop. That is why they are called Loops, they repeat.
- Thanks Nava for that awesome little explanation. Now, there will be times that a condition is met or not met and you want the loop to break, continue, or exit, hence the three internal loop commands:
- The Break; command is probably the command you will be using most as when it is called, it "breaks" out of the loop and continues with the rest of the procedure or function.
- Continue; is a useful command when used properly. When called, it stops the loop where it is and continues from the beginning of the loop. It's important to remember that is doesn't start the loop over, it continues. Say you wanted to repeat a loop 10 times. If on the fifth cycle through you called Continue, it wouldn't start back at one, it would start at 6. Understand?
- Exit; is most commonly used in loops, but can be used otherwise. When called, Exit exits out of the loop and the procedure/function, and continues along with the script. It is used a lot for failsafes (more on that later). Say you have a function that's suppose to find an item in the inventory. But if the inventory isn't open, it won't work. Therefore you can call Exit; if the inventory isn't open so it won't try to find the item when it already knows it wont.
- These commands are especially useful because they prevent the cause of what we call infinite (endless) loops. Nothing looks more like autoing then when your character is standing in the same place repeating the same thing over and over again, accomplishing nothing. Here is an example of an infinite loop:
Simba Code:
program InfiniteLoops;
(**
* Notice that it will never stop printing "Waiting..." to the debug box every
* second because i is never reset, it is ALWAYS equal to 5. This is an example
* of what NOT to do :p
*)
procedure InfiniteLoopExample;
var
i: Integer;
begin
i := 5;
while (i = 5) do // while i equals 5
begin
WriteLn('Waiting...');
Wait(1000);
end;
end;
begin
ClearDebug;
InfiniteLoopExample;
end.
You'll notice that "Waiting..." will repeatedly print to the debug box until you manually execute the script. Do you know what an endless loop does? Thought so, it's pretty straight forward.
- Here's an example that uses each type of loop and each type of internal command.
Simba Code:
program InternalCommandsExample;
function RepeatUntil: Boolean;
var
count: Integer;
begin
repeat
if (Random(100) > 75) then
begin
WriteLn('Greater than 75!');
Exit; // See how it will exit if the random number is greater than 75?
end else
WriteLn('Less than or equil to 75!');
Inc(count);
until(count = 10); // If no number is greater than 75, it will repeat 10 times
end;
procedure ForToDo;
var
count: Integer;
begin
for count := 1 to 10 do
begin
if (count = 5) then
Continue; // You'll notice that when count equals 5, nothing gets written to the debug box
WriteLn('Count does not equal 5! Count = ' + IntToStr(count));
end;
end;
procedure WhileDo;
var
count: Integer;
begin
while (count < 100) do
begin
if (count >= 10) then
Break; // See how it will break out of the loop if the count is greater than or equal to 10?
WriteLn('Count is less than 10!'); // This will not be written if count is greater than or equal to 10 because we broke out of the loop
Inc(count); // Can't forget this, otherwise we'll have an infinite loop; take it out and run the script
end;
end;
begin
ClearDebug;
RepeatUntil;
ForToDo;
WhileDo;
end.
- Not too difficult I hope. Do you have better understanding of the internal commands? Good. You'll find that these are essential in making a well working script and when forgotten may mean the difference of a 5 minute runtime as opposed to 5 hours.
- When you run the above script, your debug will read something like this:
Progress Report:
Less than or equil to 75!
Greater than 75!
Count does not equal 5! Count = 1
Count does not equal 5! Count = 2
Count does not equal 5! Count = 3
Count does not equal 5! Count = 4 // Notice here how there's no 5 written?
Count does not equal 5! Count = 6 // This is because we told the loop to continue when the count was 5
Count does not equal 5! Count = 7
Count does not equal 5! Count = 8
Count does not equal 5! Count = 9
Count does not equal 5! Count = 10
Count is less than 10!
Count is less than 10!
Count is less than 10!
Count is less than 10!
Count is less than 10!
Count is less than 10!
Count is less than 10!
Count is less than 10!
Count is less than 10!
Count is less than 10!
Successfully executed.
- Well there you go, all the information you need to know about the three loops! If you understood everything I just showed you, I shouldn't see any infinite loops in any scripts!
Try..Except..Finally Statements
- These statements are probably the most difficult to understand. Like the rest, there is a time and place to use them. You'll find that there aren't many situations where they can be used, but they are extremely useful when you do.
- Try..Except statements are used so that if your script were to encounter a runtime error (an error that happens while the script is running), it wouldn't stop, but continue on. The best example of this would be when reading a file. If you told Simba to read from a file that doesn't exist, you would get a runtime error and the script would stop. However, if you used a try..except..finally statement, the script wouldn't stop, it would continue on, but without the information that was supposed to be obtained from the file.
- I hope that wasn't too confusing for you. There are three different ways you can write try statements. Here's a breakdown of each:
Simba Code:
// 1.
try // Like a repeat loop, 'try' acts as a 'begin'
Action1;
Action2; // Again, there can be as many actions as you wish
except // Short for 'exception'
Action3;
Action4; // If the script encounters an error in Action1/2, it will run Action3/4
end; // This is required no matter which way you write the statement
// 2.
try
Action1;
Action2;
finally // This will execute Action3/4 NO MATTER WHAT, even if Action1/2 was an Exit; command
Action3;
Action4;
end;
// 3.
try // What to attempt to do
Action1;
Action2;
except // What to do when it encounters an error
Action3;
Action4;
finally // What to do no matter what
Action5;
Action6;
end;
- I'm sure you get the idea, but here's a short example that uses the third way of writing it. Read this one carefully because it teaches you how to write from a text file.
Simba Code:
program TryExceptFinallyExample;
(**
* Will write the string 'Text' to the file 'FileName'
* There are several procedures/functions I use in this example that you've
* never seen before. Don't panic! Click on the triangle beside 'Files' in the
* functions list and you'll see them all
*)
function WriteToFile(Text, FileName: string): Boolean;
var
thePath: string;
theFile: Integer; // When working with files, they are always of the Integer type
begin
// When setting the path, be sure you always end with a '\', otherwise you will get errors
thePath := AppPath + 'Scripts\'; // This will save the file in Simba/Scripts (AppPath = Application Path)
try
theFile := RewriteFile(thePath + FileName, False); // Saves the file to thePath and names it 'FileName'
except // An exception would be thrown most likely if there was an invalid file name
WriteLn('Error opening file!');
finally
WriteLn('Done trying to open file');
end;
// Notice how I assigned the opened or created file to 'theFile', this is so we can use it later in the procedure
if (WriteFileString(theFile, Text)) then
Result := True;
CloseFile(theFile); // Remember to ALWAYS close the file when you're finished! If you don't it can cause memory leaks and your script will run very slowly
end;
begin
ClearDebug;
if (WriteToFile('Test!', 'TestFile.txt')) then
WriteLn('Successfully wrote to file!')
else
WriteLn('Error writing to file');
end.
- Now that is a lot to take in, but I know you can handle it! Take a look at all the different Simba file handling functions and procedures in the functions list. As you can see there are a lot of different things you can do. Writing to a file can be useful if you want to save progress reports. Maybe your computer crashes or some updates automatically restart the computer while your script is running. Either way, you have your report nicely saved on your computer.
- If you successfully wrote that script, you debug should look like:
Progress Report:
Done trying to open file
Successfully wrote to file!
Successfully executed.
Also, navigate to the folder you saved the file to (Simba/Scripts). There should be a nice text file that has "Test!" written in it.
- If you don't fully understand these statements, don't worry, they're not used often and you can certainly write an awesome Runescape script without them.
Putting it all Together
- In this section of the tutorial, you will learn how to make a script using all the different programming statements I've taught you, including having some statements inside other statements (nesting). Exciting, no? In this example, I have combined all the different types of statements. Be sure to examine it carefully and make sure you understand everything you are reading. Look back in the tutorial if you need to.
Simba Code:
program PuttingItAllTogether;
// To be set by the user of the script
const
TREE_TYPE = 'Willow';
LOGS_TO_CUT = 100;
// Global vars can be 'reset' at any time during your script
var
TotalLogs: Integer;
TreeName: string;
TreeExp, TotalExp: Extended;
// Checks to see if the constants were set properly
function CheckSetup: Boolean;
var
s: string;
logs: Integer;
begin
if (TREE_TYPE = '') then // If the tree type wasn't filled out
begin
WriteLn('Please enter a tree type at the top of the script');
Exit;
end;
s := Lowercase(TREE_TYPE);
if ((s <> 'normal') and (s <> 'oak') and (s <> 'willow')) then // if tree type isn't a valid tree
begin
WriteLn('Please enter a valid tree type at the top of the script');
Exit;
end;
if (LOGS_TO_CUT <= 0) then
begin
WriteLn('Please enter a number of logs to cut at the top of the script');
Exit;
end;
Result := True; // Set to true at the end because if there was an error, it exits and therefore the result is set to false
end;
// Notice the general layout of this function ;)
procedure SetTreeProperties(Tree: string);
begin
case Lowercase(Tree) of
'normal':
begin
TreeName := 'Tree';
TreeExp := 25;
end;
'oak':
begin
TreeName := 'Oak tree';
TreeExp := 37.5;
end;
'willow':
begin
TreeName := 'Willow tree';
TreeExp := 67.5;
end;
else
WriteLn('Invalid tree type in "GetTreeType"');
end;
end;
procedure IncTotalLogs(HowMuch: Integer); // Inc = Increment
begin
IncEx(TotalLogs, HowMuch); // This will increment TotalLogs by HowMuch; if HowMuch = 10, TotalLogs would increase by 10
WriteLn('Increased total logs by -> ' + IntToStr(HowMuch));
WriteLn('Total logs chopped -> ' + IntToStr(TotalLogs));
end;
procedure SetTotalExp;
begin
TotalExp := (TotalLogs * TreeExp); // Multiply the total logs by the tree's exp
WriteLn('Total experience gained -> ' + FloatToStr(TotalExp));
end;
function WriteReportToFile: Boolean;
var
theFile: Integer;
thePath: string;
begin
thePath := AppPath + 'Scripts\Progress.txt';
try
theFile := RewriteFile(thePath, False);
except
WriteLn('Error opening file!');
end;
WriteFileString(theFile, 'Tree: ' + TreeName + #13 + #10); // The '#13 + #10' will skip to the next line in the file, so Exp: won't be written on the same line
WriteFileString(theFile, 'Exp: ' + FloatToStr(TreeExp) + #13 + #10);
WriteFileString(theFile, 'Total Logs: ' + IntToStr(TotalLogs) + #13 + #10);
WriteFileString(theFile, 'Total Exp: ' + FloatToStr(TotalExp) + #13 + #10);
CloseFile(theFile); // Again, don't forget this!
end;
begin
ClearDebug;
if (CheckSetup) then
WriteLn('Script has been setup properly')
else
TerminateScript; // Simply terminates the script when called
SetTreeProperties(TREE_TYPE); // Be sure to call this, otherwise the global vars aren't set
repeat
IncTotalLogs(Random(28)); // Will increase the TotalLogs by a random number from 0-28
SetTotalExp;
until(TotalLogs >= LOGS_TO_CUT); // StrToInt() avoids a type mismatch error
WriteReportToFile;
WriteLn('Finished!');
end.
- I know that looks like a lot, and most likely it will be confusing to you, but don't give up. Remember that you have to be patient when learning how to script, you aren't going to understand everything the first time.
- If you understand the above script, and managed to experiment successfully, when you hit run, the debug box should get spammed by a bunch of words. When finished, it should look like this:
Progress Report:
Finished checking the user's setup
Script has been setup properly
Increased total logs by -> 2
Total logs chopped -> 2
Total experience gained -> 135
Increased total logs by -> 18
Total logs chopped -> 20
Total experience gained -> 1350
Increased total logs by -> 27
Total logs chopped -> 47
Total experience gained -> 3172.5
Increased total logs by -> 5
Total logs chopped -> 52
Total experience gained -> 3510
Increased total logs by -> 23
Total logs chopped -> 75
Total experience gained -> 5062.5
Increased total logs by -> 17
Total logs chopped -> 92
Total experience gained -> 6210
Increased total logs by -> 1
Total logs chopped -> 93
Total experience gained -> 6277.5
Increased total logs by -> 6
Total logs chopped -> 99
Total experience gained -> 6682.5
Increased total logs by -> 13
Total logs chopped -> 112
Total experience gained -> 7560
Finished!
Successfully executed.
- Also, you need to check the file that was created from that script. Open Simba/Scripts/Progress.txt and a notepad file should open that looks something like this:
Congratulations! You now know the basics of programming in Simba. You now have enough knowledge for me to introduce you to what it takes to make a working RuneScape script.
The SRL Include
Remember at the start of the guide when I said you needed to download SRL properly? Well here is why... SRL is comprised of all sorts of functions/procedures available for you to use. Each of them make you scripting life easier. In order to use these handy functions, you have to
include and setup SRL in your script. You can do so by setting up you script like this:
Simba Code:
program New;
{$i SRL\SRL.simba} // Be sure to add this to ALL your scripts!
begin
SetupSRL; // You also have to call this in your mainloop, otherwise the mouse will move about 1 pixel every 10 seconds :p
end.
At this point you should set that script as your
default script. Meaning that every time you open Simba or open a new tab, you will be greeted with a script that already has SRL setup for you.
Simply to to
File > Save as Default.
Now, if you navigate to
Simba/Includes/SRL/SRL/, you should see three folders:
skill,
misc and
core. When you include SRL (srl.simba), you are only including the core folder. Any other files you wish you include have to be done separately.
For example, if I was making a script where I needed to cast some spells, I would include the Magic.simba file found in the skills folder because it has many different functions and procedures to help me script for magic. To include that file I'd simply add this at the top of my script:
Simba Code:
{$i srl/srl/skill/magic.simba}
The same would be done for any skill file or any file in the misc folder. Don't be afraid to take a look through them, I'm sure you'll find some very handy functions laying around.
Remember the functions list? Well, you'll notice that there is now a little triangle beside the word
Includes. Click it, it will show the list of all the functions you have included in your script.
Well there you go, you now know how to use any file in the SRL include.
DeclarePlayers & S.M.A.R.T.
The first thing you should know about making script run for RuneScape is about the DeclarePlayers. DeclarePlayers is a procedure that allows you to setup your RuneScape account(s). For example, the username, password, how many logs to cut, how many loads to bank. Obviously those are just a few examples, but the possibilities are endless.
If you've used any scripts at SRL, then you've probably used
S.M.A.R.T. (
Simba
Minimizing
Autoing
Resource
Thing) created by Benland100. This tool allows you to run a script in Simba, and still do whatever you want on your computer. You still can, of course, use a standard internet browser if you wish.
Every DeclarePlayers procedure has to be setup like this, otherwise your script won't work properly. You can, of course add attributes to allow the user to customize each player, but these are the minimum requirements. I also show you how to use S.M.A.R.T., so pay attention!
Simba Code:
program DeclarePlayers;
{$DEFINE SMART} // This is how we include SMART; it HAS to be called BEFORE SRL!
{$i srl/srl.simba}
procedure DeclarePlayers;
begin
HowManyPlayers := 1; // This is set to the total amount of players (more on multiplayer later ;)), for now, just keep it set as 1
NumberOfPlayers(HowManyPlayers); // This is a procedure in SRL which sets up player arrays (also, more on that later), this will always be the same
CurrentPlayer := 0; // This is the player to start with; the first player will always be 0 (you'll find out when you learn all about arrays)
Players[0].Name := ''; // Username
Players[0].Pass := ''; // Password
Players[0].Nick := ''; // 3-4 lowercase letters from username; used for random event detection
Players[0].Active := True; // Set to true if you want to use Player 0
Players[0].Pin := ''; // Leave blank if the player doesn't have a bank pin
end;
begin
ClearDebug;
SetupSRL;
DeclarePlayers; // Calls the procedure, you can't forget this!
LoginPlayer; // You want your player to login, right?
end.
I don't expect you to understand everything (like the
"Players[0]."), but you should know how to add SMART to your script and how to login your player. You will learn all about Players if you decide to move on to my intermediate and advanced tutorials (just a little glimpse - Players is an array custom type which store all the different player's information. Confused?
).
Since you now have a DeclarePlayers procedure, lets make our player log in, shall we? Fill out the DeclarePlayers accordingly (with your username/password/nickname), and hit run. Wait a few seconds and you should see the SMART window pop up and the script should execute after you player has been logged in. Your debug box should look something like:
Progress Report:
SRL Compiled in 16 msec
SMART Initialized.
Loaded: Server 152, Members: False, Signed: True, Super Detail: False.
Welcome to Runescape.
Username Here
Successfully executed.
Congratulations! You now know all about DeclarePlayers and how to login a player. I bet it wasn't as hard as you thought.
Failsafes
Failsafes are essential in ALL scripts made for RuneScape. Failsafes are what make the script last for hours without error. They can be made using all the programming statements, but are most commonly conveyed using
if statements. Here's a general layout.
Simba Code:
if (Condition1) then
Action1 // Recall that there's no semicolon here
else
if (Condition2) then
Action2
else
if (Condition3) then
Action3
else
if (Condition4) then
Action4; // Semicolon because it's the last statement
See how there is always another procedure or "failsafe" to run if the one before it fails? The chances of all four procedures failing isn't very high, hence why some scripts can run for hours - they have awesome failsafes!
Now, before you rush ahead and read the next example, there are a few things I need to explain so you aren't confused. If you looked at it already, you probably asked yourself "MSX1? What's that?". Those are constants in the SRL include that define coordinates on the RuneScape screen. You'll find them to be very helpful while scripting:
- MS - Main Screen - The main RuneScape playing screen.
- MM - MiniMap - The RuneScape minimap in the top right corner of the RS screen.
- MI - Main Inventory - You inventory box on the right of the RS window, below the minimap.
- MC - Main Chat - The RS Chat box at the bottom on the RS window.
- MB - Main Bank - The RS bank.
- DB - Deposit Box - The RS deposit box.
Now, to search in one of these boxes, all you have to do is write the two letters, followed by
X1,
Y1,
X2,
Y2. There are also center points for each of these boxes, which would have the two letters followed but one of
CX or
CY. These constants can be found in
Simba/Includes/SRL/SRL/core/Globals.simba. If you don't understand, you will after you read this example (keep in mind I don't use every type of box):
Simba Code:
program FailsafesExample;
{.include SRL/SRL.simba}
procedure FailsafeExample;
var
x, y : Integer;
begin
if FindColor(x, y, 2167538, MSX1, MSY1, MSX2, MSY2) then // If the color (2167538) is found, the coordinates of where it was found is stored in the variables (x, y).
MMouse(x, y, 4, 4) // Moves the mouse to x, y; 4, 4 is the randomness on x, y
else
begin
Wait(1000); // Remember 1000ms = 1s
WriteLn('First FindColor failed, trying second...');
if FindColor(x, y, 3652378, MMX1, MMY1, MMX2, MMY2) then
Mouse(x, y, 4, 4, True) // This moves AND left clicks the mouse with randomness 4, 4; 'True' = Left click; 'False' = Right click
else
begin
Wait(1000);
WriteLn('Second FindColor failed, trying third...');
if FindColor(x, y, 4981245, MIX1, MIY1, MIX2, MIY2) then
MMouse(x, y, 4, 4)
else
begin
Wait(1000);
WriteLn('Third FindColor failed, trying forth...');
if FindColor(x, y, 6478356, MCX1, MCY1, MCX2, MCY2) then
Mouse(x, y, 4, 4, True)
else
begin
Wait(1000);
WriteLn('Forth FindColors failed, logging out');
Logout; // This is pretty straight forward, it logs your player out
end;
end;
end;
end;
end; // There are so many 'end's because each begin has to have an end, otherwise you will get an "Identifier expected..." error
begin
ClearDebug;
FailsafeExample;
end.
I made that example to purposely fail, so you would get the idea of how a failsafe works. Do you understand what they do? Do you understand how to move the mouse, how to click the mouse? Do you understand how to specify which box you want to look in? Keep in mind that the box can be any integer values you wish. These constants are just there for your convenience.
If you successfully wrote the above script, when you hit play, the debug box should read:
Progress Report:
First FindColor failed, trying second...
Second FindColor failed, trying third...
Third FindColor failed, trying forth...
Forth FindColors failed, logging out
Successfully executed.
That is just one example of a failsafe. There are literally 1000s of possibilities, some of which I hope to show you in the more advanced tutorials. You are now finished learning all about failsafes. Now, on to the last part of the tutorial.
Antiban and AntiRandoms
Antiban and AntiRandoms are also an essential to ALL RuneScape scripts. The definitions should be pretty straight forward, but I'll explain them anyhow.
- Antiban - Procedures/functions that prevent your character from getting banned. Antiban makes your character look more "human-like". Movements like random camera angle motions, random examination of objects/items or random game tab (inventory, quest, music, etc) clicking, etc. Again, there are 100s of possibilites.
- AntiRandoms - Procedures/Functions that solve the many RuneScape random events. Don't panic! All the solvable random events are already implimented into SRL. The only thing you have to do is add one line of code.
Antiban
- Almost all Antiban procedures are made using a case statement. There are also several antiban procedures already in SRL. All we have to do is put a few of them together, and away we are.
- First, I want you to go to your SRL folder and open Antiban.simba (Includes/SRL/SRL/core/Antiban.simba). See how there are several antiban procedures? If you want to know what they do, click the one you want on the functions list, scroll up a bit, and you will see a description of the procedure, and how to use it. Here is an example of a typical antiban procedure (usually common in every script, no matter the author):
Simba Code:
(**
* The reason I used Random(60), even though there are only 6 antiban
* procedures is because if you antiban too much, you will look like a bot.
* You want to antiban approx. once every ten times the procedure is called
*)
procedure Antiban;
begin
case Random(60) of // Random(60) generates a random integer from 0 to 59
10: RandomRClick;
20: HoverSkill('Mining', False);
30: PickUpMouse;
40: RandomMovement;
50: BoredHuman;
59: ExamineInv;
end;
end;
- Antiban procedures can be as basic or as advanced as you want them. The more advanced, the better, obviously. Everytime the above procedure is called in your script, if the result from Random(60) equals 10, 20, 30, etc., then it will do the corresponding antiban procedure. Neat, huh?
AntiRandoms
- Knowing the definition, I'm sure you are thinking it's going to be extremely difficult to implement random event solving in your script. Well, you thought wrong. It is actually very, very simple. The first thing you should do is add this little piece of code to your DeclarePlayers procedure:
Simba Code:
Players[0].BoxRewards := ['Xp', 'mote', 'ostume', 'oins', 'aphire', 'ssence'];
Any other rewards can easily be added. This line will randomly choose one of the options when a reward box is opened. The 'Xp' option is the option to get a gene lamp.
- If you are wondering why there is '' around each option, it is because they are strings, and that's how strings are declared, remember? Also, a positive to having that in your DeclarePlayers procedure is that the user of the script can choose different rewards for different players.
- You should also know why there are [] around all the strings. This is because it's a TStringArray (you'll learn more on arrays in the more advanced tutorials).
- Now, on to what we need to write as a procedure. Here is an example of a common AntiRandoms procedure and when it may be called:
Simba Code:
procedure AntiRandoms;
begin
FindNormalRandoms; // Whenever this is called, the script will check to see if your character is in a random event
LampSkill := 'woodcutting'; // If you set the script to choose an experience lamp from a random event box, it will use the exp on the woddcutting skill
LevelUp; // This is an Antiban procedure, but I find it more useful when called here because AntiRandoms is usually called more often than Antiban
end;
procedure ChopTrees;
begin
// Chopping trees code here
while (IsChopping) do // IsChopping isn't an actual function, it is one I made up for this example, so don't go try using it in one of your scripts ;)
begin
Antiban; // This is an example of when you would call an antiban procedure
AntiRandoms; // Call AntiRandoms while your character is chopping down a tree
end;
end;
- See? I bet that's much easier than you expected. So basically, while your character is hacking away at a tree, the script will continually search for random events, so if you happen to end up in one, the script can solve it without problems. I highly recommend you put FindNormalRandoms in almost all of your procedures so that no matter where you get sucked into a random event, your script can still attempt to solve it.
Well, that's it for Antiban and AntiRandoms. Every script you write for RuneScape should include both of these. These significantly decrease your changes at a ban (not that the chances are very high to begin with). Also, don't be afraid to use your imagination and create your own Antiban procedures. Remember, not EVERYTHING is in SRL.
Conclusion
Well there you have it! My beginner's tutorial. To be quite honest, you probably won't be able to make a RuneScape script with what you've learned so far. But don't worry! You've learned what it takes to make a working script. You know the basics, and everything from here on in is just learning the different Simba commands and how to use them (with a few new programming concepts here and there).
Remember to always ask questions if you're unsure about something. I have no problem giving a more detailed explanation on something if you need it. Don't be afraid to post your questions and either I or someone else from the community will replay as soon as possible.
I would also like to encourage you to post any scripts you write that started with this tutorial. It's always nice to see how this has helped people. Also, if you just want me to take a look over your script and give you detailed feedback/suggestions, feel free to post it here.
In the meantime, see if you can tackle my Intermediate Tutorial (not actually finished yet) in the intermediate scripting tutorials section. Until that is finished, you can continue with the intermediate/advanced sections in my
AIO SCAR Scripting Tutorial. I hope this helped you learn the basics of programming.
Cheers,
Coh3n