The following are scripting rules designed for three purposes:
1) To improve the readability of your code.
2) To make your code easier to debug.
3) To minimise errors in your code.
Adhere to them, or Kaimetsu will punch you in the eye and never help you with your code.
DEFINITIONS
Conditional Statement
A piece of code that can be evaluated and declared either true or false. For example, 'playerrupees>20' is a conditional statement; it is true if the player has more than 20 rupees, and false otherwise. 'timeout' is also a conditional statement (along with all other events); it returns true if the flag is set and false if not.
Code Block
A code block is a section of code delimited by braces ('{' and '}'). They can be used to specify the behaviour of many structures, including if, while, for, function and with. Below are some examples.
NPC Code:
if(playerenters){
greetplayer();
}
function greetplayer(){
if(playerap>60){
message Hello! So good to see you!;
}
}
Event Block
An event block is a special type of code block. It specifies the behaviour of an if statement that responds to an event. For example, the blue text below is an event block:
NPC Code:
if(playertouchsme){
stealdonuts();
message Pardon me, sir, I seem to have accidentally jostled you;
}
Whereas this is not:
NPC Code:
if(this.donuts==30){
message I am in heaven! ^_^;
}
Flags such as playerenters, playerchats and timeout are events. 'this.donuts==30' is just a condition.
Nesting
Nesting is the act of placing code blocks within other code blocks. In the following example, the green text is nested inside the blue.
NPC Code:
if(playerchats){
if(strequals(#c,Where are my donuts?)){
message I have no idea;
}
}
The green text is part of the blue event block, but the blue event block is not part of the green text. Nesting is an integral part to all truly complicated scripts.
RULES
Rule One
Never include code that is not part of an event block. Think about when you want your code to execute, and place it in a corresponding event block.
Rule Two
Never nest event blocks within one another, or have a single event block depend on multiple events. It's not as bad to have a block react to one of multiple events (playerenters||timeout, for example), but it's still to be discouraged in most circumstances.
Rule Two A
Do not use multiple event blocks that respond to the same event. Check for an event once only.
Rule Three
Don't combine multiple commands on one line unless the relationship between them is clear and obvious. Each line should have only one purpose. The following example is fine.
NPC Code:
this.x=10; this.y=40;
This line of code simply sets a position - it's okay to put both commands on the same line because they both combine to achieve an obvious purpose. On the other hand...
NPC Code:
this.x=10; rupees=100;
This code is poor. There is no obvious link between setting an x coordinate and modifying a rupee count.
Be careful about what you consider obvious - as the programmer, you have an automatic insight into the code's purpose. Others will need to figure it out themselves.
Rule Four
Similarly to rule three, do not combine unrelated conditional statements. Instead of writing shambling messes like this:
NPC Code:
if(playerrupees>5&&this.monkey==84&&strequals(#g,C OOLGUYS)){
message WORD UP DAWG WOOT LOL;
}
Try to organise your statements by nesting them, like this:
NPC Code:
if(strequals(#g,COOLGUYS)){
if(playerrupees>5){
if(this.monkey==84){
message Yay, our script is now phat;
}
}
}
Here we have an issue of readability vs efficiency. Intuitively, it makes more sense to check the guild first (if they're not in the guild, we don't give a damn how many monkeys they have). However, the order of evaluation will not change the operation of the script and it's usually more efficient to check normal variables than strings. Try to strike a balance between the two factors, and remember to comment the code if necessary.
Rule Five
Use '==' when comparing two values for equality.
Use '=' when assigning a value to a variable.
Rule Six
Beware deprecated commands. These are old parts of the scripting engine that are no longer supported because they have been replaced. Although they may still work, it is very bad form to use them. Examples:
playersays()
showimg @@@ (using showimg to draw text)
setlevel
Rule Seven
Name your variables appropriately. Variables that are prefixed with 'this.' are usually only necessary if the variable's value has to stay unchanged between executions of the script. If you're just storing a temporary variable, don't add the prefix. As well as small efficiency improvements, this will make your script more readable - it allows people to deduce more about a variable from its name.
Rule Eight
If your script is checking multiple possibilities and they are mutually exclusive (ie, they can't both be true), use elseif instead of a string of ifs. It's more efficient (Graal doesn't always need to evaluate all the conditions), and it adds implicit meaning to your code.
(More rules will come if/when I think of them)