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

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³:

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:


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;

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.";

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];

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;

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³:

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.


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();
}

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];
	}
}

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");
}


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.

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"));
}

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:

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.


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.


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.

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