Exploring Verge³
by Overkill
Programming? Code? Huh?
Learn some basics about code. A big section, caked with horrible wordplay for titles. You don't have to read it all right away, but it's here for when you realize something you've done gives errors.
Ick. This tutorial is huge. I hope writing this is time well wasted.
- Syntax
- Brackets, Braces and Parentheses, oh my!
- Comments
- Variables (a *big* section).
- Operators, Math and Brackets.
- Next Time, You'll do it IF I say so or ELSE!
- WHILE You're at it...
- FOR Everything Else, There's Mastercard
- Let's SWITCH Things Up a Bit
- Functions
- Preprocess This!
- Naming and You
- Tabs, Spaces and New Lines are Your Best Friends.
- Read the Docs
- Don't Hesitate for Help!
Syntax
Syntax. What is it? "The rules governing the structure of a language", is one of the definitions made by the mischievious GoogleBot. Syntax is a stupid, fancy word to say what the compiler checks over. If you follow the syntax, it'll compile. If you don't it spews errors back, and you're in for a world of pain. This is why we follow the rules. All source code that follows syntax will have at least some similarities to another. Syntax is one of those things where "making a statement" by trying to do things different than others is a stupid, shameful idea (unlike the clothes you wear perhaps). Now that we know what it is, why don't we figure out how we keep the syntax?
Brackets, Braces and Parentheses, oh my!
There are three types of "brackets" in Verge³:
- Parentheses are (). These are called "brackets" by some.
- Brackets are []. These are called "square brackets" by some.
- Braces are {}. These are called "curly brackets" by some.
Note: This is just to give you a heads up that I prefer to use the proper "bracket terminology". Other than that, whatever.
Also, make it a good practice to close all brackets you open, and don't close more than you open. This will let you avoid a world of otherwise inevitable pain.
Comments
Comments are pieces of information ignored by the compiler. They let you document code, and also help you debug your code. It's recommended you use them even if you think you're "too cool" for them.
There are two types of comments:
- Single-line comments follow two slashes //, and make everything following them be ignored by the compiler.
int veryimportantnumber; // More important than life.
- Multi-line comments start with a slash, then asterisk /*, and end with an asterisk then slash */ everything in between these symbols be ignored by the compiler.
#include "topsecretcode.vc" /* sunday i wish i had money money means lots of fun i do have */ void AutoExec() { GoTopSecret(); // Sekret ^__^;; }
Variables
Variables. What are they? Well, look back to math class, where you have 5x = 2 and stuff. Your game will have billions of these things. Fun.
Variables have to declared using syntax. (Don't you love that word?)
In math class, you could have had something like this, minus the RPGish stuff in there:
Let the HP of the main dude hero be 4000.
In verge³, it's a tad different.
int hero[MAIN_DUDE].hp = 4000;
It's a bit confusing, but bear with me. I'll talk to you about the different types of variables, and when I do this, you should be able to figure out how to declare 'em.
Integers
In math, integers were any number, positive or negative. However, in verge³ it's any non-decimal, non-fractional number between 2,147,483,647 (231 - 1) and -2,147,483,648 ((-2)31). Why? Because most computers can only handle up to 32 bit numbers. A bit disappointing if you were looking forward to breaking the damage cap record, making one of those RPGs with insanely large damage amounts. But, we'll just say that you don't want to, for now. An integer is a number. You do lots of math with these. Integers are a type of variable in Verge³.
Example:
int a = 1; int b = 2; int c; c = a + b;
So... to make integer variables, type something like:
int myvariable = 405;
- int tells the compiler what type of variable we're declaring.
- myvariable tells the compiler what the name of the variable is, which you can name to your liking.
- The equality sign = tells the compiler you want to initialize the variable (ie. set it to something, in this case 405).
- The semi-colon ; tells the compiler that you're done and that it should move on to your next pieces of code. Don't forget these. If you forget this small thing it will be chaos when you have a large codebase.
- An Integer (int) lets you do math, and store various numbers. You'll find out just how useful these things are.
- Integers can only be assigned values in functions. They can be declared and initialized almost anywhere, though.
Strings
A string is a bunch of text and stuff. I guess they called them strings, because its a bunch of text stringed together...? -_-;;. You do lots with these. Strings are a type of variable in Verge³.
Example:
string a = "Hello";
string b = "world!";
string c;
c = a + " " + b;
Exit(c);
string dumb = I FAIL AT LIFE; // Don't repeat this mistake.
To make string variables, basically type something like:
string mystringvariable = "My name is Dennis.";
- string tells the compiler what type of variable we're declaring.
- mystringvariable tells the compiler what the name of the variable is, which you can name to your liking.
- The equality sign = tells the compiler you want to initialize the variable (ie. set it to something, in this case My name is Dennis.).
- The quotation marks "" tell the compiler you've got text. "In between" the quotes is your text. Note the type of quotation mark, only double-quotes will do. Also, don't forget these, it's a painful world searching for quotation marks in a huge megacode.
- Note that if you want a blank string, put nothing between the quotation marks ""
- The semi-colon ; tells the compiler that you're done and that it should move on to your next pieces of code. Don't forget these. If you forget this small thing it will be chaos when you have a large codebase.
- A String lets you store text. You'll find out just how useful these things are, but how disappointing strings sometimes are in Verge³. They use quotation marks!
- Strings can only be assigned values in functions. They can be declared and initialized almost anywhere, though.
Arrays
Arrays are a way of simplifying similar variables. Say, for instance you have thing1, thing2, thing3, thing4, and so on... to thing2000! Now, all two-thousand things are identical-looking on top of that. Would you rather have a seperate code for each thing which would take forever, or have an array of two-thousand things? Probably the latter if you're smart.
int thing[2000]; // Two-thousand things!
// What they do is beyond me, but now they do it easier!
thing[2000] = 30; // Thing number 2000 can't be set.
// Arrays start at 0 instead of 1, so an array of 2000 things
// goes from 0 up to the 1999th element. Hope that makes sense.
string name[7]; // The names of some people!
name[0] = "Jimmothy";
name[1] = "Timothy";
name[2] = "Rex";
name[3] = "Joe";
name[4] = "Bob";
name[5] = "Bill";
name[6] = "Shunny McShunShun";
Exit(name[6]); // Shunny McShunShun, being the outcast, gets singled out
// and we exit.
string tic_tac_toe_board[3][3]; // A 3x3 tic-tac-toe board. A two-dimensional array.
// The first dimension is the X of the tic-tac-toe grid.
// The second dimension is the Y of the tic-tac-toe grid.
tic_tac_toe_board[0][0] = "X";
tic_tac_toe_board[0][1] = "O";
tic_tac_toe_board[0][2] = "X";
tic_tac_toe_board[1][0] = "O";
tic_tac_toe_board[1][1] = "X";
tic_tac_toe_board[1][2] = "";
tic_tac_toe_board[1][0] = "O";
tic_tac_toe_board[1][1] = "";
tic_tac_toe_board[1][2] = "X";
// This could result in:
// 0 1 2
// 0 X O X
// 1 O X
// 2 O X
// ... X winning!
To make array variables, basically type something like:
int myarray[30]; string myotherarray[30]; int mytwodimensionalarray[30][30];
- int and string both tell the compiler what type of variable we're declaring.
- myarray and myotherarray and mytwodimensionalarray all tell the compiler what the name of the variable is, which you can name to your liking.
- The equality sign = can't be used to initialize the array when declaring it. You have to set each element in the array seperately. Sorry.
- The number between the between the brackets [30] tells the compiler that the variable is an array, and how many elements are in that array (Size).
- Every pair of brackets [] add another dimension to the array. When you use more than one dimension, think of the array as a grid, like in Battleship or something.
- The semi-colon ; tells the compiler that you're done and that it should move on to your next pieces of code. Don't forget these. If you forget this small thing it will be chaos when you have a large codebase.
- An Array lets you store more than one integer or string, for simplicity's sake.
- The lowest element you can get/set in an array is 0.
- The highest element you can get/set in an array is (array size - 1).
- Array variables can't be declared in functions.
- Arrays can only be assigned values to their individual parts. Variables can only be assigned values in functions.
Structures
Structures are a way of simplifying similar variables even more. They are one of the closest things to Object Oriented Programming in Verge³, if you know what that is. Structures make your game a lot simpler.
Perhaps you start off with something like this:
int player1_hp = 2000; int player1_atk = 50; int player1_def = 24; string player1_spellone = "Heal"; string player1_spelltwo = "Uber-omega-destroy-the-world-bomb"; int player2_hp = 5012; int player2_atk = 3004; int player2_def = 96; string player2_spellone = "Fire"; int player3_hp = 6460; int player3_atk = 3004; int player3_def = 96; string player3_spellone = "Ice Wall";
We could do the following:
int player_hp[3]; int player_atk[3]; int player_def[3]; string player_spell[3][2]; // A two-dimensional array, // where the first dimension is the player number, // the second dimension is the spell number. player_hp[0] = 2000; // Remember, arrays start at 0, not 1. player_atk[0] = 50; player_def[0] = 24; player_spell[0][0] = "Heal"; player_spell[0][1] = "Uber-omega-destroy-the-world-bomb"; player_hp[1] = 5012; player_atk[1] = 2000; player_def[1] = 2000; player_spell[1][0] = "Fire"; player_hp[2] = 6460; player_atk[2] = 2000; player_def[2] = 2000; player_spell[2][0] = "Ice Wall";
...which is better than the first method, but still not very efficient.
Then there's structures, which are probably the best way to do this crappy example:
struct player_type // Declare a new *type* of variable.
{
int hp, atk, def;
string spell[2];
};
player_type player[3]; // Declare an array of three player_types.
player[0].hp = 2000; // Remember, arrays start at 0, not 1, even in structs.
player[0].atk = 50;
player[0].def = 24;
player[0].spell[0] = "Heal";
player[0].spell[1] = "Uber-omega-destroy-the-world-bomb";
player[1].hp = 5012;
player[1].atk = 2000;
player[1].def = 2000;
player[1].spell[0] = "Fire";
player[2].hp = 6460;
player[2].atk = 2000;
player[2].def = 2000;
player[2].spell[0] = "Ice Wall";
Another Example:
struct person_type
{
string name;
int friends;
int coolness
};
person_type overkill;
person_type jimmybob6;
overkill.name = "Overkill";
overkill.coolness = 1337;
overkill.friends = 902650;
jimmybob6.name = "Jimmy Bob Six";
jimmybob6.coolness = -42;
jimmybob6.friends = 0;
// This will not compile. I am not Jimmy Bob Six.
// Though, in other languages this is possible, you have
// to painfully set each part of the structure in Verge.
overkill = jimmybob6;
/*
NOTE: You shouldn't need to make your own map engine,
I'm just making an example of multi-dimensional
arrays combined with structs.
*/
struct map_type
{
int tile; // A tile on the map
int passable; // If a certain part of the map can be passed over by a sprite.
};
// You cannot have multi-dimensional arrays of structs.
map_type world[100][100];
struct map_type2
{
int tile[100][100];
int passable[100][100];
};
// Map type #2 actually compiles.
map_type2 world;
So, summarizing all this rubbish into more understandable terms:
struct myvariabletype
{
int something;
string somethingelse;
};
myvariabletype myvar;
- struct tells the compiler we're declaring a new type of variable.
- myvariabletype is the name of your new type.
- The braces {} tell the compiler that the stuff in between them is the variables that everything of this type will have in them, or something.
- The semi-colon ; tells the compiler that you're done and that it should move on to your next pieces of code. Don't forget these. If you forget this small thing it will be chaos when you have a large codebase.
- The semi-colon ; after the closing brace }, isn't necessary but I like to use it. This is one of the only places you can have a semi-colon after a closing brace without pulling yourself into a sadistic world of pain.
- A Structure Type (struct) lets you store a bunch of arrays, integers and strings, for simplicity's sake. Then a variable can be declared using this new type that you make.
- You can even have arrays of your structure types.
- Your arrays of your structure types can only be one-dimensional.
- Structures, and variables using this stucture, can't be declared in functions.
- Structure variables cannot be given an initial value upon their declaration.
- Structure variables can only be assigned values to their individual parts. Variables can only be assigned values in functions.
Conclusion
Phew. That was huge. It took me over two days to write thus far in the second chapter. I hope you didn't just read that all at once, that would be tragic and no doubt confounding. If my explanations were too wordy, or too inexplanatory, tell me and I'll try to simplify this later. Anyway, let's move on, shall we?
Operators, Math and Brackets.
All right, math is a big part of programming. Although, not all of it is very hard math. And some of the math you don't even have to understand very well to use it effectively in code.
Operators are the signs that make up the math in programming (adding, subtracting, dividing, multiplying, etc.)
Brackets are used, because Verge³ has no order of operations. An example of 3 + 5 * 2 equals 16, not 13 (BEDMAS). To get it to equal 13 in Verge³, we use brackets to bring priority to the mutliplication: 3 + (5 * 2).
Now that you know a little about operators, let me tell what they are in Verge³:
- Simple Operators
- Addition [+]
int a = 1 + 2; // 3.
- Subtraction [-]
int a = 32 - 5; // 27.
- Multiplication [*]
int a = 6 * 5; // 30.
- Division [/] (rounds down to the nearest whole number)
int a = 15 / 4; // 3 (rounded down from 3.75).
- Modulus [%] (the remainder of the division)
int a = 15 % 4; // 3.
- A power [pow(base, exponent)]
int a = pow(2, 8); // 256 = 28.
- Addition [+]
- Bitwise Operators If you don't know about bitwise operators, it is recommended you skip over this section. For a detailed description of this stuff, read the Verge³ Manual. Otherwise...
- Bitwise AND [&]
a = 7 & 2; // 2. Returns whatever bit is being checked if that bit is on.
- Bitwise OR [|]
a = 0 | 32; // 32. Turns on the 32 bit in the bitfield.
- Bitwise XOR
a = 3 ^ 2; // 1. Toggles the 2 bit in the bitfield.
- Bitwise NOT is NOT (pun lolol) an operator in Verge³ for some reason. However, it can be done via emulation:
(bit_field | bit_mask) ^ bit_mask;a = (7 | 2) ^ 2; // 5. Turns off the 2 in the bitfield.
- Bitshift Left [<<]
a = 2 << 3; // 16.
- Bitshift Right [>>]
a = 16 >> 3; // 2.
- Bitwise AND [&]
- Integer Variable Operators
- Assignment [=] Sets the the value of a variable on the left side to the value on the right side.
coolness = 1337;
- Increase [++] Increases the value of a variable by one.
a++;
- Decrease [--] Decreases the value of a variable by one.
b--;
- Increment [+=] Increases the value of a variable by the value on the right side.
a += 16;
- Decrement [-=] Decreases the value of a variable by the value on the right side.
b -= 4 * 2;
- Assignment [=] Sets the the value of a variable on the left side to the value on the right side.
- Logical Operators Used with if(), while() and for() structures, which are explained later.
- Equality [==]. Returns true when the left side equals the right side.
- Inequality [!=]. Returns true when the left side doesn't equal the right side.
- Greater Than [>]. Returns true when the left side is greater than the right side.
- Less Than [<]. Returns true when the left side is less than the right side.
- Greater Than or Equal [>=]. Returns true when the left side is greater than or equal to the right side.
- Less Than or Equal [<=]. Returns true when the left side is less than or equal to the right side.
- NOT [!]. Returns true when the left side is less than or equal to the right side.
- OR [||]. Returns true when the left side is less than or equal to the right side.
- AND [&&]. Returns true when the left side is less than or equal to the right side.
There are more operators, but I suggest you read the Verge³ Manual for the full spiel.
Next Time, You'll do it IF I say so or ELSE!
The title may have given away what this chapter is about, maybe not. It's about if() statements and else statements. These things allow certain parts of your code to only be executed when a certain condition is met. For example, you only want to be get a "Game Over" IF you lost.
The basic syntax of if() is:
if (condition that must be true)
{
// Code.
}
Example:
// Is humble when you're the cool rocker...
if (you_rock)
{
Exit("I am not nearly as cool as thou.");
}
// ...but taunts you if you aren't!
else
{
Exit("You suck, leave my presence at once.");
}
// If you rock, and ROCK ALOT, your awesome presence kills people.
if (you_rock && you_rock_alot)
{
Exit("Please... leave. Your awesomeness is fatal.");
}
// If you suck, or I hate you, go kill yourself.
if (you_suck || i_hate_you)
{
Exit("Go kill yourself. Thanks.");
}
if (you_only_have_one_thing_to_execute) YouCanDoThis();
else
{
YouHaveToUseBracesAsUsualWhenYouHaveMultipleThingsToExecute();
OtherwiseTheCompilerWillDoWeirdThings();
}
Example 2: Compiler Issues!
if ((has_key && door_is_locked) || !door_is_locked)
{
MysteriousDoorOpening();
}
...This will not compile. It's not your fault. It's Verge³'s. If you want both && and || or in your statements, you have to use work-arounds. These work-arounds include nested ifs, function calls, or seperate ifs for each.
- if() statements are control structures, that execute a certain statement if the condition is met (true) at the time of checking.
- The parentheses () tell the compiler what condition must be met before certain things are executed.
- The braces {} tell the compiler what you want to be executed only when the condition is met. Make it a habit to close every brace you open.
- if() statements have... some issues. See Example 2.
WHILE You're at it...
Har har, another punny title. Now, we're going to learn about while() statements. While() statements are a type of loop (something that repeats itself), that repeats as long as the supplied condition is true. These loops are dangerous if you're not careful, because eternal loops without a ShowPage() command in them will freeze Verge³. So, it's good practice to either make sure your loops all have ShowPage(), or the condition of the loop is possible to be met.
The basic syntax of while() loops is:
while (condition that must be true until you want to exit)
{
// Code.
}
Example:
// The program loops until you press button 1 (defaults to [ENTER]).
while(!b1)
{
PrintString(0, 0, screen, 0, "PRESS B1");
ShowPage();
}
// Loops until you press either button 1 or button 3 (defaults to [ESC]).
// Don't be confused! Use && in statements that
// you want to exit when any condition is met.
while(!b1 && !b3)
{
PrintString(0, 0, screen, 0, "PRESS B1 OR B3");
ShowPage();
}
// Loops until you press both button 1 and button 3.
// Don't be confused! Use || in statements that you only
// want to exit when all conditions are met.
while(!b1 || !b3)
{
PrintString(0, 0, screen, 0, "PRESS B1 AND B3");
ShowPage();
}
// A never-starting loop!
while(0)
{
ShowPage();
}
// A never-ending loop!
// Make sure we've got ShowPage() in there, so the window keeps refreshing.
while(1)
{
ShowPage();
}
- while() statements are control structures, that execute a certain segment as long as the condition is met (true).
- The parentheses () tell the compiler what condition must be met in order for things to continue to be executed. It should also be possible to make this condition false somewhere in your loop so that the program can continue afterward.
- The braces {} tell the compiler what you want to be executed only when the condition is met. Make it a habit to close every brace you open.
- while() statements can freeze Verge³ if you're not careful with the conditions, and you don't have a ShowPage(); call somewhere.
- It's a shame Verge³ doesn't have until() statements, which execute a certain segment as long as the condition isn't met (false).
FOR Everything Else, There's Mastercard
My puns suck. That aside, we're now going to learn about for() statements. For() statements are the other loop type in Verge³. They could be called counting loops, because they only execute a certain segment a certain amount of times. These loops are not in danger of freezing Verge³ (under normal circumstances), unlike while() loops.
The basic syntax of for() loops is:
for (initial value; simple condition; increment/decrement)
{
// Code.
}
Example
int i, j;
// Outputs something along the lines of:
// Hello, number 0
// Hello, number 1
// Hello, number 2
// ... and so on, up to 99.
// The output can be read in v3.log
for (i = 0; i < 100; i++)
{
log("Hello, number " + str(i));
}
// Counts down from 1000 to 1 and logs it.
for (i = 1000; i > 0; i--)
{
log(str(i));
}
// For loops are great for variables with arrays in them.
// This example could be used to heal all the characters fully!
for (i = 0; i < MAX_CHARACTERS; i++)
{
character [i].hp = character [i].maxhp;
}
// Restore all magic points for each level of magic, a la FF1.
// Demonstrates the idea of "nested" for loops.
for (i = 0; i < MAX_CHARACTERS; i++)
{
for (j = 0; j < MAX_MAGIC_LEVEL; j++)
{
character [i].mp[j] = character [i].maxmp[j];
}
}
- for() statements are control structures, that execute a certain segment a certain amount of times.
- You must declare an int for a counting variable. People commonly use i, j, k, l and so on, depending on the number of loops you have inside each other.
- The Initial Value is what you set your counting variable to at the start of the loop. A semicolon ; must follow.
- The Condition is what must be made false for the loop to end. It should be simple, something along the lines of i < 3, and must use the counting variable. A semicolon ; must follow.
- The Increment / Decrement is the amount you want raise or lower your counting variable every time through the loop. A semicolon ; must NOT follow, or else you're in a world of pain.
- The parentheses () tell the compiler what the things are that the for() loop should know.
- The braces {} tell the compiler what you want to be executed a certain amount of times. Make it a habit to close every brace you open.
Let's SWITCH Things Up a Bit
All right, the final control structure in Verge³. switch() statements make it easier to check for a bunch of values that could be given to one variable, instead of having a ton of if()s. You probably won't use switch() often (I don't), but it's your choice.
The basic syntax is:
switch (variable_to_be_checked)
{
case one_number:
// Code.
case another_number:
// Code.
case yet_another_number:
// Code.
case we_sure_like_numbers:
// Code.
}
Examples:
int mystery_number = Random(0, 9);
switch (mystery_number)
{
case 0:
log("Your number is zero.");
case 1:
log("Your number is one.");
case 2:
log("Your number is two.");
case 3:
log("Your number is three.");
case 4:
log("Your number is four.");
case 5:
log("Your number is five.");
case 6:
log("Your number is six.");
case 7:
log("Your number is seven.");
case 8:
log("Your number is eight.");
case 9:
log("Your number is nine.");
}
// BIG NOTE #1: You can't call Map() from a switch statement.
// BIG NOTE #2: You can't use return in a switch statement.
// SOLUTION #1: have a variable that's set in the switch statement accordingly and then
// execute the map() or return.
// SOLUTION #2: Don't use switches! It's rare that you'll ever have to use them.
int last_map_code;
switch (last_map_code)
{
case 0:
Map("happy.map");
case 1:
Map("sad.map");
case 2:
Map("WHY WON'T MY SWITCH CODE WORK.map");
}
- switch() statements are control structures, that execute a certain code depending on the case of a variable.
- The number of times you'll want to use switch() statements is rare. Keep it that way.
- You can't use map() or return in these statements in Verge³.
- Note to C coders: There is no break or continue statements, so only one case will be executed.
- The parentheses () tell the compiler what variable you want to switch() upon.
- The braces {} tell the compiler what you want to be executed a certain amount of times. Make it a habit to close every brace you open.
Functions
Wow, this tutorial is perhaps the most strenuous. I hope someone understands my yammering... Whether you want or not, functions are a vital part of your code. They simplify things by making a certain part of your code be executed when you call on it.
There are three types of functions: void, int, and string.
- void functions "return" a big empty hole, nothing.
- int functions return an integer variable.
- string functions return an string variable.
Examples of void functions:
// A pointless function for now, since it just logs the text,
// but you could make Put() into a fancy textbox function if you wanted.
void Put(string text)
{
log(text);
}
// This calls dennis.
void CallDennis()
{
Put("YES HELLO ITS DENNIS HI I AM FINE HOW ABOUT YOU GOOD");
}
// AutoExec() runs automatically when Verge3 starts.
// In this case, it'll output a call to Dennis every time you hit button 2 (ALT).
// To exit this pointless code piece, you hit button 1 (ENTER).
void AutoExec()
{
int done;
while(!done)
{
if (b1) done = 1;
if (b2) CallDennis();
ShowPage();
}
}
Examples of int functions:
// Adds the variables "a" and "b" together and returns the sum.
// Pointless example, but eh :/
int myadder(int a, int b)
{
return a + b;
}
// Adds the variables "a" and "b" together and returns the sum.
// Oh, ho, tricked you, also adds the sneaky "c" variable into the mix.
int myotheradder(int a, int b)
{
// Local integer. This variable only exists in the function it's made in.
int c = 2;
return a + b + c;
}
void AutoExec()
{
// 1 + 2 = 3!
// Adds the numbers, then converts the sum into a string so it can be logged.
log(str(myadder(1, 2)));
// 1 + 2 = 5 ? o__0
// Clever like a ninja, it added in the value of c (2) when returning the number.
log(str(myotheradder(1, 2)));
}
Examples of string functions:
// Combines the strings "a" and "b" together and returns this new combined string.
// Yet another pointless example, because adding strings shouldn't need a function. ;__;
string concatinate(string a, string b)
{
return a + b;
}
// Combines the strings "a" and "b" together and returns this new combined string.
// Oh, ho, tricked you, also adds the sneaky "c" variable into the mix.
string otherconcatinate(string a, string b)
{
// Local string. This variable only exists in the function it's made in.
string c = " owns.";
return a + b + c;
}
void AutoExec()
{
// Mega + man = Megaman
// Adds the strings, and well at that.
log(concatinate("Mega", "man"));
// Mega + man = Megaman owns.
// Uses impressive ninja skills again. KEKEKE ^___^
log(concatinate("Mega", "man"));
}
- Functions are used to simplify code, allowing you to put simple command calls when using commonly repeated code morsels.
- Functions may or may not return values. void functions don't retun anything. int and string functions return a variable of that type.
- Local variables (as opposed to global variables) are declarable inside functions. However, they can only be int or string, and no arrays. This was said earlier, but I'm summarizing what I said again.
- Things between the the parentheses () tell the compiler what the arguments (variables passed to the function). The arguments can only be int or string, and no arrays. Each argument declared is seperated by a comma. If you don't have any arguments, just put a set parentheses.
- Hey, the easy way to remember what arguments do is to know that they make the compiler angry and argumentative towards you when you fail to supply them.
- The braces {} tell the compiler what you want to be executed when you call this function. Make it a habit to close every brace you open.
- When you call a function, you put the function name, open a parenthesis, put a value for every argument with a comma seperating each, and then a closing parenthesis and a semi-colon. Then you're done.
- Variables can be assigned a value that's returned from int or string function, but obviously need to be an int for int funcs, or string for string funcs.
Preprocess This!
Preprocessor statements are another element of coding. They're basically statements that are executed before the code is processed.
There are two types of preprocessors:
- #include lets you load any plain text file of any name or extension for compilation with Verge.
- #define lets you set constant values at the start of the code.
Example of #include:
#include "graphics.vc" #include "battle.vc"
Example of #define:
#define CHARACTER_TOTAL 10
#define CHARACTER_MAX_LEVEL 99
struct character_type
{
string name;
int level;
int hp, mp;
int maxhp, maxmp;
};
character_type character[CHARACTER_TOTAL];
Now, for some notes.
- #include loads a code file. It must exist for VC to compile
- #define is useful for declaring array sizes, and constant number values. It's not so great for constant strings, so just declaring strings as normal global variables is a better idea.
- Order of preprocessors is important. If you have something #defined in an #included file, but another file that was #included before is using this #defined value, then it'll give you errors. Confusing, yes, so make sure that you have your code set up in a way that any #defined constant will have been declared before any part of the code puts this value to use.
- It is recommended you always put preprocessors near the top of your code, because again, order is important.
- You can't use #defined values in other #define statements.
- You can't use preprocessors inside functions.
- #define has other uses too, since really all it does it tell the compiler to seek-and-replace a keyword with a value. So you could have a commonly used math algorithm #defined or something, but I'd recommend functions over this, still.
- Preprocessors don't need semi-colons at the end. They need a hash mark #, number sign #, pound sign # or whatever you call it, at the front though.
- PEOPLE USUALLY PUT DEFINED THINGS IN UPPER CASE AND USE UNDERSCORES WHEN THERE'S MULTIPLE WORDS.
Naming and You
There's naming conventions people tend to stick to for their code. It's good practice to follow them, so others can easily pick up your code if they want to help you and it looks tidy.
- Functions usually have names that LookLikeThis()
- Variables usually have names that look_like_this
- Variables also sometimes have names that lookLikeThisButIFindThisUglySoPleaseTryToFightTheUrge
- Constants (#defined things) have names that LOOK_LIKE_THIS
- Use regular letters for naming. You don't need á, Þ, and $ all over.
- Numbers can't go at the start of a variable name. The compiler will yell at you. But you can have a number following an acceptable character.
- Punctuation and/or math symbols can't go in a variable name. The compiler will yell at you.
- No spaces in a variable name. The compiler will yell at you.
- Abbreviated variable names are allowed, but make sure you don't overabbreviate. If you use uncommon acroynmns, you should put a comment beside the variable, saying what it stands for.
- Name things by their purpose, not just something random because you suddenly feel like it. This is what we call semantics, and it'll help your code be more easily understood by outsiders and you.
Tabs, Spaces and New Lines are Your Best Friends.
That's right, three keys on your keyboard will become your new best friends. Tab, Enter and the Space Bar keys. These will make your code astoundingly more legible.
- For every time you have a set of braces {}, put a tab indentation for each line in between these braces. This will make it really easy for you to find a missing brace.
- Put a space after every comma, like you should do in English class.
- Put spaces between operators (various math signs) and operands (variables, numbers, etc).
- Put a space between a function or control statement and the open parenthesis that has to follow it.
- When you feel things are cluttered in your code, hit enter until things are set straight. This can make your mess cleaner.
I know you probably don't like this idea of spaces everywhere, but trust me, it makes your code look aesthetically pleasing and much more legible. Please follow these rules at the very least, if possible. If I confused you, I guess you could do it your way, but keep in mind I'm only trying to make your code look better.
Read the Docs
Verge-RPG.com has a documentation section. It teaches a whole lot more, and does it better than me, I think. http://www.verge-rpg.com/docs/ is the place to visit for some interesting reads, some of them even published by yours truly *ahem*. Just so you know.
Don't Hesitate for Help!
If you ever run into major confusion with your code, Verge-RPG.com has a help message board that teaches a lot. You need to get a free username there, then you can post whenever you get a problem. However, some people might yell at you to "Read the Docs"! Heh. http://www.verge-rpg.com/boards/ is the place to go for discussion and help on Verge³, for the most part.
Phew. I did it. Longest. Tutorial. Ever. It took over two weeks to write this bad boy, I hope it wasn't all pointless time-wasting.
-- Overkill