The VERGE 3 Manual

The reference manual for the VERGE 3 game creation engine.

Dedication

For Sully
VERGE is dedicated to erudite marine life everywhere.

Introduction

"Not documenting important features is a major aspect of the VERGE dev philosophy 
 though! Because it places the knowledge in the hands of an elite priesthood upon 
 whom the lower classes are dependent"
        -Gayo, in the sooper-secret VERGE dev chatroom 

Welcome to VERGE!!!

Okay, well, after too many weeks of coding this system, and 3 hours of data entry, I'm making this library public and calling it a night.

Hopefully vecna will decide to add more infos here and there.

All of the function refernce at the least has a nodeshell that matches up with the most recent v3vergec.txt.

The documentation widget doesn't seem to be working 100% as planned, but I'm sure I can crush the quirks that didn't manifest until I gave it the rigorous testing of the for-real v3 docs tonight.

If anyone wants to start making their own documentation, go right ahead. You may need to log-in and log out after doing so. It may also not work. I've been too busy adding stuff here.

I'll appoint contributors/editors/moderators after I wake up at the boss's discretion.

Sincerely,
McGrue

PS: If you couldn't figure it out, this is a highly temporary introduction.

Variables

What is a variable?

When running any program, certain information need to be kept track of by the computer. For instance, most rpgs will want to know a health value that changes when the player is damaged. To do this, you can 'declare' a variable called "playerhealth", which would then store a number that relates to their health, and then use the name of the variable to refer to it.

Types of variables

Like all programming languages, verge has a several different means of storing data, for different purposes. Each has a subsection, with more information:

Declaration

Declaring a variable is creating it. You cannot use a variable without creating it first. In verge the syntax is:

(type of variable) (name of variable);

So, in our example, we would write the following line of code:

int playerhealth;

This says we want to use a number, which we are going to refer to as "playerhealth" from now on. Arrays and structs are handled rather differently, see their specific sections for more information, but strings are similar:

string playername;

What we must do is make sure we declare the variable BEFORE using it anywhere else. This generally means you just need to make sure the line you declare the variable is above any lines in which you use it. This is good:

int playerhealth;
playerhealth = 100;

This is BAD, verge will not like it:

playerhealth = 100;
int playerhealth;

Note we could also assign a value when we first declare it, this sometimes saves space and confusion:

int playerhealth = 100;

Unlike other programming languages, verge automatically sets numbers to 0 and strings to blank (or "" as it may be referred to), even if you don't assign a value when you first declare it. However, it is considered good practice to make sure you variables always contain something before you use them.

Naming variables

You can call your variable pretty much anything you like, but it's best to name them something obvious that will remind you what information it stores. Verge allows variable names to consist of upper and lower case letters, numbers, and underscores (like _ that). ( Well, to be honest it allows all symbols that aren't reserved as something else, but don't use them. ) However, make sure the name always begins with a letter.

Bad variable names:
hit%    //No special symbols like % allowed
3DModel //Putting a number at the start will make verge try to do maths on your variable)
player$ //(Ok, so the $ is technically allowed, but will cause confusion)
estbx   //(This is allowable, BUT WHAT DOES IT MEAN? Use names that make sense)
Good alternatives:
HitPercent
Model3D
playerMoney
enemy_status_box

Another important thing to note here, is that you need to make sure all things that have names, and might exist at the same time (see scope below) must be called different things. In particular, don't name variables and functions the same, and (for a different reason) don't name ANYTHING the same as defines. A final point here is that unlike in some programming languages, upper and lower case letters are not treated is differently, so make sure to have completely independent names.

Having some kind standard system is useful to keep track of what each name is, however exactly what sort of standard system is the sort of thing programmers can argue over for hours. If you are brave, do a search and pick a method you like. However, I'll give a few guidelines at the bottom of the page that might be useful. Remember, these are not RULES, just SUGGESTIONS.

Scope

In verge, a variable can be either local or global. This is related to whether a variable is declared inside or outside a function. A local variable will only exist for the duration of the function it is in, and will be created every function call. A global variable will exist for the duration of the program itself. Remember, each variable needs a certain amount of computer memory to store it, so even though that's not so much of a problem with modern machines, do try to keep global variables to a minimum. However, at the moment ALL arrays and structs MUST be global, they cannot be declared locally.
Also, scope effects how variable can be named as well. So, you can have to entirely different "x" variables in two different functions, but you cannot have a global "x" and have another "x" variable anywhere else at all.

Pointers

If you do not know what pointers are, skip the next section: you're done with this one. ;)

Verge, for all intents and purposes, has no pointers. As such. However, to understand how it handles images, sounds, entities and suchlike, it's useful to know what it is doing. When you use a Load...() function verge assigns what ever you just loaded some space in memory, and records where it is located. It then assigns a number to that location, and gives it back to you. That number can be later used to tell verge which image you want it to use in a function. It's just like saying 1st, 2nd, 3rd, 4th image and so on - verge removes all of the memory management worries from your shoulders.

However, if you simply must have direct memory access, you can, via a very arcane system, directly access memory. To read more on v3's DMA, go [here].

Integers

Integers hold non-fractional numerical values. An "int" can have a value from -2,147,483,648 to 2,147,483,647.

int an_int; //this creates an int named 'an_int'
int another_int; //this creates another int.

an_int = 5; //this sets it to the value 5.
another_int = 3; //another_int is now equal to 3.

another_int = an_int; //another_int is now equal to 5.

an_int = 7; //an_int is now 7, but another_int is still 5.

The verge integer is 32 bit, here's a detailed run down of what that means:
In a 32 bit integer, there are 32 bits than can be either on or off
This is 2^32 combinations, or 4294967296
Binary numbers: 0 1 0 1 1.....0
Equivalent to: 2^0+2^1+2^2+2^3+2^4...-2^31
Which is: 1 + 2 + 4 + 8 + 16....-2147483648
Why is the last number (bit) negative?
So we can store all the negative numbers easily as well.
Then it is still just case of adding to bits to get the number.
Note that as 0 has to be stored as well, there is one less positive than negative
So in a 32 bit int, the number can be between -2^31 and 2^31-1
Alternatively in decimal from -2147483648 to 2147483647
Eg. The number 13 is stored as 8+4+1 or 1011000...0
The number -13 is stored as -2147483648 plus everything BUT 8+4 so 11001111...1
Note that the +1 is still on, as negative numbers stretch one lower than positives
Because the top bit is negative, in an overflow case (trying to store to large a number) you will 'wrap around' and get a negative number.

Fixed-point

An overview of fixed-point notation

by aen, grade 6

Fixed-point is a way of treating whole numbers as both whole and fractional parts. It's called fixed point because you decide how much precision you need. Do you need to be able to represent halves? Tenths? Hundredths? Thousandths?

You can sort of think of fixed-point as a "secret code" for numbering. I'm sure you've heard of such numbering systems as binary, hexadecimal, and octal. Binary uses only 1s and 0s. Octal uses the numbers 0 through 7. Hexadecimal uses the numbers 0 through 9 and also the letters A through F.

Fixed-point also has a special sytstem for representing numbers. One example could be the number 100. You could decide, for example, that you want your fixed-point system to be able to track precision into the tenths. In that case, you could say that every ten numbers represent 1 whole number. The number 100, then, would end up being representative of the number 10.

How is that pulled off? The numbers 0 through 9 would equate to 0, 10 through 19 would equal 1, 20 through 29 would equal 2, etc. You can basically "decode" a system like this by dividing a number by 10. This division yields the integer part of your number. The fractional part is the number modulus 10. If you are unfamiliar with modulus, it's just the remainder of a division. For example, 13/10 equals 1 with a remainder of 3, so 3 is your fractional part.

When dealing with tenths, you're always going to have a fractional part of 0 through 9. In this case, these values correspond directly to .0, .1, .2, etc. However, if you decide to go with different precisions, this will not always be the case. If you were dealing in fourths for example (division and modulus by 4), you would have to take that into account when interpreting the fractional part. Fractionl parts are basically percentages of a whole number, so with fourths the fractional part is going to be one of 0, 1, 2, or 3. 0 would be 0% or .0, 1 would be 1/4th or .25, 2 would be 2/4ths or .5, and 3 would be 3/4ths or .75.

You may see a lot of >>8 or >>16 going on in fixed-point examples in C all over the web. This is basically the same as dividing by 256 or 65,536. Usually you'll see >>8 when dealing with 16-bit numbers, since 8 is half that many bits, or >>16 when dealing with 32-bit numbers for the same reason. These systems are capable of precision up to 256ths or 65,536ths, basically. Sometimes people aren't too picky about how much precision is needed, which is why they'll just split things down the middle like that. Bit shifting can also be faster, which is another reason you'll see it all over the place. As long as you understand the concept, you can do it any which-way you want!

See Also: Book of Hook - An Introduction to Fixed Point Math

Strings

Strings hold phrases of text in them.

string your_name; //this creates a string named 'your_name'

your_name = "mud"; //this sets your_name to the value 'mud'

Is a string a fixed number of characters?

vec: No. There's limits in some situations.. log and exit() probably have limits of 4k. But general string ops are virtually unlimited.
Gayo: Nyahaha. I set up a loop to double the size of a string with every iteration and got to several hundred megs of memory usage before giving up.
Because the memory is dynamically allocated to the string at runtime, you have very few bounds worries.

Arrays

strings and ints may also be put into arrays. Arrays can only be declared with constant values.

int numbers[15]; //makes a list of 15 integers

string names[7]; //this one is a list of 7 strings

numbers[0] = 42; //this sets the first member of 'numbers' to 42.
numbers[14] = 3; //this sets the last member of 'numbers' to 3.

// the following line will do very very bad things
// because it is setting data outside of the array's bounds.
numbers[15] = 3; 

//The following is also illegal:
int foo = 17;
int illegal[foo]; //verge does not allow this.

Arrays are defined with the number of elements that they contain, but when accessing the elements you start counting with 0. So if you have 15 elements, they are numbered 0 through 14.

Arrays can also be created in multiple dimensions.

//this creates a 2-dimensional array of ints
int mock_screen[320][240];

//this sets element 0,0 of the array to 12
mock_screen[0][0] = 12; 

//this sets element 123,79 of the array to 43
mock_screen[123][79] = 43;


//this creates a 3-dimensional array of ints.
string goats[100][100][100];

//this sets element 0,41,12 of this array to "Toothgnip".
goats[0][41][12] = "Toothgnip";

//this makes a 10-dimensional array of ints.
//making a multi-dim array this big is stupid, 
//but possible.
int tacos[5][4][17][22][79][34][11][19][7000][2];

You cannot set an array instance equal to another array instance. You may only set array elements. To wit, the following is completely bad and wrong:

int list_a[100];
int list_b[100];

list_a = list_b; //NO!

Structs

The struct is a custom-made type of variable that you can put multiple ints and strings inside of.


//
// The below defines a struct named 'user'

struct user 
{
  int id;
  string name;
  int coolness;
  string pet_names[15];
  int bank_account_numbers[4];
}

//
// Now that 'user' is defined, we can make specific
// instances of it

user mcgrue;
user vecna;

//
// And now we can alter these instances just like you 
// could alter an int or string... except with special syntax!

mcgrue.name = "Ben";
vecna.name = "Also Ben";
vecna.coolness = 7;
mcgrue.pet_names[0] = "Oliver";

//Note: While you can set the member variables of a struct, 
// you cannot copy an entire struct's contents to another instance
// of that struct.  To wit, the following is completely illegal:

mcgrue = vecna; //THIS WILL NOT COMPILE.

and finally, you can make arrays and multidimensional arrays of structs. This is generally the best way to use structs since you cannot copy them via reference like in the previous example, so to move them around it's best to keep them all in the same array.


struct point
{
  int x, y, z;
  int color;
}

//makes an array of 1000 points
point buncha_points[1000];

//this set's element 3's x-variable to 20.
buncha_points[3].x = 20;
New in Verge 3.1, you can nest structures, which is very useful. You have to still address each struct item by individual pieces, since Verge can't copy structs or do references at the moment.
struct spell
{
  string name;
  int mp_cost;
};

struct party_member
{
  string name;
  int hp, max_hp;
  int mp, max_mp;
  int atk;
  int def;
  spell spells[8]; // This creates 8 spell structures for each party member made!
};
party_member party_members[5]; // 5 party members.

party_members[0].name = "Bob";
party_members[0].atk = 6000;
party_members[0].spells[0].name = "Fire";
party_members[0].spells[2].name = "Wind";

// THIS WILL NOT WORK
party_members[0].spells[2] = party_members[0].spells[0];

Language Specification

VergeC, or vc, is a C-like scripting language created specifically for use in creating VERGE games.

You create vc files in any text editor you want, and when you run verge.exe (with releasemode 0 set in your verge.cfg), the engine will attempt to compile your code starting with a mandatory system.vc file in the same base directory as the engine file, and then any other vc files you #include therein.

Basic Syntax

As a C-like scripting language, vc has certain syntax rules that need to be adhered to. For veteran coders, much of this will be old-hat.

First off, the semicolon is analguous to a period in english. It denotes the end of a statement. Whenever you declare a variable, set a variable, or call a statement, you need to end the line with a semicolon, like so:

int a_variable;

a_variable = 42;

some_function();

Curly braces are also prevalent, acting as bookends between a block of code. Whenever using conditionals or defining a function, you will be using curly braces to delimit the boundaries of the conditional or function, like so:


void some_function() 
{
  if( a_variable == 42 ) 
  {
    exit( "Ah, yes... but what was the question?" );
  }
}

Notice how everytime I opened a curly brace I tabbed everything in a level, and when the curly brace was closed I deleted that level of tab. This is not strictly neccesary, but a very good habit to get into to make your code more readable to others... which is an exceptionally good thing if you want help debugging your program from others. ;)

The rest of the syntax will be covered in their specific sections. A whole plethora of odd symbols awaits the novice programmer. You can find syntax highlighting files for text editors in the [files section]. We strongly suggest you get one and use the appropriate text editor (everyone on the verge development team uses [textpad]). We would be lost in a sea of bland symbols ourselves without syntax highlighting, you surely shouldn't go it without.

Operators

For those of you familiar with C, I'll give you a quick rundown (everyone else skip this paragraph): VERGE has pretty much all the C operators you'll need except pointer stuff. It has no order of operations. There's no *=, /=, or %=, but there is a += and -=. The assignment operators do not return values and as such cannot be used inside an arithmetic or logical expression. Since all integers are signed, bitshifting is automatically signed as well.

Verge contains five kinds of "operators" used to build statements. An operator is a symbol which, when combined with one or more "operands" (constants, variables, or expressions), changes the value of the operands or produces a new value based on them. For example, the + arithmetic operator takes two integer operands and produces a new integer which is the sum of those two.

Operators are either unary or binary; that is, they take either one or two operands. Unary operators either precede or follow their operands, whereas binary operators have are placed in between their two operands. The + operator mentioned above is binary, so its operators are placed on either side; to produce the sum of 5 and 6, we type "5 + 6". Except where otherwise stated, all the operators described below are binary.

ARITHMETIC OPERATORS:

The arithmetic operators represent fundamental mathematical operations such as addition and subtraction.

Addition (+): The addition operator generates a new number that is the sum of its operands.

Subtraction (-): The subtraction operator generates a new number that is the difference of its operands. Order is important; the operand after the minus sign is subtracted from the one before it.

Multiplication (*): The multiplication operator generates a new number that is the product of its operands.

Division (/): The division operator generates a new number that is the quotient of its operands. As with subtraction, order is important; the first operand is the numerator, the second the denominator. This is integer division, which means that the final value is always an integer, rounded down if necessary.

Modulus (%): The modulus operator returns the remainder of the division of the first operand by the second.

Arithmetic operators can be combined into complex arithmetic expressions. They are evaluated from left to right; that is to say, there is no order of operations. To enforce a specific evaluation order, you may use parentheses.

// Arithmetic Operator examples
int n = 0;      // n starts out as 0

n = 2 + 3;      // Addition: n is now 5
n = 12 - n;     // Subtraction: n is now 7
n = 2 * 4;      // Multiplication: n is now 8
n = n / 2;      // Division: n is now 4
n = 10 % 3;     // Modulus: n is now 1 (the remainder of 10 / 3)

// Examples of complex expressions

n = 1 + 3 * 5;                    // n is now 20 (since there's no order of operations)
n = 100 % (9 * 3);                // n is now 19 (the remainder of 100 / 27)
n = 2 * (5 - (7 * 3));            // n is now -32

BITWISE OPERATORS:

Bitwise operators are so called because they operate individually on every bit of a (32-bit signed) integer. Because they manipulate numbers on a binary level, they are somewhat tricky for beginners. If you feel comfortable with them, however, you can use bitwise operators freely in arithmetic expressions.

Bitwise OR (|): The Bitwise OR generates a new value by ORing each bit of the two operands. What this means is that the new value will have a 1 in each bit location where either or both of the operands had a 1, and a 0 in every other bit location.

Bitwise AND (&): The Bitwise AND generates a new value by ANDing each bit of the two operands. What this means is that the new value will have a 0 in each bit location where either or both of the operands had a 0, and a 1 in every other bit location.

Bitwise XOR (^): The Bitwise XOR generates a new value by exclusive-ORing each bit of the two operands. What this means is that the new value will have a 1 in each bit location where either one or the other but not both of the operands had a 1, and a 0 in every other bit location.

Bitwise NOT (~): The Bitwise NOT, a unary operator that precedes its operand, generates a new value by inverting each bit in the bitfield. All bits that were 1 are now 0, and all bits that were 0 are now 1. To toggle a single bit, use a bitwise XOR of the notted bit

Left Bitshift (<<): The Left Bitshift operator generates a new number which is its first operand with all the bits shifted left a number of spaces equal to the value of the second operand. If this sounds confusing, here's an easier way to think about it: in the expression m << n, the value returned is equal to m multiplied by 2 to the nth power.

Right Bitshift (>>): The Right Bitshift operator generates a new number which its its first operand with all the bits shifted right a number of spaces equal to the value of the second operand. In the expression m>>n, the value returned is equal to m divided by 2 to the nth power (using integer division, naturally).

LOGICAL OPERATORS:

The logical operators can be used only in the conditions of if and while statements. They return either true (a nonzero number) or false (zero). Like arithmetic operators, logical operators take integer variables, constants, or expressions (arithmetic or logical) as their operands, and are evaluated from left to right.

Equality (==): The Equality operator returns true if the two operands are equal; otherwise, it returns false. It is represented as a double equals sign to differentiate it from the Assignment operator (which see). Note that neither strings nor structs can be used as logical operands, so this operator cannot be used to test their equality.

Inequality (!=): The Inequality operator returns true if the two operands are inequal; otherwise, it returns false.

Greater Than (>): Greater Than returns true if the first operand is greater than the second; otherwise, it returns false.

Lesser Than (<): Lesser Than returns true if the first operand is lesser than the second; otherwise, it returns false.

Greater Than or Equal To (>=): Greater Than or Equal To returns true if the first operand is greater than or equal to the second; otherwise, it returns false.

Lesser Than or Equal To (<=): Lesser Than or Equal To returns true if the first operand is lesser than or equal to the second; otherwise, it returns false.

Logical OR (||) (also simply the keyword "or"): The logical OR returns true if either or both of its operands are true; otherwise, it returns false.

Logical AND (&&) (also simply the keyword "and"): The logical OR returns true only if both of its operands are true; otherwise, it returns false.

Logical NOT (!) (also simply the keyword "not"): The logical NOT is a unary operator that precedes its operand. It returns true if its operand is false; otherwise it returns true.

Note that there is no logical XOR in VERGE.

ASSIGNMENT OPERATORS:

Assignment operators are special in that they actually change the value of one of their operands. The operand to be changed must be a variable, since only variables can have their values altered. Assignment operators are also unique because they do not return values; for this reason, they cannot be used inside expressions.

Assignment (=): The ordinary assignment operator changes the the value of the first operand to the value of the second.

Increment (++): Increment is a unary operator that follows its operand. It increases the value of its single operand by 1.

Decrement (--): Decrement is a unary operator that follows its operand. It decreases the value of its single operand by 1.

Increase (+=): The Increase operator increases the value of the first operand by the value of the second.

Decrease (-=): The Decrease operator decreases the value of the first operand by the value of the second.

The ordinary assignment operator (=) can be used within a declaration statement to initialize a newly declared variable to a specific value.

// Assignment operator examples
int n = 2;        // n is declared and assigned the value of 2
n = 7;            // n is assigned the value of 7
n++;              // n is now 8
n--;              // n is now 7 again
n += 12 + n;      // n is now 26
n -= n;           // n is now 0

STRING OPERATORS:

There are only two string operators in VERGE. They accept only string variables, string literals, and functions that return strings as their operands.

String Concatenation (+): The string concatenation operator is the plus sign, just like the addition operator. Since the operator is preceded by its first operand, the compiler figures out whether it's doing addition or concatenation by looking at the type (int or string) of that operand. Concatenation produces a new string composed of the second operand appended to the first.

String Assignment (=): The String Assignment operator is identical to the ordinary assignment operator, except it functions on strings rather than integers.

// String concatenation examples
string s = "";                     // s is declared and set to an empty string
string s = "hell" + "o";           // s is now "hello"
string s = "why " + s + " there";  // s is now "why hello there"

As of Verge 3.1, the += operator is a valid shortcut to add strings together.

string s = "Fish";
s = s + " and Chips"; // The old way of joining strings together
s += " and Chips"; // Now a valid shortcut.

As of Verge 3.1, you can put parentheses directly after a string, and the compiler will interpret that as a CallFunction.

CallFunction("myfunction"); // Uses CallFunction call the function named "myfunction" at runtime.
"myfunction"(); // Same thing, but less typing, and can make string variables look more like function pointers in some code.

Comments

Just as in VC1 and VC2, both C and C++ style comment conventions are supported.

Comments: Comments are not required in your VergeC code, but smart coders will use them to help organize and make their scripts readable for future reference. They are ignored by the compiler. There are two ways to use comments:

  1. If you type a double slash (//) in your code, everything on that line after the slashes will be ignored.
    void dex_join  // #75: When Dexter joins
    {
      AddPlayer(3);
    }
    
  2. The second method is to use /* and */. When the compiler encounters a /*, everything will be ignored until it sees a */. Example:
    void dex_join
    {
      /* This is the part where Dexter joins after
      being seen on the path of Jujube mountains.
      The event below is number 75. */
      
      addcharacter(3);
    }
    

The // is preferred for simple phrases that you wish commented, while the /* */ method is best for large areas of text to be left commented.

NOTE: Try using commenting if you have a problematic area of your event script that refuses to compile. Use // before the lines that create errors and try recompiling until you can isolate the problem.

Preprocessor Directives

Preprocessor directives are special statements that begin with a pound # sign, and are the only ones that don't need the semi-colon ; at the end.

Preprocessor directives must be in a linear order, and BEFORE the code to keep certain errors from coming up.

There are two important directives:

Control Structures

VergeC 3 supports most of the code control structures that genuine ANSI C does, with some differences that are explained below:

  1. IFs: if statements are the most basic form of code execution control. They have been much improved since VC1, primarily from the addition of OR conditionals as well as the ELSE branching statement. The basic format of an IF is:
    if ([condition])
    {
      (code to be executed if condition is true)
    }
    else
    {
      (code to be executed if condition is false)
    }
    
  2. SWITCHes: switch/case statements basically replace a series of IF statements. Cases are yet another method of simplifying and empowering your VC code's flexibility. They are most useful in situations where you wish to provide multiple results based on the condition of some variable. Here's how they're used:
    Switch([variable to be tested])
    {
      Case [result 1]: [command];
      Case [result 2]: [command];
      Case [result 3]: [command];
      Default: [command];
    }
    

    When the interpreter encounters this construct, it will test the value of what is given in the Switch parentheses, then run the Case statement that matches it, if any. If no Case matches, it will use the Default case, assuming one exists (a default case is optional). Note that unlike C, switch cases can be expressions or functions that are evaluated at runtime. Also unlike C, no break; statements are in the below example; break statement in VC are not only unnecessary but will cause an error if they are present. Example:

    switch ( Party[0] ) //checking the first person in the party...
    {
      case 1: Text(DARIN,"My name's Darin and I'm leading this party!","","");
      case 2: Text(SARA,"I'm Sara and I'm here to pump you up!","","");
      case 3: Text(DEXTER,"Dexter is leading this party.","","");
    }
    
  3. FOR loops:FOR loops are perhaps more commonly used than WHILE, altho I personally dig WHILE loops greatly. Anyhow, FOR loops in VergeC 2.0 are much closer to their true C counterparts than they were in VC1. The syntax now is:
    for (init; condition; post)
    {
      commands;
    }
    

    To clarify, an example would be:

    for (i=0; i<5; i++)
    {
      printstring(0, 0, screen, i, "This is font "+str(i)+".");
    }
    
  4. WHILE loops: These work much the same as FOR loops do, but can use nearly any condition to control how long it executes. The syntax is such:
    while ([condition])
    {
      commands;
    }
    

    The condition inside the parentheses after WHILE can be anything you can stuff in an IF statement. When the engine encounters a WHILE loop, it will repeatedly execute the commands inside the curly braces until the condition inside the parentheses is NOT true. Therefore, your WHILE loop should contain some commands that affect that condition, or else your loop will run endlessly.

  5. New in Verge 3.1, UNTIL loops and UNLESS statements. They are essentially another way of expressing while(!(condition)) and if(!(condition)), respectively.
V3 logical expressions are not short-circuited: every part of the condition is evaluated, even if unnecessary.

Functions

Functions are blocks of code that accomplish some task whenever they are called. Some functions return values (string or int), while others don't (void). They are very much similar to C functions.

// void function - returns nothing.
// Autoexec() is special, since it's called on startup.
void Autoexec()
{
  Log("1 + 1 = " + str(MyAdder(1, 1)));
  Log(MyConcater("Hello", "World!");
}

int MyAdder(int a, int b)
{
  return a + b;
}

string MyConcater(string a, string b)
{
  return a + " " + b;
}

Recursive functions are possible in verge, and the depth of recursion is limited by the memory of the system it is running on, as opposed to a fixed limit.

// An example of recursion using factorials.
// Factorial(n) == n * (n-1) * (n-2) * ... * 3 * 2 * 1,
// Where n is a natural number, also Factorial(0) == 1.
int Factorial (int n)
{
  if (n <= 0)
  {
    return 1;
  }
  else
  {
    return n * Factorial (n - 1);
  }
}

Verge does not support prototypes. Do not use them. Indeed, prototypes are not necessary at all in verge. All function names are known to all other functions.

For example, there is no need for this:

int MyFunc(int arg1, int arg2);

void Autoexec()
{
  // Code
}

int MyFunc(int arg1, int arg2)
{
  // Code
}
Unlike C, in VC there are no pointer & / dereference * operators. The only arguments passable to a function are integers and strings. The only permissible return values are int, string, or void. This is an inconvenience, meaning arrays and structures can't be passed directly, and instead indices to the respective arrays must be passed. However, you can get used to this shortcoming over time.

System and Map Code

Since V2, VERGE has had this concept of separate system codespace and map codespace. While in V1, everything happened in the map VC, in V2 and V3, the majority of the important code is now in the realm of the system code, while only events and code relevant to that map is in the map codespace.

In V3, the only 3 files you need to make a barebones VERGE game are verge.exe, fmod.dll, and system.vc.

Inside system.vc, the function autoexec() is called once verge has finished initializing. That is your entry point. You can #include any number of additional .VC files into your system.vc in order to provide a logical breakdown of your code components into different source files, for instance, menu.vc, effects.vc, etc. These are all considered to be part of the system codespace.

Any functions, variables, or structs you declare in any system file are considered globally accessable. You can access system code and variables from a map VC. In general, most of the descriptions of code you will see in tutorials and discussions on the forum are implicitly describing system VC code. Aside from some enhancements, the general concept and structure of system VC code has not changed since V2.

Map code, however, has changed a good bit since V2. In V2, your map code consisted of numbered events rather than the named functions you see in system VC code.

In V3, its more accurate to think of a map's VC code as an extension of system.vc, but that only 'exists' while that particular map is loaded. In reality, the functions that are declared in your map VC are simply added onto V3's list of system functions when the map is loaded, and unloaded when the map is changed. You can declare as many named functions as you like, functions that return values, helper functions, functions with local variables.

Its important to understand however that these functions only exist when that map is laoded. This has the following consequences: One other note. While event zero was always the 'autoexec' event of a map in V2, in V3, each map has (in the Map Properties dialog) a simple string arguement called startup script. This is simply the name of the function - if any - you would like called when the map is loaded. Since I said before that MAP VC is simply an extension of system VC that only exists for that map, you can use either a system VC function name or a map VC function name as your startup script - or for any other script arguement, such as an entities activation script, or a zone's script.

This also means that you can do things like: Set your HookRender function to a MAP vc name and leave it. If the function does not exist, the HookRender will simply do nothing. When you enter a map that defines that function name, it will be used for the HookRender, and when you enter a different map that uses the same function name, that map's appropriate function will be used instead.

DMA

Access a DMA buffer via the following arrays:

dma.byte[offset]; // 0 to 256
dma.word[offset]; // 0 to 65536 - takes up two bytes.
dma.quad[offset]; // 0 to 4294967296 - takes up four bytes.
dma.sbyte[offset];  // -128 to 127
dma.sword[offset];  // -32768 to 32767 - takes up two bytes.
dma.squad[offset];  // -2147483648 to 2147483647 - takes up four bytes.

The latter three use a signed representation of the data for reading purposes. Quads cannot be read as unsigned, as they need to be converted into integers in order to be used (which are signed quads)

int buf = malloc(10);
int ofs = 4;
dma.byte[buf+ofs] = -1;
messagebox(dma.byte[buf+ofs]); //will display 255
messagebox(dma.sbyte[buf+ofs]); //will display -1

Malloc

int Malloc (int size)

Allocates a chunk of memory and returns a pointer handle to it.

Example usage:

int mypointer = Malloc(256); // mypointer now points to a 256 byte chunk of memory.

Returns a pointer to a newly allocated memory space of the specified size.

Note: This function is not intended for general use. It is only for advanced users. There is rarely a need to use it. Memory blocks allocated with Malloc should be freed with MemFree, which is not interchangeable with FreeImage, FreeSound, FreeFont, or anything else.

MemCopy

void MemCopy (int source, int dest, int size)

Copies a block of memory from one location to another.

Example usage:

int ptr1 = Malloc(256);
int ptr2 = Malloc(256);

MemCopy(ptr1, ptr2, 256);

Does a direct memory copy between two memory pointers. This is an advanced function and should, generally speaking, not be used. ^_^

MemFree

void MemFree (int pointer)

Frees a malloc()-allocated block of memory. (Incompatible with non-DMA memory.)

Example usage:

int myptr = Malloc(256);

MemFree(myptr);

Frees a memory block allocated with Malloc. This is not interchangeable with any other Free function, such as FreeImage. Other V3 constructs such as images, fonts, and sounds are virtual objects which return handles and not direct pointers.

Engine

Download the Current Engine. This has no pack-in demo, but includes everything you need to start making games in Verge3.

Here is a list of the contents of the engine download, and what each file is.

Verge.cfg Options

xres [res] -width of screeen in pixels

yres [res] -height of screeen in pixels (note this is different than vid_mode or whatever).

nosound [0/1] - turn sound on or off

windowmode [0/1] - fullscreen mode or windowed mode

automax [0/1] - maximizes window automatically

releasemode [0/1] - to compile or not to compile

startmap [mapname] - initial map

vcverbose [0/1] - controls whether or not verge generates vccverbose.txt during compilation (default 0)

editcode [0/1] - you can reload and evaluate code at runtime. Incompatible with releasemode.

lua [0/1] - whether or not the Lua scripting language is used instead

soundengine [engine id] - an id 0 is FMOD, 2 is Audiere.

logconsole - if this is present, the same output that would go to v3.log also goes to a console window that will spawn at runtime.

logconsole-normalstdout - if this is present, the same logspew will happen as with logconsole, excepting that if you manually repipe stdout, it'll go there instead of spawning a console window. This is very useful if you use TextPad to execute verge via it's 'tools' menu.
Note that this config variable will not happen if logconsole is also active in the verge.cfg file.

(from v3changelog.txt)

- Added 'gamerate' verge.cfg option, will set the timer think rate. Note that using the default of 100 is highly recommended unless you know what you're doing - changing this value will effect the timing of EVERYTHING.

Changelog

========================================
07/21/05
- Mac Version (see included readme for details)
- By putting 'editcode 1' in verge.cfg, you can reload and evaluate code at 
runtime. Incompatible with releasemode.
- New expression parser that includes unary minus, unary bitwise not (~) and 
correct handling of logical operators and parenthesis. Also allows logical 
operators outside of conditionals. (eg. 'int x = a || b')
- verge.cfg now has comments (# or //) and handles tabs. Values must not have 
whitespace.
- Addded curmap.path, which is the path (relative to the verge top directory) of 
the current map.
- Added Read/write access to parallax via layer.parallaxx[],layer.parallaxy[]
- Added ImageValid(int img) to test if an int is a valid image handle
- entity.obstructable[] now works for the player. To help with backwards 
compatibility, SetPlayer() now makes the passed entity obstructable.
- entity.chr[] added to allow read/write access to the CHR for entities
- Added FileEOF(int file). Returns 1 if the current file pos is at the end of the file
- Added asc(). asc() returns the int value of the first character of the passed 
string, returns 0 for '' 
- Removed 253 chr limit on FileReadLn
- Added an _os macro, which can take values 'mac' or 'win'
- Added the _build macro, an int of the form YYYYMMDD
- FileSeekPos's SEEK_END now accepts +ve or -ve values (both mean back from the end)
- Fixed the automax 0 bug on win98 (and XP in odd cases)
- Fixed a bug where a zone might not activate even with 100% activation chance
- Fixed imageshell/rotscale bug 
- Fixed pixel-based movement in movestrings (P/T works now.)
- Fixed a bug with stalking a CHR with different-length walk animation
- Fixed a bug with switching entities from wandering to stalking and back
- Fixed a bug where entities with speed < 100 would barely move
- Fixed a parsing bug with numeric literals at the end of a line
- Fixed a bug where #include's are not parsed property at the end of a file
- Fixed check for arrayness that prevented 1-length arrays

NOTE: This release is incompatible with previous releases' compiled VC

========================================
09/28/04
 - Fixed bug in 32-bit, 50% lucent vertical line render
 - Fixed bug in idle frame handling of follower entities
 - Added code that validates animations when a VSP is loaded.
   Previously if a tileset had an animation which referenced
   tiles greater than the number of tiles in the tileset (because
   some were deleted), the engine would simply crash at random
   times and give no indication of the cause. 
 - Fixed a bug relating to a #define being the last line
   of an #include causing valid VC code to not compile
 - Fixed a crash bug when an integer type is passed
   as a string argument
 - Fixed a crash bug with non-arrayed strings in
   a non-arrayed struct
 - Added CF_CUSTOM color filter mode, along with
   SetCustomColorFilter(int color1, int color2)
 - Added netcode.

========================================
08/01/04
 - Added RenderMap() to allow rendering chunks of map direct to
   an image you specify.
 - Added SetButtonKey() and SetButtonJB() to allow remapping of
   b1-b4; up/down/left/right cannot be remapped because in both
   keyboard and joystick handling, special processing is done
   for these.
 - Bug fixed in FileReadString()
 - Fixed bug causing SetEntitiesPaused() to totally stop responding
   to the message queue in the main game loop
 - FontHeight() no longer returns... the font width.
 - Fixed a bug in PrintRight()
 - automax 0 works again.
 - Added FunctionExists()
 - Added atan2()
 - Added windows clipboard functions CopyImageToClipboard() and 
   GetImageFromClipboard() and the variable clipboard.text
 - Corrected a bug in the vc error system that performs reverse-
   lookups on code offsets for stack traces. This should help fix
   some situations where VERGE crashes due to a (runtime) VC error 
   rather than return an error message.
 - Added GetInt(), SetInt(), GetString(), SetString(),
         GetIntArray(), SetIntArray(), GetStringArray(), and SetStringArray()
 - EntityStop() will now abort any delay commands
 - Added FlipBlit()
 - SetRandSeed() will now give deterministic results.
 - Improved line number error reporting drastically.  
 - Added 'vcverbose [0/1]' verge.cfg command to control if the vc compiler outputs
   vccverbose.txt (defaults 0)
 - cameratracking = 2 functionality added, cameratracker variable added
 - Added several new variables:

  entity.visible
  entity.obstruct
  entity.obstrucable
  entity.script

  curmap.w
  curmap.h
  curmap.startx
  curmap.starty
  curmap.name
  curmap.rstring
  curmap.music
  curmap.tileset

  layer.lucent

========================================
04/21/04
 - Bug in renderstring parser fixed.
 - HookTimer() crash bug fixed. (between this and the above fix,
   it seems most win98-related crashes are gone now too)
 - SCAN_GPLUS is now correctly defined.
 - Upon ChangeCHR(), the entity animation/specframe/etc state will
   be reset to prevent out of bounds frame errors.
 - Maximum image capacity has been increased.
 - Added 'P' and 'T' commands to entity movestrings. P will enable
   pixel-accurate arguements to U/D/L/R (X/Y will still work in tile
   increments). T will set it back to tile increments. 
 - Added 'gamerate' verge.cfg option, will set the timer think rate.
   Note that using the default of 100 is highly recommended unless you
   know what you're doing - changing this value will effect the timing
   of EVERYTHING.
 - You'll no longer get a message looking for a map file if autoexec
   returns without a Map() or Exit() call.
 - Added SetEntitiesPaused() to pause/unpause automatic entity processing.
 - Added SetRandSeed() to allow setting the random number generator seed.
   Note that passing a value of 0 will set a random seed (since generating
   a random seed can be tricky if you already set the random generator's
   seed to something deterministic).
 - Bug causing the maximum volume of SetSongVol() to be 666 (!) instead
   of 100 fixed. I swear, if you saw the math going on, ... 666... wtf.
 - Added HookKey() and HookButton()
 - Tweaked font spacing for fixed-width fonts.
 - Introducing the V3 Sprites system! This is a preliminary version, 
   additional improvements are planned for the next build, including
   horiz/vert flipping, layer specification, and a sprite-thinking 
   callback system that will assist people that have a hard time writing 
   timer-based code :D

========================================
04/09/04
 - GetObsPixel is fixed.
 - entity.frame[] will now account for idle frames.
 - Idle frames will now be the idle frames specified in the
   CHR, not the first frame of the walking animation for that
   direction.
 - cameratracking is fixed.
 - Samples will no longer loop when played regardless of the
   default looping setting of the sample.

========================================
04/04/04
 - Map/Entity/CHR system.
 - Map VC system implemented.
 - Issue with Random seeding has been corrected.
 - Tools and stuff released. 

========================================
02/22/04 
 - Mikmod out. FMOD in. Music API restructured.
   There is now a "simple music" API and an advanced
   music API, which is needed to do things like
   crossfading, pausing, and manipulation of music position.
   Both APIs fully support modules, MIDIs and mp3/oggs.
   Sound effects can also be either wav or mp3/ogg.
   (however they are handled differently. sound effects are
   fully loaded into memory; mp3s played as music are streamed)
 - A bug in for() loops was fixed.
 - The "system" font now renders to any image correctly.
 - A few new window management routines were added.
 - Some new string-handling functions. TokenCount() and
   GetToken() will aid with breaking a string apart for 
   purposes of word wrapping for instance. Also added 
   ToUpper() and ToLower().
 - LoadFont no longer takes w/h arguments. The cell size 
   is automatically detected. Its not foolproof however, in 
   cases where the autodetection fails, you can still use the
   original loader that takes width/height, now named 
   LoadFontEx.
 - Joystick variables are now activated.
 - Miscellaneous new VC commands: FontHeight(), MixColor(),
   and chr().
 - Fixed a bug involving string arrays causing problems with
   all strings declared after it by not updating the offsets
   correctly.
 - Fixed a bizarre bug with launching v3 from Textpad :o
 - Using %s or other %codes in VC strings wont screw stuff
   up anymore.
 - Added lastkey; returns the last key pressed as an ASCII
   character
 - Eagle/2xSAI has been removed until such time as we get around
   to fixing it and putting it back in or giving a care about it
   in general
 - Preliminary AVI playback is in. There are still some bugs
   and quirks that we are working out. We HIGHLY RECOMMEND 
   that you use only simple codecs like intels Indeo and not
   DIVX/XVID due to codec compatibility issues. Unless you 
   plan to make an installer and include the codecs your 
   game uses. ^_^

Planned Features

Next Build:

Well, all the stuff that was on this list is now done. But we can look forward to binary trees (faster compile, better error reporting and faster CallFunction(). Also, hopefuly a little more stuff with entities. :D

Known Issues

Crashes on returning from switch statements. Use a local variable or an if statement instead. This is fixed.

#define macros do not always work as expected. If you experience odd behavior, use a global variable instead.

There is limited support for hexadecimal notation. If your code will not compile, use decimal numbers instead.

if (w & $FF00 == $FF00)
{
    // BROKEN
}
if (w & 65280 == 65280)
{
    // Using decimals works fine
}

This is fixed.

Function Reference

General Utility Functions

For the General System Variables, go [here].

CallFunction

void CallFunction (string funcname)

Executes a function by the name it's given.

Example usage:

//
// A simple example.
//

void MyFunc()  
{ 
  exit( "Hello world!" );
}

void Autoexec()
{
  CallFunction("MyFunc");
}



//
// A more complicated example illuminating the possibilities of this function
//

void FuncA()  
{ 
  log( "Function A was called!  Eeeeh!" );
}

void FuncB()  
{ 
  log( "Function B was called! Bzzzz..." );
}

void Autoexec()
{
  int i, j; //for the for-loop lower down...
  
  // let's make a lookup table
  string MyLookupTable[2]; 
  
  // and now we initialize it...
  MyLookupTable[0] = "FuncA";
  MyLookupTable[1] = "FuncB";
  
  //and now let's set up a silly way to make it look things up
  for( i=0; i<100; i++ ) 
  {
    //j will be randomly set to 0 or 1 each iteration of this loop
    j = Random(0, 1);
    
    CallFunc( MyLookupTable[j] );
  }
}

Calls a function by name. This can be useful for creating "function tables" of a sort, which might be useful for item effects or magic visual effects or things like that.

The function to be called MUST take no parameters. It may or may not return void, but it is impossible to catch the return value when called this way.

If you wish to simulate arguments and return values, it is neccesary to use global variables for both roles. Be careful in doing this, as it leaves a lot of room for user error. I would suggest heavy error checking within the functions, unless the CallFunc is something that's being called frequently.

If the specified function name does not exist, or is a v3 builtin function, CallFunction() will just do nothing (no error messages). If you care that a function exists, please refer to FunctionExists().

CopyArray

int CopyArray (string source, string dest)

Copies data from one global int/string array to another, if they're of compatible size and type.

Example usage:

string foo[2];
string bar[2];

void autoexec() {

    foo[0] = "taco";
    foo[1] = "burrito";

    bar[0] = "carrot";
    bar[1] = "celery";

    CopyArray("foo", "bar"); //bar[0] is now "taco"

    MessageBox( bar[0] );
}

Copies data from one global int/string array to another, if they're of compatible size and type.

Returns 1 on success, 0 on failure.

Exit

void Exit (string message)

Quits the VERGE Engine with the supplied message.

Example usage:

//this exits the program without an alert window.
Exit(""); 


//this exits the program with a little self-centered promotion! :D
Exit("http://vecna.verge-rpg.com");

Exit terminates the verge engine application.

If the message string is empty, it will exit immediately with no message box.

If the message string is not empty, the a message box will pop up with the exit message displayed, when the message box is closed the application will end.

FlushKeyBuffer

void FlushKeyBuffer ()

Clears the key buffer for future GetKeyBuffer() calls.

Example usage:

FlushKeyBuffer();

Clears the key buffer for future GetKeyBuffer() calls. This allows you to figure out what keys are actually new keypresses, by wiping out the old ones after you've taken care of them.

FunctionExists

int FunctionExists (string funcname)

Determines the existance of a given function based on its name.

Example usage:

//copy this all into a blank system.vc and run verge 
//if you don't understand what's going on.

void Sully() 
{
  exit( "I am a clam.  I have no beard.  Isn't that weird?" );
}

void Autoexec() 
{
  if( FunctionExists("Sully") )
  {
    CallFunction( "Sully" );
  }
  else
  {
    exit( "Sully() does not Exist!" );
  }
}

Returns 1 if the function named in the argument exists, 0 if it doesn't exist. However, it does so with the following caveats:

This function is extremely useful for errorchecking purposes when you're using CallFunction() in conjunction with datafile-defined strings, or any other time you're using CallFunction() and explicitly demand that a function exist.

GetInt

int GetInt (string intname)

Returns the value of a global non-array integer variable.

Example usage:

int num;
string my_var = "num"; // my_var now points to num.
GetInt(my_var); // Gets the value of num.

Returns the value of a global non-array integer variable.

GetIntArray

int GetIntArray (string intname, int index)

Returns the value of a global, one-dimensional integer array index.

Example usage:

int num[12];
string my_var = "num"; // my_var now points to num.
int my_index = 7; // my_index is set to 7.
GetIntArray(my_var, my_index); // Gets the value of num[7].

Returns the value of a global, one-dimensional integer array index.

GetKeyBuffer

string GetKeyBuffer ()

Returns a buffer of recent keys pressed in string form.

Example usage:

// Assumes you've declared the following.
// int i; for iteration
// int ch; to store current character being checked.
// string buf; to store all the character retreived from the key buffer.
// string s; for the string to store the all the typing after it's been handled.

buf = GetKeyBuffer();
for (i = 0; i < len(buf); i++)
{
  ch = asc(mid(buf, i, 1));
  if (ch == 8)
  {
    if (len(s))
    {
      s = left(s, len(s) - 1);
    }
  }
  if (ch == '\n')
  {
    // SUBMIT TEXT.
    // If this newline check is ignored, it'll be printed in the text.
  }
  else if (ch == '\t')
  {
    s += "    ";
  }
  else
  {
    s += chr(ch);
  }
}
FlushKeyBuffer(); // Remember to do this after you've checked all the input!

Returns a buffer of recent keys pressed in string form. This function is useful for capturing text input from the keyboard. You should use FlushKeyBuffer(); after the key buffer is retrieved, so that future calls return only new characters.

It allows typing of the standard characters and their upper cases, as well as buffering of enter, tab, and backspace. Backspaces should be iterated through via a VergeC-side loop in order to work, like the example shows.

GetString

string GetString (string strname)

Returns the value of a global non-array string variable.

Example usage:

string name;
string my_var= "name"; // my_var now points to name.
GetString(my_var); // Gets the value of name.

Returns the value of a global non-array string variable.

GetStringArray

string GetStringArray (string strname, int index)

Returns the value of a global, one-dimensional string array index.

Example usage:

string name[98];
string my_var = "name"; // my_var now points to name.
int my_index = 21; // my_index is set to 21.
GetStringArray(my_var, my_index); //Gets the value of name[21].

Returns the value of a global, one-dimensional string array index.

GetUserSystemVcFunctionByIndex

string GetUserSystemVcFunctionByIndex (int function_index)

Returns a user-defined system-scope vc function name by int index

Example usage:

int functionCount = GetUserSystemVcFunctionCount();
Log( "The current game has "+str(functionCount)+" user-defined functions.  Isn't that swell?" );

Log( "Let's print them all out to v3.log!" );

int i = 0;
for( i=0; i

Returns a string of a user-defined system-scope vc function by a numerical index provided. Valid indexes range from 0 inclusive to the maximum bound supplied by GetUserSystemVcFunctionCount() exclusive.

Excludes map-scope user-defined functions of the current (or any) map.

Currently there is no rhyme or reason to the ordering of the functions in the indexed list. The management reserves the right to alphanumerically sort them in the future. Behavior should not be associated with their ordering.

GetUserSystemVcFunctionCount

int GetUserSystemVcFunctionCount ()

Returns the number of system-vc scope functions the current compiled game has.

Example usage:

int functionCount = GetUserSystemVcFunctionCount();
Log( "The current game has "+str(functionCount)+" user-defined functions.  Isn't that swell?" );

Log( "Let's print them all out to v3.log!" );

int i = 0;
for( i=0; iReturns the number of system-vc scope functions the current compiled game has. This does not take into account currently-loaded map-scope vc functions.

HookButton

void HookButton (int button, string function)

Calls the specified function on every discrete press of the specified button

Example usage:

// Put this in system.vc and it will actually compile and run...
void autoexec()
{
  // Hooks the up key to the function
  HookButton(1, "ButtonDown_Enter");
  while (!b3) { UpdateControls(); }
  exit("And you said you would change...");
}

void ButtonDown_Enter() // If up arrow is pressed
{
  // Display a little message box
  MessageBox("One enter button pressed");
}
Each time the key, set by the standard button numbers, is pressed the function is called. Note this is once and only per button press, it is not called repeatedly if the button is held. It needs to be released then pressed again to trigger another function call. As with all hook functions, it requires the string of a function name that requires no passed values, and any return value is ignored. To remove the hook, call pass "" as the function name. The button numbers to pass are similar to those passed to Unpress, with some limitations:
Numerical ValueButton Hooked
0All buttons (no effect)
1b1
2b2
3b3
4b4
5up (no effect)
6down (no effect)
7left (no effect)
8right (no effect)

HookKey

void HookKey (int key, string function)

Calls the specified function on every discrete press of the specified key

Example usage:

// Put this in system.vc and it will actually compile and run...
void AutoExec()
{
  // Hooks the up key to the function
  HookKey(SCAN_UP, "UpKeyHook");
  // Stay in the program loop until escape is pressed
  while (!b3)
  {
    UpdateControls();
  }
  Exit("Well, if you will take another lover...");
}

// If up arrow is pressed
void UpKeyHook()
{
  // Display a little message box
  MessageBox("One up key has been pressed.");
}
Each time the key, set by a scan code is pressed the function is called. Note this is once and only per key press, it is not called repeatedly if the key is held. It needs to be released then pressed again to trigger another function call. As with all hook functions, it requires the string of a function name that requires no passed values, and any return value is ignored. To remove the hook, call pass "" as the function name. Where you can, use HookButton() instead, as this also supports gamepad input.

HookRetrace

void HookRetrace (string func)

Calls the specified function everytime an R is hit in the renderstring.

Example usage:

// Assume that this function exists somewhere in the system code.
void TintScreen() 
{
    ColorFilter(CF_GREY, screen );
}

// Assume this line is in your map's startup function.
HookRetrace( "TintScreen" );

/*
  Now, when the map with the preceding line is run, what happens depends on 
  its renderstring.

  Since the function is only called when an 'R' is hit in the string, if your string 
  was "1,E,2,R", everything would be grayscale since it was applied after 
  everything else was rendered.

  However, if the renderstring was "1,2,R,E" the map would be grayscale, and the 
  entities on the map would be in color.  (This is how Paladin's Quest did their 
  flashbacks, for an obscure reference.)

  If your rstring was "1,E,R,2", then layer 1 and the entities would be gray, and 
  tile layer 2 would be in it's original colors.  See how it works?

  Finally, if the rstring had no 'R' in it at all, like "1,E,2", then the function specified
  in HookRetrace would never be called!
*/

Calls the specified function everytime an R ("Special: Retrace" layer in MapEd3) is hit in the renderstring (curmap.rstring). For example, if your renderstring is "1,E,2,R", every time the 'R' is rendered, the function you specified in this hook will be called.

HookRetrace's frequency of calling varies from system to system and game to game. If person a is getting 40 frames per second, the hooked function will be called 40 times a second for them. If another person gets 80 frames per second, that person's hooked function will be called 80 times a second. It is this behavior that makes HookRetrace ideal for anything that depends specifically on how many Render() calls get made by the engine. Anyone needing a more consistant timer should look into HookTimer.

Note: A map must be active for HookRetrace() to have an effect.

HookTimer

void HookTimer (string funcname)

Calls the specified function once every timer tick.

Example usage:

// Somewhere you hook this.
HookTimer("MyTimer");

// Increase a variable called mytimer every tick.
void MyTimer()
{
  mytimer++;
}

The specified function will be called every timer tick, 100 times per second.

The function name is passed as a string and the given function must be void and take no arguments. If the string passed does not resolve to a known function at run-time, no hooking will occur.

ListBuiltinDefines

string ListBuiltinDefines ()

Returns a list of all of v3's builtin defines.

Example usage:

string defines = ListBuiltinDefines();

Returns a string list of all of v3's builtin defines. This could be useful for something like syntax highlighting.

ListBuiltinFunctions

string ListBuiltinFunctions ()

Returns a list of all of v3's builtin functions.

Example usage:

string functions = ListBuiltinFunctions();
Returns a string list of all of v3's builtin functions. This could be useful for something like syntax highlighting.

ListBuiltinVariables

string ListBuiltinVariables ()

Returns a list of all of v3's builtin variables.

Example usage:

string variables = ListBuiltinVariables();
Returns a string list of all of v3's builtin variables. This could be useful for something like syntax highlighting.

Log

void Log (string logtext)

Write a line of text to your logfile. Essential for debugging.

Example usage:

Log("Initializing new game...");

Log() simply writes logtext to the verge.log file. This is an exceedingly useful tool for debugging your VC code.

MessageBox

void MessageBox (string text)

Pops up a windows Messagebox.

Example usage:

MessageBox("Notification: Grue likes anuses");

MessageBox("Notification: vecna can't sit down painlessly right now...");

Pops up a windows messagebox, as with Exit, but without exiting the engine. Primarily intended for debugging use, when you want a notification more immediate than with Log().

Note that vc-execution pauses while the system waits for the user to press the 'ok' button on the MessageBox that pops up.

Random

int Random (int min, int max)

Returns a random integer between min and max, inclusive.

Example usage:

int rand = Random(0,10);

Returns a random integer between min and max, inclusive.

You can seed this random number generator by using SetRandSeed()

SetAppName

void SetAppName (string name)

Set the window's application name for your program.

Example usage:

SetAppName("verge3 ultra edition by VECNAR");

Sets the application name shown in the taskbar and the verge3 application window.

SetButtonJB

void SetButtonJB (int button, int jb)

Sets an internal VERGE button to a joystick button.

Example usage:

SetButtonJB(1, 5); // Sets internal VERGE button b1 to read from joystick button 5.

This function will set the default VERGE buttons (b1, b2, b3, b4) to the specified joystick button. Useful for custom button mapping dialogues.

SetButtonKey

void SetButtonKey (int button, int key)

Binds an internal VERGE button to a key

Example usage:

// Sets button 1 (which was enter) to Z on the keyboard
SetButtonKey(1, SCAN_Z);

The values used for the button variable are the same integers that are passed to the unpress() function. The values for the key variable are from the SCAN defines.

SetButtonKey(1, SCAN_Z);
//Would set button 1, which defaulted to [enter] to the 'Z' key on the keyboard

SetButtonKey(2, SCAN_O);
//Would set button 2, which used to be [alt] to the 'O' key on the keyboard.

The internal button values (1-8) are defined here.

SetInt

void SetInt (string intname, int value)

Sets the value of a global non-array integer variable.

Example usage:

int num;
string my_var = "num"; // my_var now points to num.
SetInt(my_var, 176); // Sets the value of num to 176.

Sets the value of a global non-array integer variable.

SetIntArray

void SetIntArray (string intname, int index, int value)

Sets the value of an index in a global one-dimensional integer array.

Example usage:

int num[12];
string my_var = "num"; // my_var now points to num.
int my_index = 7; // my_index is set to 7.
SetIntArray(my_var, my_index, 1337); // Sets the value of num[7] to 1337.

Sets the value of an index in a global one-dimensional integer array.

SetKeyDelay

int SetKeyDelay (int delay)

Sets a delay for repeating key presses with GetKeyBuffer()

Example usage:

SetKeyDelay(20);

Sets a delay for repeating key presses with GetKeyBuffer(). You should only worry about this if you expect the user to type at all.

SetRandSeed

void SetRandSeed (int seed)

Initializes the random number generator

Example usage:

SetRandSeed(109);

This function may be used to initialize the random number generator with the seed of your choice. If you are careful, you may be able to rig your game to behave the same every time if you initialize it with the same random seed every time.

SetResolution

void SetResolution (int xres, int yres)

Sets the screen's resolution.

Example usage:

SetResolution(640, 480);

Sets the screen resolution to the (xres, yres). This will always succeed in windowed mode, but it may fail in fullscreen mode.

Come to think of it, I should probably make it return a value based on whether or not it suceeds. If you see this, remind me! :D

SetString

void SetString (string strname, string value)

Sets the value of an index in a global one-dimensional string array.

Example usage:

string name;
string my_var = "name"; // my_var now points to name.
SetString(my_var, "Bob"); // Sets the value of name to "Bob".

Sets the value of an index in a global one-dimensional string array.

SetStringArray

void SetStringArray (string strname, int index, string value)

Sets the value of an index of a string array

Example usage:

string name[98];
string my_var = "name"; // my_var now points to name.
int my_index = 21; // my_index is set to 21.
SetStringArray(my_var,"Ralph"); // Sets the value of name[21] to "Ralph".

Sets the value of an index inside an string array variable. Does not work on string arrays inside structs currently.

Unpress

void Unpress (int button)

Causes a button to show as released until it is pressed again

Example usage:

if (b1)
{
  Confirm();
  Unpress(1);
}

This important function is used when you have handled a button press event and are ready for the engine to not show it as being pressed any more. After calling Unpress() for that button, the button will be read as being released. It will not read as being pressed until the user presses the button again.

This is most commonly used for buttons that operate as events, rather than states. For example, normally the [left] button will make a character be walking as long as it is pressed down. But if [left] is being used to control a menu cursor, you do not want to move the cursor left for as long as it is pressed (otherwise you will whiz across the menu in a split second). You may want to require each movement in the menu to be a separate press of the [left] button. In this case, you would use Unpress() after you did each movement.

I have made this sound more complicated than it is. Just look at the example.

This table shows the values to be given to unpress for each of verge's logical buttons. If you want to unpress left, you would use Unpress(7).

Numerical ValueButton Unpressed
0b1 through b4
1b1
2b2
3b3
4b4
5up
6down
7left
8right
9b1 through b4 and all directionals (available on versions >= r251 (Oct 11, 2008))

UpdateControls

void UpdateControls ()

Updates all keyboard, joystick, and verge system input variables.

Example usage:

UpdateControls();
// deal with input

Updates all keyboard and joystick input variables, including the key[] array, as well as the "Quick Keys", such as b1, b2..etc.

String Functions

asc

int asc (string char)

Returns the integer value of a character.

Example usage:

log(chr(asc("A")));

asc() returns the int value of the first character of the passed string, and returns 0 for "". It's the reverse of the chr() function. Could be useful for such things as alphabetical sorting, if done correctly.

chr

string chr (int ascii)

Returns a string representation of the ascii code given.

Example usage:

string s;

s = chr( 35 ); // s is now equal to "#"

Returns a string representation of the ascii code given.

The following are some useful instances for this function in verge:

  • chr(34) is the DOUBLEQUOTE (")
  • chr(10) is the NEWLINE (that thing you get when you hit enter)

for a full list of ascii codes, go to asciitable.com

GetToken

string GetToken (string source, string delimiters, int index)

Retrieves a token from a string

Example usage:

GetToken("a-b-c","-",1); //returns token index 1
//        0 1 2

Given a source string and a set of delimiters, returns the token at the given index. The set of delimiters is in the form of a string containing each of the delimiter characters concatenated. For example, if you want to use space, hyphen, and semicolon as delimeter characters, you would use "; -".

GetTokenPos

int GetTokenPos (string source, string delimiters, int tokenpos, int include_token)

Converts a token position into its character position.

Example usage:

string s = "a-b-c-d-e f g-h";
// Should be 5 - the position where token "c" ends + 1.
Log ("Position of third token in string (excluding token): " + str(GetTokenPos(s, "-", 3, 0)));
// Should be 6 - the position where token "c" ends + length of delimiter + 1. 
Log ("Position of third token in string (including token): " + str(GetTokenPos(s, "-", 3, 1)));
// Should be 13 - the position where token "e f g" ends + 1.
Log ("Position of third rightmost token in string (excluding token): " + str(GetTokenPos(s, "-", 5, 0)));

Takes a string, its delimiters, and token position within a string, and returns the character position for that token. This character position can then be used with mid() and other string functions.

left

string left (string s, int ofs)

Crops off beginning of a string

Example usage:

woot="All work and no play make jack a dull boy";
woot=left(woot,10);

woot == "All work a";
Takes the given string and crops 'ofs' number of characters from the leftside of the string going right.

len

int len (string s)

Returns the length of a string.

Example usage:

int i;

i = len( "I LIKE TACOS." ); //i is now equal to 13.

Returns the length of a string.

mid

string mid (string s, int ofs, int len)

Crops out a section of a string

Example usage:

string woot="All work and no play makes jack a dull boy";
woot=mid(woot,10,15);

woot == "nd no play make";

Takes string 'str' and crops out characters from ofs to ofs+len or in other words crops from ofs for len characters.

right

string right (string s, int ofs)

crops off end of a string

Example usage:

string woot="All work and no play makes jack a dull boy.";
woot=right(woot, 10);

woot == " dull boy."
takes string 's' and crops out around ofs characters starting from the right going left.

str

string str (int val)

Changes an int into its string representation.

Example usage:

string s;

s = str( 42 ); 
//s is now equal to the string "42".  

Changes an int into its string representation.

strcmp

int strcmp (string s1, string s2)

Compare two strings, checking for equality.

Example usage:

if( !strcmp("bob","fred") ) 
{
    log( "This should never execute." );
}
else
{
    log( "Bob is not Fred.  Good show!" );
}

Strcmp compares two strings and returns 0 if they're equal. Inequalities, however return 1 if s1 is > s2, or-1 if s1 is < s2. This comparison is case-sensitive.

This may seem backwards for some as it returns a false value if the strings are equal. However, it's put in place this way so that it's forwards compatible with any 'string distance' functionality that may be added in the future.

Always remember to put a ! in front of strcmp in if-statements if you're checking to see if two strings are equal.

strdup

string strdup (string s1, int times)

Duplicates string over a number of times

Example usage:

strdup("blah",1) returns blah. 
strdup("blah",3) returns blahblahblah.
strdup("blah",0) returns an empty string.
Strdup returns a string composed of the string 's1' repeated times 'times'.

strovr

string strovr (string source, string overwrite, int position)

Overwrites the characters in a string at the specified position.

Example usage:

Log ("Result: " + strovr("abcdefghij", "taco", 2)); // Should be "abtacoghij". 

Overwrites the characters in a string at the specified position.

strpos

int strpos (string source, string substring, int position)

Searches for a substring within a string.

Example usage:

// returns zero
strpos("foo", "foobar", 0);

// returns 3
strpos("barf", "foobarfoo", 0);

// returns -1
strpos("moo", "foobar", 0);

// return zero
strpos("moo", "moo", 0);

// returns -1 (ignores 1 character, only includes "oobar")
strpos("foo", "foobar", 1);

// returns 6 (ignores 3 characters, only includes "barfoo")
strpos("foo", "foobarfoo", 3);

// returns zero
strpos("", "foo", 0);

// returns 3 (valid position; string length is 3)
strpos("", "foo", 3);

// returns -1 (invalid position)
strpos("", "foo", 4);

// returns 0 (valid position; string length is zero)
strpos("", "", 0);

// returns -1 (invalid position)
strpos("", "", 1);

Searches for the first occurrence of a substring within a string.

source
The string to be searched.
substring
The string to find.
position
The position where you would like to begin searching.

On success, the position of the substring within the source string is returned. Note that if the source string contains the substring multiple times, only the position of the first match is returned.

If the substring cannot be found, a value of -1 is returned.

Searching an entire string

To search an entire string, start at position zero:

// returns zero
strpos("foo", "foobar", 0);

// returns 3
strpos("barf", "foobarfoo", 0);

// returns -1
strpos("moo", "foobar", 0);

// return zero
strpos("moo", "moo", 0);

Searching part of a string

You can exclude part of the string from your search by increasing the position. It is useful to think of the position as the "number of characters to ignore" at the start of the string you are searching.

// returns -1 (ignores 1 character, only includes "oobar")
strpos("foo", "foobar", 1);

// returns 6 (ignores 3 characters, only includes "barfoo")
strpos("foo", "foobarfoo", 3);

How empty strings affect searching

Note that searching for an empty string will always return a successful result if the position is any number from zero to the length of the string.

// returns zero
strpos("", "foo", 0);

// returns 3 (valid position; string length is 3)
strpos("", "foo", 3);

// returns -1 (invalid position)
strpos("", "foo", 4);

Empty strings are like "fence posts"

To help make sense of this behavior, it is common to imagine that a string is a "fence" and that each character in the string has one "fence post" on each side. If a string is only one character long, it will have 2 fence posts.

For example, imagine the vertical bars here are the fence posts "in between" each character:

|f|

If a string is two characters long, it will have 3 fence posts:

|f|o|

You can imagine that passing an empty string as the substring to find is like passing in a fence post: it means you're searching for a fence post. Note that if an empty string is a fence post, then searching an empty string for an empty string will return success (zero).

Here are some examples:

// returns 0 (valid position; string length is zero)
strpos("", "", 0);

// returns -1 (invalid position)
strpos("", "", 1);

TokenCount

int TokenCount (string source, string delimiters)

Counts the number of tokens in a string

Example usage:

//returns the last name
int count = TokenCount("john jacob jingleheimer smith" ," " ); 
string lastname = GetToken("john jacob jingleheimer smith" ," ", count-1);

Given a string and a set of delimiters (see GetToken()), counts the number of tokens that can be retrieved from it.

TokenLeft

string TokenLeft (string source, string delimiter, int position)

Returns a string of all tokens left of a certain token offset in a string.

Example usage:

string s = "a-b-c-d-e f g-h";
Log ("Leftmost 3 tokens of string: " + TokenLeft(s, "-", 3)); // Should be "a-b-c"

Returns a string of all tokens left of a certain token offset in a string. Useful for limiting the range of things in a string list.

TokenRight

string TokenRight (string source, string delimiter, int position)

Returns a string of all tokens right of a certain token offset in a string.

Example usage:

string s = "a-b-c-d-e f g-h";
Log ("Rightmost 3 tokens of string: " + TokenRight(s, "-", 3)); // Should be "d-e f g-h"

Returns a string of all tokens right of a certain token offset in a string. Useful for limiting the range of things in a string list.

ToLower

string ToLower (string source)

Takes string and formats all the letters into lowercase form

Example usage:

string blah="Hi! my name is BOB!";
blah=toLower(blah);
blah == "hi! my name is bob!"
Takes string and formats all the letters into lowercase form

ToUpper

string ToUpper (string source)

Takes string and formats all the letters into uppercase form

Example usage:

string blah="hi! my NAME is BOB.";
blah=toUpper(blah);
blah == "HI! MY NAME IS BOB.";
Takes string and formats all the letters into uppercase form

val

int val (string s)

Attempts to convert a string into its numeric value.

Example usage:

int i;

i = val( "25" ); // i is now equal to 25.
i = val( "77%" ); // i is now equal to 77.

i = val( "BOB" ); 
// i is now equal to 0, 
// because it failed to change bob into a number.

val attempts to convert a string representation of a number into its integer value.

val is very clever.

Dictionary Functions

Dictionaries are form of data type that function as an array, but with a "key", a string that is used to specify an array index. Dictionaries can be assigned both integer and strings entries, but after an index is set, the type can't be changed by later modifications to the array's entry.

DictContains

int DictContains (int dictionary, string key)

Returns if a specific key exists within a dictionary.

Example usage:

if (DictContains(bob_dict, "name"))
{
  name = DictGetString(bob_dict, name);
}

Returns true/false as to whether or not a specific key exists within a specified dictionary. This is useful to prevent runtime errors caused by trying to DictGetInt() or DictGetString() to a non-existant dictionary key

DictFree

void DictFree (int dictionary)

Frees a dictionary from memory.

Example usage:

DictFree(dict);

Frees an unneeded dictionary from memory.

DictGetInt

int DictGetInt (int dictionary, string key)

Gets an integer entry from a dictionary type.

Example usage:

int hp = DictGetInt(bob_dict, "hp");

Gets a integer entry from a dictionary type. If the specified key does not exist, it will raise an error.

DictGetString

string DictGetString (int dictionary, string key)

Gets a string entry from a dictionary type.

Example usage:

string name = DictGetString(bob_dict, "name");

Gets a string entry from a dictionary type. If the specified key does not exist, it will raise an error.

DictListKeys

string DictListKeys (int dict, string separator)

Returns a lists of all of a dictionary's keys.

Example usage:

int my_dict = DictNew();
DictSetString(my_dict, "foo", "bar");
DictSetString(my_dict, "barf", "fudge");
DictListKeys(my_dict, "+"); // Returns "foo+barf+"

Returns a lists of all of a dictionary's keys, with separator as a string token between each dictionary key. This is extremely useful for keeping track of what data is in a dictionary for key/value iteration and similar.

DictNew

int DictNew ()

Creates a new dictionary handle.

Example usage:

int dict = DictNew();

// Want a dictionary in a dictionary? Here's one way how!
int subdict = DictNew();
DictSetInt(dict, "subdict", subdict);
// Set the subdictionary's "hp" key = 0.
DictSetInt(subdict, "hp", 0);

Creates a new dictionary handle which can then be used by dictionary functions.

DictRemove

void DictRemove (int dictionary, string key)

Deletes a key from a dictionary.

Example usage:

DictRemove(bob_dict, "name");

Deletes a key from a dictionary. If the specified key does not exist, it will raise an error. If the entry you're deleting is a reference to another dictionary, make sure to free that dictionary first to prevent memory leaks.

DictSetInt

void DictSetInt (int dictionary, string key, int value)

Sets the value of an entry within a dictionary, creating a new key as necessary.

Example usage:

DictSetInt(bob_dict, "hp", 10);

Sets the value of an entry within a dictionary, creating a new dictionary key as necessary. If the key exists, it will replace the value at that key.

DictSetString

void DictSetString (int dictionary, string key, string value)

Sets the value of an entry within a dictionary, creating a new key as necessary.

Example usage:

DictSetString(bob_dict, "name", "Bob");

Sets the value of an entry within a dictionary, creating a new dictionary key as necessary. If the key exists, it will replace the value at that key.

DictSize

int DictSize (int dictionary)

Gets the size of the dictionary.

Example usage:

// Log our "dynamic array" of names.
// DictSize() determines the upper count of the array.
// Assumes no missing number keys in between 0 and DictSize() - 1.
for (i = 0; i < DictSize(dict); i++)
{
  string name = DictGetString(dict, str(i));
  Log(name);
}

Gets the size of the dictionary. Possibly useful for dictionaries that use number strings as keys!

Map Functions

CompileMap

void CompileMap (string filename)

Forces the map VC to compile for a map.

Example usage:

CompileMap("mymap.map"); // Tries to compile mymap.vc and shove the code into mymap.map

Forces the map VC to compile for a map. You give it the filename of the map, and then it looks for the .vc file of the same name (sans .map) to compile into the map.

GetObs

int GetObs (int x, int y)

Checks for obstructions at tile coords.

Example usage:

// Imagine the following 3 by 3 grid is your map.

//    0 1 2
//
// 0  0 0 0
// 1  0 1 1
// 2  0 0 1

GetObs(0, 0); // Returns 0.
GetObs(1, 1); // Returns 1.
GetObs(2, 2); // Returns 1.
GetObs(2, 0); // Returns 0.

Returns the index of the obstruction tile at the given coords.

Note: Coordinates are in terms of tiles, not pixels. In order to convert tiles to pixels do, (pixel coordinate / 16).

GetObsPixel

int GetObsPixel (int x, int y)

Check for obstruction pixels on the map.

Example usage:

// If the top-left corner of the player touches any obstruction, die.
if (GetObsPixel(entity.x[player], entity.y[player]))
{
  Exit("You died.");
}

Verifies that an obstruction pixel is at the given coordinates. If there is an obstruction it returns true (i.e. not zero). Otherwise, it returns false (i.e. 0). This is useful for collision detection in large in advanced game systems.

Note: Coordinates are in terms of absolute pixels on the map, not screen-relative pixels.

GetTile

int GetTile (int x, int y, int layer)

Find specific VSP index of tile

Example usage:

none
Returns the vsp index of the tile at coords x,y on the given layer. Note: xy is in terms of tiles.

GetZone

int GetZone (int x, int y)

Find index of zone at tile coords

Example usage:

// Imagine the following 7 by 7 grid is your map,
// Where the top and left are the X and Y coords.

//    0 1 2 3 4 5 6
// 
// 0  0 1 0 0 0 0 0
// 1  0 2 0 0 0 0 0
// 2  0 0 0 0 0 0 0
// 3  0 0 9 0 0 4 0
// 4  0 0 0 0 0 0 0
// 5  0 2 1 0 0 0 0
// 6  0 0 0 0 0 0 0


GetZone(0, 0); // Returns 0.
GetZone(1, 0); // Returns 1.
GetZone(1, 1); // Returns 2.
GetZone(3, 5); // Returns 4.
GetZone(4, 5); // Returns 0.
GetZone(3, 2); // Returns 9.
GetZone(5, 2); // Returns 1.
GetZone(6, 6); // Returns 0.

Returns the numerical index of a map zone at the given coords, and not the zone's textual name.

Note: Coordinates are in terms of tiles, not pixels. In order to convert tiles to pixels do, (pixel coordinate / 16).

Map

void Map (string mapname)

Loads the specified map.

Example usage:

//Example 1
/////////////////////////////////////////////

// this loads the map named "test.map" 
// located in the base verge directory.

map( "test.map" ); 



//Example 2
/////////////////////////////////////////////

// This demonstrate's map()'s ability to 
// stop all  functionality under it.

void grue_is_awesome() {
  map( "test.map" );
  exit( "GRUE SUXS!!!!" );
}

void autoexec() {
  grue_is_awesome();  
}

// When this program is executed, 
// as long as ./test.map exists, you will 
// load that map fine, and the program will 
// never exit with the "GRUE SUXS!!!!" 
// message.  This is because map() halts the
// function it was called in, and starts off anew in
// the map-vc.

This function loads a map. If you are using maps in your game, which is not strictly neccesary, this function is essential.

VERGE 3 format .MAP files are currently only created by MapEd 3.

Upon execution of this function, all code execution halts completely, never to be returned, and starts anew in the map's own vc's starting function. For a more in-depth discussion of the correlation between system-vc and map-vc, please view [this section].

Render

void Render ()

Blits the map and entities to "screen"

Example usage:

Render();
Showpage();

Blits the map and entities to the variable screen.

Note: This also will run what ever function you have HookRetrace()'d. Which makes this a very bad function to ever call in a HookRetraced function (since it would cause an infinite loop and crash the game.)

RenderMap

void RenderMap (int x, int y, int destimage)

Renders the map to the target image

Example usage:

//Make only Entities be rendered, and then...
curmap.rstring = "E";
//...take a snapshot of the map...
RenderMap(xwin, ywin, img);
//...and copy it to the clipboard.
CopyImageToClipboard(img);

This function allows you to render the map and its entities to an image other than the screen. The x and y are the screen offset in pixels, often making xwin and ywin desirable arguments. If used in conjunction with curmap.rstring, you could do some interesting things.

SetObs

void SetObs (int x, int y, int obs)

Place an obstruction on the map

Example usage:

// Set the obstruction tile at (5, 2) to obstruction tile 1.

// Obstruction tile one, is commonly a fully filled 16 x 16 tile, thus preventing
// any entry onto that coordinate.

SetObs(5, 2, 1);

Changes the obstruction tile index at the given coords to the given obstruction type.

Note: Coordinates are in terms of tiles, not pixels. In order to convert tiles to pixels do: (pixel coordinate / 16).

SetTile

void SetTile (int x, int y, int layer, int tile)

Place a tile on the map

Example usage:

SetTile(0, 0, 1, 45); // Changes the tile at (0, 0) on layer 2 to tile 45.

Changes the tile index at the given coords on the given layer to the given tile.

Note: Coordinates are in terms of tiles, not pixels. In order to convert tiles to pixels do: (pixel coordinate / 16).

SetZone

void SetZone (int x, int y, int z)

Place a zone on the map

Example usage:

SetZone( 5,13, 53 ); //the zone at tile (5,13) is now 53.

Changes the zone at tile-coordinates (x,y) to value z.

Note: zone z must exist on the map, or else SetZone will just set the zone at tile-coordinates (x,y) to 0. This is so v3 doesn't crash, which is, overall, a good thing.

Entity Functions

For the corresponding Entity variables go here

ChangeCHR

void ChangeCHR (int ent, string chrfile)

Replaces an entity's imagefile on the map with a different one

Example usage:

// Create our player.
int player = EntitySpawn(10, 10, "me.chr");

// Are we disguised?
if (disguise)
{
  // ...We're disguised!
  // Look like someone else!
  ChangeCHR (player, "him.chr");
}

Replaces entity ent's character sprite on the map with the file named chrfile. In addition to the character's appearance, this will also affect the hotspots and the animation associated with it.

EntityMove

void EntityMove (int entity, string script)

Sets the movecode of an entity - so moving them around on the map

Example usage:

// Examples adapted from Parallel Seven

// Moves the first party member to the x position 77, 
// then to the y position 42, then faces upwards
EntityMove(party[0].ent, "x77y42u0");

// Animate drunk picking up broken bottle
EntityMove(2, "z24w80z25w100");
// Waits till the entity is done with the movecode before continuing
WaitForEntity(2);

void IdleAnimPlayer(int pparty)
// Sets a party member into the idle animation
{
  EntityMove(party[pparty].ent, "z4w100z2w100b");
}
// Note: The 'b' at the end repeats this movecode

// Sets the party member to animated movement frame
EnityMove(party[pparty].ent, �z0�)

With this function you can set actions for the entity (specified by int reference) to follow using a 'movecode' string. In verge a movecode is a string of instructions for an entity to follow, one after the other, like a 'script'. Each command is a letter, sometimes followed by a number, here are a list of what each does:

ulrd (followed by number) Move the entity either up, down, left or right by set number of tiles.

xy (followed by number) Move an entity so a set x or y tile position

pt Changes movement to either pixel accurate, p, or tile accurate, t. Now works.

z (followed by number) Set the current frame of the entity, like setting entity.specframe

w (followed by number) The entity pauses for set number of timer ticks (default 100 = 1 second)

f (followed by number) Sets the entity's facing: use directional 0 moves instead, then you don't need to remember which number is which direction

b Loops the entire movecode, eternally

They can be either upper or lower case (which ever you think looks nicer) and don't need a space or anything between commands. Verge processes entity movecodes every call to ShowPage() so, if you need the game to 'pause' for a textbox or something, make sure you use SetEntitiesPaused() so the entities don't suddenly 'jump' to their next positions.

There are a few things to remember when moving entities around, firstly the entity needs to have their specframe set to 0 to enable the walk animation, rather than just sliding around. So if you change the frame, remember to set it back with �z0� before moving. Also, any movement is ignorant of obstructions and other entities, so make sure to test what you use to make sure it works as expected.

Note, unlike PlayerMove(), verge does not wait for this to finish before running the next line of code. So you can set several entities moving all at the same time. However, it is likely you will sometimes want to wait untill a particular entity has finished moving, so I recommend having a WaitForEntity() function.

EntitySetWanderDelay

void EntitySetWanderDelay (int entity, int delay)

Change the wander delay time.

Example usage:

//This sets entity 3 on the map to take a wander-step twice
//   a second (which is kinda fast)
EntitySetWanderDelay( 3, 50 );

//This sets entity 42 on the map to take a wander-step once
//   every 6 seconds (which is kinda slow)
EntitySetWanderDelay( 42, 600 );

This function changes the specified entity's wander delay to a new value.

The wander delay is how long the entity will wait before wandering around again.

The value specified is in 1/100ths of a second.

This function is a part of a small family of Wander-mode effecting Entity functions, which includes: EntitySetWanderDelay, EntitySetWanderRect, EntitySetWanderZone, and EntityStop.

EntitySetWanderRect

void EntitySetWanderRect (int entity, int x1, int y1, int x2, int y2)

Sets an entity's wandermode to Rect.

Example usage:

// This sets map entity index 1 to wander within an area between 
//  tile (0,0) and tile (10,10)

EntitySetWanderRect( 1,  0,0, 10,10 );

This function changes the specified entity's wander mode to Rect.

The entity will wander within the bounds of the map coordinates specified. x1,y1 represents the tile coordinates of the top-left corner of the wander rectangle area, and x2,y2 represents the bottom-right corner.

If the entity is outside the rectangle but adjacent to it he could move inside it. However, if the entity is completely not anywhere near the rectangle, it will not be able to wander.

If anyone would like to report what happens if you use x1,y2 for any other corner and x2,y2 for the opposite, please inform us. I'm too tired to check. -Grue

This function is a part of a small family of Wander-mode effecting Entity functions, which includes: EntitySetWanderDelay, EntitySetWanderRect, EntitySetWanderZone, and EntityStop.

EntitySetWanderZone

void EntitySetWanderZone (int entity)

Sets an entity to wander about in Zone 0.

Example usage:

//let's pretend we're talking to Sor, Norse god of muscle fatigue!

void Talk_Sor() 
{
  //stop the entity so we can talk to him...
  EntityStop( event.entity );

  // Do the talking!
  //
  // TextBox( SOR_PRT, "Yeah yeah, well, I'm twice as Thor as he'll ever be.  Can I get a massage here now?" );

  //now that we're done talking, set the entity to wander-zone mode so he can wander around again.
  EntitySetWanderZone( event.entity ); 
}

This function changes the specified entity's wander mode to Zone.

This function tells an entity to wander around within the confines of the zone it is currently standing in. Other zones will act like obstructions to it.

For the curious, no zone data is stored concerning this functionality; The entity just compares it's current zone to the zones of where it can move when it's thinking about moving.

This function is a part of a small family of Wander-mode effecting Entity functions, which includes: EntitySetWanderDelay, EntitySetWanderRect, EntitySetWanderZone, and EntityStop.

EntitySpawn

int EntitySpawn (int x, int y, string chr)

spawn an entity onto the map

Example usage:

int currentplayer = EntitySpawn(10, 10, "Hero.chr");
SetPlayer(currentplayer);
entity.speed[currentplayer]=100;

Spawn entity at tile x,y on currently loaded map using .chr file. EntitySpawn will return the index of the entity for interface with entity variables.

EntityStalk

void EntityStalk (int stalker, int stalkee)

Makes one entity follow another

Example usage:

// Make companion follow the player.
EntityStalk(companion, player_ent);

// Make the entity Bob follow the entity Jim.
EntityStalk(bob, jim);

// Stop following.
EntityStalk(companion, -1);
EntityStalk(bob, -1);
EntityStalk makes an entity follow behind another, where stalker is the entity who's following and stalkee is the entity being followed. Useful for when you want party members following the leader.

EntityStop

void EntityStop (int entity)

Clears an entities movecode

Example usage:

EntityMove(1, "u3"); // Move entity '1' up 3 tiles
Wait(100); // A function that waits for 1 second
EntityStop(1); // Stop entity 1 early

Clears the movecode of an entity, set by EntityMove() - stopping whatever action the entity is currently taking.

GetPlayer

int GetPlayer ()

Returns the map's entity index for the current player.

Example usage:

int anEntityIndex = EntitySpawn(0, 0, "nathan.chr");
SetPlayer( anEntityIndex );  //this sets the "player" on this map.

if( anEntityIndex == GetPlayer() )
{
    Log( "This will always execute.  Do you know why?  I hope you do!" );
}


GetPlayer returns the entity index that currently is controlled by the directional keys amd which is being followed by the camera (during normal camera operation).

HookEntityRender

void HookEntityRender (int entity, string func)

Every time the specified entity would be rendered, calls the specified function instead

Example usage:

int e;
// Hook all current map entities to PaperDollRender()
for(e = 0; e < entities; e++)
{
  HookEntityRender(e, "PaperDollRender");
}

void PaperDollRender()
// Give everyone cloaks and moustaches
{
  // Work out the x,y coord of the current entity's hotspot on the screen
  int pdr_xh = entity.x[event.entity] - xwin;
  int pdr_yh = entity.y[event.entity] - ywin;
  // Work out the x,y coord of the top left corner of an entity's tile
  int pdr_xb = pdr_xh - entity.hotx[event.entity];
  int pdr_yb = pdr_yh - entity.hoty[event.entity];
  // Blit the cloak tile UNDER the entity 
  TBlit(pdr_xb, pdr_yb, cloak, screen);
  // Blit the entity's current frame
  BlitEntityFrame(pdr_xh, pdr_yh, event.entity, entity.frame[event.entity], screen);
  // Blit the moustache tile OVER the entity
  TBlit(pdr_xb, pdr_yb, moustache, screen);
}

// Note: In practice, you'd probably want to want to use TGrabRegion() based on the 
// entity.frame[event.entity] value to get a tile that matches with the current frame
// of the entity, but this example is already complicated enough :D
This 'hooks' a function to be called each time a set entity is rendered, instead of blitting the entity automatically. This would generally be during a Render() call when the entity is in the viewable area. As with all hook functions, it requires the string of a function name that requires no passed values, and any return value is ignored. If no function matching the name is found, the hook does nothing. The entity value needed is the int value of their index. This is either set on the map, or returned by EntitySpawn(). Also when within the hooked function, event.entity refers to the currently rendered entity. Remember to manually blit the current entity frame if you want to display the entity as normal - this hook OVERRIDES the normal entity render, rather than coming before or after. Be careful about blitting to to correct x,y coords on the screen.

PlayerMove

void PlayerMove (string script)

Sets a movecode for the player - taking control from the user

Example usage:

// Examples adapted from Parallel Seven

// Player waits briefly then changes to 'glance right' frame
PlayerMove("w40z21");

// Player looks around
PlayerMove("d0w40r0w40");
// Parallel Seven specific textbox
TBox(party[0].port, 1, 1, party[0].name, "Where the hell is there a weapon when you need one?");
// Player moves to x,y position then looks right and pauses
PlayerMove("y61x77r0w40");

With this function you ignore what ever input the user gives, and set actions for the player to follow using a 'movecode' string. In verge a movecode is a string of instructions for an entity to follow, one after the other, like a 'script'. Each command is a letter, sometimes followed by a number, here are a list of what each does:

ulrd (followed by number) Move the player either up, down, left or right by set number of tiles.
xy (followed by number) Move an player so a set x or y tile position
pt Changes movement to either pixel accurate, p, or tile accurate, t. Now works.
z (followed by number) Set the current frame of the player, like setting entity.specframe
w (followed by number) The player pauses for set number of timer ticks (default 100 = 1 second)
f (followed by number) Sets the entity's facing: use directional 0 moves instead, then you don't need to remember which number is which direction
b Loops the player movecode, eternally � DO NOT DO THIS

They can be either upper or lower case (which ever you think looks nicer) and don't need a space or anything between commands.

There are a few things to remember when moving the player around, firstly the player needs to have their specframe set to 0 to enable the walk animation, rather than just sliding around. So if you change the frame, remember to set it back with �z0� before moving. Also, as the program would go into an eternal loop if the player got 'stuck' any movement will go straight through of obstructions and other entities, so make sure to test what you use to make sure it works as expected.

Note: When using PlayerMove(), it ignores normal code execution and does Render() and ShowPage() for as long player is moving. If this is not what you want (for instance if you'd prefer a textbox to execute as the player is walking or something more dramatic) you might want to use EntityMove() on your player index instead.

SetEntitiesPaused

void SetEntitiesPaused (int pausestate)

Halts all entity movement

Example usage:

SetEntitiesPaused(1);
TextBox("Nobody's moving behind ME, that's for sure");
SetEntitiesPaused(0);

This function stops entity movement codes from being processed until they are unpaused.

pausestate is either 1 (on) or 0 (off).

You would use this in situations where the screen stops updating. For instance, a textbox that halts the game until the player closes.

Not using this function would result in the entities moving around while the screen isn't being updated. Once the textbox closes the things are being drawn again, the enties will all appear to warp to their new locations.

SetPlayer

void SetPlayer (int entity)

Set up controls and camera for entity

Example usage:

int currentPlayer = EntitySpawn(0, 0, "nathan.chr");
SetPlayer(currentPlayer);

SetPlayer links the direction keys, enter, and the camera to the entity index specified. It also makes the specificied entity obstructable.

Graphics Functions

AdditiveBlit

void AdditiveBlit (int x, int y, int sourceimage, int destimage)

Additive Blits an image onto another image.

Example usage:

int image;
image = LoadImage("mypic.pcx");

AdditiveBlit(0, 0, image, screen);

Special version of Blit, this function Additively blits the sourceimage over the destimage, creating some nice effects.

AlphaBlit

void AlphaBlit (int x, int y, int source_image, int alpha_image, int dest_image)

Blit an image with an alpha mask

Example usage:

int portrait = LoadImage("Hero.png");
int portrait_mask = LoadImage("Hero_mask.png");

AlphaBlit(0, 0, portrait, portrait_mask, screen);

Before I go into this function let me explain what a mask is.

A mask is a grayscale (essentially, black and white) image that is applied to another image to tell the computer how much transparency is allowed in different places. By using a mask you can blit anti-aliased images and other things for a higher image quality. If used properly you can eliminate the hard edges you might often get with TBlit.

AlphaBlit blits image source_image to image dest_image at cooridinates (x, y), with the alphamask alpha_image.

Note: source_image and alpha_image must have be the exact same dimensions in pixels.

Blit

void Blit (int x, int y, int source_image, int dest_image)

Draws an image onto another image, ignoring transparancy.

Example usage:

int image;
image = LoadImage("mypic.pcx");

Blit(100, 100, image, screen);
This function blits the image source_image on to dest_image at the coordinates x and y. Screen is the builtin image object representing the physical screen.

BlitEntityFrame

void BlitEntityFrame (int x, int y, int ent, int frame, int dest)

Blits a specified entity frame to the screen

Example usage:

void PaperDollRender()  //add to a HookEntityRender
{
   //Blit current frame of the entity being referenced
   BlitEntityFrame(x, y, event.entity, frame_index, screen);
   //Blit Paper Doll Stuff
}

Blits the frame number frame of entity ent to the dest image at coords (x, y). It will not draw transparent pixels, and abides SetLucent values.

If you add this to a HookEntityRender(), you can get the current entity being referenced using event.entity.

BlitLucent

void BlitLucent (int x, int y, int lucent, int source, int dest)

Simple blit with constant translucency override

Example usage:

BlitLucent(-5,-5,20,oldScreen,screen); //motion blur effect
BlitLucent is a standard blit, with the exception that it will use the provided alpha value for constant translucency. This is exactly equivalent to the following snippet of code:

SetLucent(newLucent);
Blit(x,y,source,dest);
SetLucent(oldLucent);

BlitTile

void BlitTile (int x, int y, int tile, int dest)

Blit a tile from the vsp to the screen.

Example usage:

BlitTile(50, 50, 1, screen); // Blits tile 1 to screen at coordinates (50, 50).

Blits tile index tile to image dest at coordinates (x, y) relative to the destination image.

Note: BlitTile is different from SetTile in that SetTile positions a tile into the map it self on a tile grid while BlitTile blits the tile to an image on a pixel grid.

BlitWrap

void BlitWrap (int x, int y, int sourceimage, int destimage)

Draws an image such that it will wrap around the boundaries of the destination.

Example usage:

BlitWrap(270, 150, myimage, screen);

This is a specialty use blitter. This will blit an image to the destination image, but instead of clipping, it will wrap around the edges. In other words, if you blit a 50 x 50 image at 25 pixels from the bottom-right corner, then 25 pixels will also appear at the top-left corner.

There is no such thing as TBlitWrap. BlitWrap will not draw transparent pixels. BlitWrap at this time abides neither the clipping region (it wraps at the image height and width) or values of SetLucent.

Circle

void Circle (int x, int y, int xrad, int yrad, int color, int dest)

Draws an unfilled circle.

Example usage:

Circle (40, 40, 20, 20, RGB(255, 0, 0), screen);

Generates an ellipse (or unfilled circle) centered around coordinates (x, y) with a horizontal radius of xrad and vertical radius yrad of the given color to image dest.

CircleFill

void CircleFill (int x, int y, int rx, int ry, int color, int destimage)

Draws a filled circle.

Example usage:

CircleFill (70, 70, 30, 35, RGB(0, 0, 255), screen);

Generates an filled ellipse centered around coordinates (x, y) with a horizontal radius of xrad and vertical radius yrad of the given color to image dest.

ColorFilter

void ColorFilter (COLOR_FILTER filter, int image)

Applies the specified color filter to an image to tint it.

Example usage:

ColorFilter(CF_GREY, screen);

Applies the specified filter to the given image. The following filters are valid:

  • CF_NONE does absolutely nothing!
  • CF_GREY converts the image to greyscale.
  • CF_GREYINV converts the image to inverted greyscale..
  • CF_INV converts an image to a negative, inverted version. For instance, the inverse of green (RGB (0, 255, 0)) would be purple (RGB (255, 0, 255)).
  • CF_RED gets an average luminosity and then applies that to the red channel only.
  • CF_GREEN gets an average luminosity and then applies that to the green channel only.
  • CF_BLUE gets an average luminosity and then applies that to the blue channel only.

Note: All of these filters have builtin integer constants. See their section for more detail.

Two notes about this function. It will abide by the clipping region, but you will not gain the full speed benefit of a clip region. This may be optimized in the future. It will abide by SetLucent values: you can acheive some cool effects this way. For instance a lucent percentage of a CF_GREY filter will provide a washed-out, color-faded look.

ColorReplace

void ColorReplace (int color_find, int color_replace, int dest)

Replaces a color in an image with another.

Example usage:

slime_image = LoadImage("redslime.png");
// Replaces pure red with pure blue. Hooray! A blue slime!
ColorReplace(RGB(255, 0, 0), RGB(0, 0, 255), slime_image);
Finds a specific color in an image and replaces it with another. Could be useful for recoloring monster images. Note that this finds better use with images with small palettes. If you have images with many colors, you might want to use HueReplace() instead.

CopyImageToClipboard

void CopyImageToClipboard (int image)

Copy an image pointer from Verge into the clipboard.

Example usage:

// If CTRL+C is pressed, then copy the image into the clipboard!
if (key[SCAN_CTRL] && key[SCAN_C])
{
  CopyImageToClipboard(my_image);
}

Copies an image pointer from Verge into the Windows clipboard.

DuplicateImage

int DuplicateImage (int image)

Makes an exact, but seperate, copy of an image.

Example usage:

int image_a, image_b;

image_a = LoadImage("image.pcx"); // load an image
image_b = DuplicateImage(image_a); // put the image inside image_b as well.
// now both image_a and image_b have the image from image.pcx

RectFill( 0, 0, ImageWidth(image_b)/2, ImageHeight(image_b)/2, 0, image_b);
//now image_b has a black rectangle in it's upper-left quadrant, whereas image_a does not.

Duplicates the passed image object and returns a new handle for storage in a different location.

FlipBlit

void FlipBlit (int x, int y, int fx, int fy, int src, int dest)

Blits a horizontally or vertically mirrored image onto a destination image.

Example usage:

// Blits a mirrored version of my_image onto coordinates (12, 34) of the screen
FlipBlit( 12,34, 1,0, my_image, screen);

Blits a horizontally or vertically mirrored image onto a destination image, where x is the X co-ordinate, y is the Y co-ordinate, fx is a boolean (0 or 1) used to determine whether you want to flip the X axis, fy is a boolean used to determine whether you want to flip the Y axis, src is the source image to blit from and dest is the destination image to blit to.

FreeImage

void FreeImage (int image)

Frees the memory occupied by the image reference passed.

Example usage:

int myimage;
myimage = NewImage(320, 240); // This loads the image into memory.

//
// Let's pretend we actually used the image hereabouts...
//

FreeImage(myimage); // This frees the image from memory. 

// myimage cannot be used after this point, without creating or loading a new image into it.

Frees the memory occupied by image, and sets the image pointer to 0.

GetB

int GetB (int color)

Returns the value of the blue channel of a color.

Example usage:

int color, blue;
color = RGB(200, 100, 50);
blue = GetB(color); // blue will equal 50

Grabs the blue channel from color, and returns its value.

Colors are special integers created by the RGB() function.

GetG

int GetG (int color)

Returns the value of the green channel of a color.

Example usage:

int color, green;
color = RGB(200,100,50);

green = GetG(color);  // green will equal 100

Grabs the green channel from color, and returns its value.

Colors are special integers created by the RGB() function.

GetH

int GetH (int color)

Returns the hue of a color

Example usage:

GetH(RGB(255, 0, 0)); // Should be 0, or close to it.
Returns the hue of a color, which is in the range of 0 to 359. A starting hue of 0 starts at red and works its way around the color wheel as the hue increases.

GetImageFromClipboard

int GetImageFromClipboard ()

Retrieve an image pointer from the clipboard.

Example usage:

// If CTRL+V is pressed, paste a copied image.
if(key[SCAN_CTRL] && key[SCAN_V])
{
  my_image = GetImageFromClipboard();
}

Returns an image pointer from the clipboard.

GetPixel

int GetPixel (int x, int y, int sourceimage)

Returns the color from a specific pixel in the specified image.

Example usage:

int color;

color = GetPixel(10, 10, screen); // Get what color is located at coordinates (10, 10) on the screen object.

Grabs the pixel at (x, y) from sourceimage, and returns its color value.

This color value is the same type created by the function RGB and used by functions GetR, GetG, and GetB.

GetR

int GetR (int color)

Returns the value of the red channel of a color.

Example usage:

int red, color;

color = RGB(125, 50, 250);

red = GetR(color); // red will equal 125

Grabs the red channel from color, and returns its value.

Colors are special integers created by the RGB() function.

GetS

int GetS (int color)

Returns the saturation of a color.

Example usage:

GetS(RGB(50, 50, 50)); // Should be 0, or close to it.
Returns the saturation of a color, which is in the range of 0 to 255. The higher the number, the more saturated (less grey), the color is. 255 is a "pure" color, whereas 0 is grey.

GetV

int GetV (int color)

Returns the value/brightness of a color

Example usage:

GetV(RGB(255, 0, 0)); // Should be 255, or close to it.
Returns the hue of a color, which is in the range of 0 to 255. 0 is black, and 255 is pure color (not necessary white - white will have 255 value, and 255 saturation).

GrabRegion

void GrabRegion (int sx1, int sy1, int sx2, int sy2, int dx, int dy, int sourceimage, int destimage)

Extracts a sub-rectangle from a given image

Example usage:

int edgar = loadimage("edgar.pcx");
int leftFrame = NewImage(16,24);

//the order of things is down/up/left/right in the world of verge
//that means we need the third frame
GrabRegion(16*2,0,16*2 +15,23,0,0,edgar,leftFrame);
GrabRegion receives the rectangle that it should extract from the source image in (sx1,sy1)->(sx2,sy2). This rectangle is placed into the destination image at (dx,dy). This function is very useful for manually slicing up an image that contains a strip of frames for an animation and extracting a single frame from it. The example will demonstrate this

HSV

int HSV (int hue, int saturation, int value)

Creates a color using the HSV color model.

Example usage:

// An animating rainbow screen!
RectFill(0, 0, ImageWidth(screen), ImageHeight(screen), HSV(systemtime, 255, 255), screen);
Creates a color using the HSV color model. Useful for easy rainbow color shifts, greyscaling and brightness adjustments.

HueReplace

int HueReplace (int hue_find, int hue_tolerance, int hue_replace, int dest)

Finds a range a range of hues within an image and replaces them with another.

Example usage:

cat_image = LoadImage("cat.png");
// Replaces red/orange with yellow/green
HueReplace(0, 40, 120, cat_image);
Finds a range a range of hues within an image and replaces them with another. Useful for color swapping in images with lots of colors.

ImageHeight

int ImageHeight (int image)

Returns the height of an image object.

Example usage:

int image, height;
image = LoadImage("image.pcx");

height = ImageHeight(image);

Returns the height of an image object.

ImageShell

int ImageShell (int xofs, int yofs, int width, int height, int image)

Creates a duplicate image handle referencing a rectangle in the original image

Example usage:

int window = ImageShell(110,60,100,100,screen);
// rendering into window will now be the same as rendering into a 100x100
// window in the middle of the screen!

This extremely powerful function will allow you to take an image, define a rectangle within it, and get an image handle referencing that rectangle within the original image. xofs, yofs, width, height indicate the position and dimensions of the rectangle within the source image. Clipping rectangles for the two images are completely independent.

*Rendering into one will render into the other.* If that is what you want to do, then this is the function you want to use.

ImageValid

int ImageValid (int image)

Returns whether specific image pointer is valid or not.

Example usage:

if (!ImageValid(image))
{
  Exit("Error! Image "+str(image)+" is not valid.");
}

Returns whether specific image pointer is safe for use or not.

ImageWidth

int ImageWidth (int image)

Returns the width of an image object.

Example usage:

int image, width;
image = LoadImage("image.pcx");

width = ImageWidth(image);

Returns the width of an image object.

Line

void Line (int x1, int y1, int x2, int y2, int color, int destimage)

Draws a colored line onto an image.

Example usage:

Line(0, 0, 100, 100, RGB(255,255,255), screen);  // draws a line from 0,0 to 100,100 on the screen object

Primitive drawing function, Line, draws a line from x1,y1 to x2,y2 on 'destimage' in color 'color'.

LoadImage

int LoadImage (string filename)

Reads an image file into memory, and returns an IMAGE handle.

Example usage:

int myimage;
myimage = LoadImage("image.pcx");

Reads in the specified image file as an image object, and returns a handle to the image object. This handle is an int that represents the image to any functions in the Graphics API that want an image.

LoadImage0

int LoadImage0 (string filename)

Loads a paletted image and makes palette index 0 transparent.

Example usage:

int myimage;
myimage = LoadImage0("image.gif");

Typically images are loaded in and magenta is used as the transparent color. LoadImage0 takes account for indexed color images, and treats color index 0 in the palette as the transparent color. Transparent pixels are only transparent if you use the transparency blitting functions.

LoadImage8

int LoadImage8 (string filename)

Loads a paletted image and makes the transparent index compatible Verge's transparency.

Example usage:

int myimage;
myimage = LoadImage8("image.gif");

Typically images are loaded in and magenta is used as the transparent color. LoadImage8 takes account for indexed color images, and treats any transparent index in the palette as death magenta. Transparent pixels are only transparent if you use the transparency blitting functions. Different from LoadImage0, which just blindly uses palette index 0 for transparency.

MakeColor

int MakeColor (int r, int g, int b)

Returns a color in a format usable by other image functions.

Example usage:

int color = RGB(255, 0, 0);
int color2 = MakeColor(255, 0, 0);

if (color == color2)
{
  // This should execute.
  Log("MakeColor() is a valid alias for RGB(). OMG SEKRIT FOUND.");
}
else
{
  // This however, should never execute.
  Log("MakeColor() has the same argument count as RGB(), but it's not the same thing, what?");
}

An alias for the function RGB(int r, int g, int b). Undocumented function that was discovered by accident.

MixColor

int MixColor (int c1, int c2, int mix)

Mixes two colors in the given proportion

Example usage:

//mixing white and red 50/50 will yield a fabulous shade of pink
pink = MixColor(RGB(255,0,0),RGB(255,255,255),128); 
Mixes c1 and c2 according to the proportion specified by mix. A mix of zero would yield a color identical to c1. A mix of 255 would yield a color identical to c2. A mix of 128 would yield a color smack dab inbetween c1 and c2.
     c1      c2
     |--------|
mix: 0      255

Mosaic

void Mosaic (int xgran, int ygran, int destimage)

Applies a mosaic effect to an image.

Example usage:

Mosaic(4, 4, screen);

This will apply a mosaic effect, with a granularity size specified with xgran/ygran, to the destination image. It abides clipping rectangle, but the mosaic effect is absolute and ignores the value of SetLucent().

While this creates the same effect you remember from your super NES, it does it in a slightly different way. The effect is better than the super NES's; it is also slower. Super NES and GBA, I believe, select the pixel in the top-left corner of each tile of the mosaic to use as the color for that entire tile of the mosaic. Verge's mosaic function will actually average every one of the pixels in the tile and use that as the color for the entire tile.

NewImage

int NewImage (int width, int height)

Creates a new image. Useful for drawing to.

Example usage:

int myimage;
myimage = NewImage(320, 240);

NewImage() creates an image object of the size specified by parameters width and height. The returned value is a handle to that image object which can be passed to any graphics function. The clipping region for the image defaults to the entire size of the image. The new image is not set to any colour, so don't forget to initalize it with a rectFill or something similar.

Rect

void Rect (int x1, int y1, int x2, int y2, int color, int destimage)

Draws a 1-pixel thick rectangle onto an image.

Example usage:

Rect(0, 0, 200, 200, RGB(255,255,255), screen); // draw a box from 0,0, to 200,200, on the screen object (in white)

Draws an unfilled rectangle from x1,y1 to x2,y2 on 'destimage', in color 'color'.

RectFill

void RectFill (int x1, int y1, int x2, int y2, int color, int destimage)

Draws a solid colored rectangle onto an image.

Example usage:

RectFill(0, 0, ImageWidth(screen)-1, ImageHeight(screen)-1, RGB(255,255,255), screen);  
// fill the screen with a full white rectangle

Draws a filled rectangle from x1,y1 to x2,y2 on 'destimage', in color 'color'

RectHGrad

void RectHGrad (int x, int y, int x2, int y2, int c1, int c2, int dest)

Draws a rectangle filled with a horizontal gradient.

Example usage:

// A dark green to green gradient! Could be cool for health bar.
RectHGrad(0, 0, 100, 5, RGB(0, 31, 0), RGB(0, 255, 0), screen);

Draws a rectangle from (x, y) to (x2, y2) filled with a horizontal gradient, blending from color c1 to c2 on the specified destination image.

RectRGrad

void RectRGrad (int x, int y, int x2, int y2, int c1, int c2, int dest)

Draws a rectangle filled with a radial/circular gradient

Example usage:

RectRGrad(0, 0, ImageWidth(screen), ImageHeight(screen), RGB(0, 0, 255), RGB(0, 0, 0), screen);
Draws a rectangle from (x, y) to (x2, y2) filled with a radial gradient, blending from color c1 to c2 on the specified destination image.

RectVGrad

void RectVGrad (int x, int y, int x2, int y2, int c1, int c2, int dest)

Draws a rectangle filled with a vertical gradient

Example usage:

// Fill the screen with a blue to black gradient! Could be nifty for menus.
RectVGrad(0, 0, ImageWidth(screen), ImageHeight(screen), RGB(0, 0, 255), RGB(0, 0, 0), screen);

Draws a rectangle from (x, y) to (x2, y2) filled with a vertical gradient, blending from color c1 to c2 on the specified destination image.

RGB

int RGB (int red, int green, int blue)

Returns a color in a format usable by other image functions.

Example usage:

int white, red;

white = RGB(255, 255, 255);
red = RGB(255, 0, 0);

Returns a color in the valid pixel format for V3's current video mode. The passed paramaters represent the red, green and blue channels used to form a color.

The valid values for each parameter range from 0, which represents 0% of that color, to 255 which represents 100% of that color.

RotScale

void RotScale (int x1, int y1, int angle, int scalefactor, int sourceimage, int destimage)

Rotate and/or scale an image and draws it to another image.

Example usage:

int face = LoadImage( "happy_face.gif" );

RotScale(160, 120, systemtime, 1000, face, screen); 

This is a rotational scaler. The x and y coordinates specify the centerpoint of the image destination. The angle field is in degrees from 0 to 360. Any value for angle is valid, it will be wrapped around at 360.

The scale factor is a whole-image divisor, in a fixed-point of sorts: it ranges from 1 to infinity. 1000 is the centerpoint, equal to a scale factor of 1. A scale of 100 is 10 times bigger than normal. A scale of 10000 is 1/10th the size of normal. It abides clipping rectangles as well as SetLucent values.

RotScale will draw transparent pixels even though there's no t infront of it!

ScaleBlit

void ScaleBlit (int x, int y, int dw, int dh, int sourceimage, int destimage)

Draws an stretched image to another image.

Example usage:

int image;
image = LoadImage("image.pcx");

ScaleBlit(0, 0, ImageWidth(image) * 2, ImageHeight(image) * 2, image, screen);  // draw the image 200% scale

This function draws sourceimage onto destimage, as a normal blit would; only the width and height of source image when it is blitted, is alterable. This allows for scaling both down and up.

SetClip

void SetClip (int x1, int y1, int x2, int y2, int image)

Sets the current clipping rectangle on an image object.

Example usage:

SetClip(0, 0, 50, 50, image);  
// restrict drawing on image object 'image' to the box 
// between 0,0 and 50,50

Line( 0,0, 100,100, 0, image ); 
// attempts to draw a diagonal black line across the image... 
// but haha! It's stopeed at 50,50 by the magical Clipping rectangle!
// ALL GLORY TO THE SETCLIP()!

Sets the current clipping rectangle on an image object. All drawing to this image object, will only appear within the specified clipping coordinates. New images' clipping rectangle defaults to the entire image.

SetCustomColorFilter

void SetCustomColorFilter (int c1, int c2)

Creates a custom color filter with colors in between c1 and c2.

Example usage:

//Make it a random color filter! Madness, I say!
SetCustomColorFilter(RGB(Random(0,255),Random(0,255),Random(0,255)),RGB(Random(0,255),Random(0,255),Random(0,255)));
//Now use the custom filter.
ColorFilter(CF_CUSTOM,screen);
Creates a custom color filter with colors in between c1 and c2. This filter can then be used by ColorFilter, using CF_CUSTOM as the filter argument.

SetLucent

void SetLucent (int percent)

Sets the Lucency value for all drawing functions.

Example usage:

SetLucent(75);
// draw stuff
SetLucent(0); // back to normal

Sets the current drawing lucency to the passed percent. 100% lucent means invisible, 0% is fully opaque.

SetPixel

void SetPixel (int x, int y, int color, int destimage)

Changes the color of a single pixel in the specified image.

Example usage:

SetPixel(50, 50, RGB(255,255,255), screen); // draw a white pixel at x:50 y:50 on the screen

Sets the pixel at (x,y) on destimage to 'color'.

ShowPage

void ShowPage ()

Updates the screen with all the changes you made to it.

Example usage:

Rect(0, 0, 100, 100, RGB(128, 128,128), screen);
ShowPage();

Basically, Copies the contents of the 'screen' image object to the physical screen.<>

ShowPage() also does a lot of secondary stuff in the background. This includes processing all entities (replacing manually having to call ProcessEntities() ), and drawing the Verge3 'sprites'. It also updates the controls (just in case you forgot UpdateControls() )

It's a pretty handy function to have in a Verge loop.

If you don't want to use all of ShowPage()'s features, then you have control over how they are executed. Look in at SetEntitiesPaused(), which allows you to turn off entity processing if you don't want ShowPage() to do it for you. This should also prevent the player from moving. Remember that if you turn the entity-pause on, you need to turn it off before gameplay can resume as normal.

In addition, you can disable the Verge3 'sprites', or just plain not use them, if you don't want them drawn. See Sprite Functions.

There is no real way to disable the updating of input. Verge3 will always do that now, which means even an empty eternal loop will bow down to ALT-X. Although it is good coding practice to call UpdateControls().


notes from vec:

You do not have to re-render everything to call Showpage(), and I strongly recommend you keep at least showpage in your waiting loops anyway because if you're running in windowed mode, or fullscreen and you alt-tab out, basically, if some other app overdraws the window/screen, it will not be refreshed until Showpage is called again.

(eg, you can just call showpage, you don't need to re-render your map or your menu or whatnot- the contents of screen hasn't changed, you're just re-blasting it to the physical screen. additionally, theres not really any benefit to doing a wait for keypress loop that way, you aren't saving any cpu usage by not re-rendering. If you want to be cpu-usage conscious, make use of Sleep() instead, but still call showpage).

Silhouette

void Silhouette (int x, int y, int color, int sourceimage, int destimage)

Draws a colored silhouette of one image onto another image.

Example usage:

Silhouette(0, 0,  RGB(0, 0, 255), hero, screen); // It's a blue silhouette of the hero!

Essentially, this is like a TBlit, except everywhere there's a non-transparent pixel in the source image, it will place a pixel of the color you specify in the destination image. In effect, a colored silhouette of the source image.

Silhouette abides by the SetLucent() value, however to acheive the effect you probably want with that, you will need to TBlit the source image directly first, then do a lucent Silhouette on top of it.

SubtractiveBlit

void SubtractiveBlit (int x, int y, int sourceimage, int destimage)

Subtractive blits one image onto another.

Example usage:

int image;
image = LoadImage("mypic.pcx");

SubtractiveBlit(0, 0, image, screen);

This function is very much like Blit(), but draws the pixels with subtractive blending. Subtractive blending has few uses, but when it is put to good use, can be very handy. The best way to become familiar with it's uses is purely experimentation.

SuperSecretThingy

void SuperSecretThingy (int x_skew, int y_offset, int y, int source, int dest)

Shhh... It's a secret!

Example usage:

// Adopted from the Timeless demo!
SuperSecretThingy(scrollofs / 16, systemtime / 2, ybase, bg, screen);

An enigmatic function which is a super secret.

Note: The source image has to be 256x256 or you get an error.

TAdditiveBlit

void TAdditiveBlit (int x, int y, int sourceimage, int destimage)

A transparent-conscious version of AdditiveBlit

Example usage:

int image;
image = LoadImage("mypic.pcx");

TAdditiveBlit(0, 0, image, screen);

Same as AdditiveBlit, with the exception that this function does not draw transparent pixels.

TBlit

void TBlit (int x, int y, int sourceimage, int destimage)

Draws an image onto another, but lets the base image show through the transparent parts of the source.

Example usage:

int image;
image = LoadImage("mypic.pcx");

TBlit(0, 0, image, screen);

Identical to Blit() in every way, the only exception here is that transparent colored pixels are not drawn to destimage.

TBlitLucent

void TBlitLucent (int x, int y, int lucent, int source, int dest)

Simple transparent blit with constant translucency override

Example usage:

BlitLucent(300,220,50,stationWatermark,screen); //station watermark
Identical to LucentBlit() in every way, the only exception here is that transparent colored pixels are not drawn to destimage.

TBlitTile

void TBlitTile (int x, int y, int tile, int dest)

Blit a tile from the vsp with transparency

Example usage:

none
Blit tile index 'tile' to x,y on image 'dest' with transparency

TGrabRegion

void TGrabRegion (int sx1, int sy1, int sx2, int sy2, int dx, int dy, int sourceimage, int destimage)

Extracts a sub-rectangle from a given image and blits with transparency

Example usage:

int edgar = loadimage("edgar.pcx");
int leftFrame = NewImage(16,24);

//the order of things is down/up/left/right in the world of verge
//that means we need the third frame
TGrabRegion(16*2,0,16*2 +15,23,0,0,edgar,leftFrame);
TGrabRegion receives the rectangle that it should extract from the source image in (sx1,sy1)->(sx2,sy2). This rectangle is placed into the destination image with transparency at (dx,dy). This function is very useful for manually slicing up an image that contains a strip of frames for an animation and extracting a single frame from it. The example will demonstrate this

Triangle

void Triangle (int x1, int y1, int x2, int y2, int x3, int y3, int color, int dest)

Renders a FILLED triangle

Example usage:

// A green, right-angled triangle.
// |\
// | \
// |  \
// +---\
Triangle(0, 0, 0, 40, 30, 0, RGB(0, 255, 0), screen);

Triangle() will draw a filled triangle using the vertices (x1, y1), (x2, y2), and (x3, y3) of the specified color to the desired destination image. Note the difference in naming convention from the other shape drawing routines, Triangle() gives a filled triangle, and if you want to draw the outline, make use of Line() instead.

Note: This is a bad triangle fill routine, and if you try to assemble a more complicated polygon from a number of triangles, some pixels will be overwritten along the edge. This creates undesirable artifacts in some cases, such as when translucency is enabled (a seam will sometimes be visible). Also, drawing three sides with Line() for an outlined triangle will not match up with the filled triangle routine.

(We hesitate to improve this because you don't need to be making 3D games. But if you are making a Starfox clone, please let us know and we can talk about it!)

TScaleBlit

void TScaleBlit (int x, int y, int dw, int dh, int sourceimage, int destimage)

A transparency-conscious version of Scaleblit.

Example usage:

int image;
image = LoadImage("image.pcx");

TScaleBlit(0, 0, ImageWidth(image) * 2, ImageHeight(image) * 2, image, screen);

Indentical to ScaleBlit, with the exception that transparent pixels will not be drawn to the destimage.

TSubtractiveBlit

void TSubtractiveBlit (int x, int y, int sourceimage, int destimage)

A transparency-conscious version of SubtractiveBlit.

Example usage:

int image;
image = LoadImage("mypic.pcx");

TSubtractiveBlit(0, 0, image, screen);

Identical to SubtractiveBlit, with the exception that transparent pixels will not be drawn to the destimage.

TWrapBlit

void TWrapBlit (int x, int y, int sourceimage, int destimage)

A transparency-conscious version of WrapBlit.

Example usage:

int mytile;
mytile = LoadImage("tile.pcx");

TWrapBlit(0, 0, mytile, screen);

Identical to WrapBlit, with the exception that transparent pixels aren't drawn.

WrapBlit

void WrapBlit (int x, int y, int sourceimage, int destimage)

Blits a tiling pattern of an image onto another image.

Example usage:

int mytile;
mytile = LoadImage("tile.pcx");

WrapBlit(0, 0, mytile, screen);

WrapBlit can be a very useful function. What it does is tiles sourceimage from it's origin coordinates (x,y) until it fills all of destimage (respecting the destination image's clipping rectangle).

This can be used to create backgrounds that scroll around, while still keeping the screen filled.

Sprite Functions

At the moment, the sprite system is unfinished and basically unusable. Nonetheless, it's there if you want it. In a future build, many more features will be added.

For the corresponding sprite variables go here

GetSprite

int GetSprite ()

Retreives a sprite handle.

Example usage:

void SpawnRainDrop()
{
  int i = GetSprite();
  if (i == -1) return;

  sprite.x[i] = Random(0, ImageWidth(screen));
  sprite.y[i] = -Random(0, ImageHeight(screen)); // Negative coords.
  sprite.sc[i] = 0; // 0 = map coordinates, 1 = screen coordinates
  sprite.image[i] = image_raindrop; // This means sprite is now on.
  sprite.lucent[i] = 0; // Opaque.
  sprite.addsub[i] = 0; // 0 = normal blit, -1 = subtractive blit, +1 = additive blit
  sprite.alphamap[i] = 0; // No alpha map here.
}

Returns the first sprite index found without an assigned image handle. You can have up to 256 sprites simultaneously. You should immediately set an image for the sprite, or else it will be reused. Returns -1 if a free index cannot be found.

Note: In the current build, all sprite data must be manually cleared from an index. This means all sprite variables should be assigned a value, or else you risk having unwanted sideeffects

ResetSprites

void ResetSprites ()

Frees all sprites.

Example usage:

ResetSprites();

Frees all sprites from memory, and sets all their variables to their initial values, typically 0 or "".

Important: Remember to free any temporary image handles associated with the sprites prior to any reset.

Sound/Music Functions

Verge now supports (or will real soon) support module repacking. Please view the documentation at [ http://www.pi-r-squared.com/code/garlick ] . A brief, exciting summary of its critical features would be: removes redundant samples from mod files and optionally uses flac lossless compression to result in a significantly smaller distribution size for all games, especially those including custom music with shared samples.

Its integration with verge is simple. A call to PlayMusic("module.it") will attempt to look for the files `module.it_` and `library` in the same directory. If it finds them, it will load them as repacked modules. If not, it will attempt to load `module.it` directly before giving up.

It is thought that this interacts flawlessly with the pakfile system. Please contact zeromus if you encounter any difficulties.

As an added bonus, my_sfx.wav_ can be loaded the same way, resulting in around a 40-50% decrease in sfx size.

FreeSong

void FreeSong (int h)

Free the song from memory to prevent memory leakage

Example usage:

int mysong=loadSong("mysong.mp3");
freeSong(mysong);
Free song 'h' from memory to prevent memory leakage

FreeSound

void FreeSound (int handle)

Releases a loaded sound from memory.

Example usage:

int MySound;
MySound = LoadSound("file.wav"); // load a sound into the MySound handle...

// ..use MySound..

FreeSound(MySound); // ...done using it, free up the memory.

Use this to free the memory occupied by a WAV file. It is good coding habit to always free memory you fill. If you do not, you could create system degenerating memory leaks, and those are no good.

GetSongPos

int GetSongPos (int h)

returns the current position of a song

Example usage:

getSongPos(mysong); returns 10
returns the current position of song 'h'

GetSongVolume

int GetSongVolume (int h)

returns the volume of the song your playing

Example usage:

getSongVolume(mysong); returns 100
returns the volume of song 'h'

LoadSong

int LoadSong (string name)

load a song into memory for playing

Example usage:

int mysong=loadSong("mysong.mp3");
playsong(mysong);
Load song 'name' into memory for playing.

LoadSound

int LoadSound (string wavfile)

Loads a sound file into memory and returns a sound handle.

Example usage:

int mysound;
// use mysound
mysound = LoadSound("myfile.wav");

Loads a sound file (like .wav, or .ogg) into the sound cache, and returns a handle for use when directing sound effect-related function calls upon the sound.

PlayMusic

void PlayMusic (string songfile)

Loads and plays the specified songfile.

Example usage:

PlayMusic("mysong.xm");
SetMusicVolume(music_volume);

This function loads and immediately plays the specified song.

This is the cornerstone of the 'simple' music API. It does not return a handle, it does no caching, it just loads and plays the song until you call PlayMusic() again with a different song, or until you call StopMusic().

Important note is that it resets to volume to 100 whenever called, so make sure to use SetMusicVolume() afterwards if you need to.

PlaySong

void PlaySong (int h)

Play a song that you have loaded into memory

Example usage:

int mysong=loadSong("mySong.mp3");
playsong(mysong);
Play song 'h' that you have loaded into memory

PlaySound

int PlaySound (int handle, int volume)

Plays the given sound effect at the given volume

Example usage:

int MySound;
int MyChannel;
MySound = LoadSound("file.wav");

PlaySound(MySound, 100); //Played without assigned channel
MyChannel = PlaySound(MySound, 100); //Played through a channel

Handle should be a handle obtained from loadsound()
Volume should be 0..100
You can also play this through a channel, as shown below. Playing through a channel allows you to use stopsound.

SetMusicVolume

void SetMusicVolume (int v)

set the volume of the music playing

Example usage:

setMusicVolume(50);
set the volume of currently playing music to 'v'

SetSongPaused

void SetSongPaused (int h, int p)

pause/unpause a song that's playing

Example usage:

// Say we're playing some song
PlaySong(mysong);

// Then we might want to pause the song
SetSongPaused(mysong, 1);

// Some time later...

// Start the song again where we left off! Hooray!
SetSongPaused(mysong, 0);
SetSongPaused can pause and unpause a song.
  • SetSongPaused(h,1) pauses the song 'h' at its current position.
  • SetSongPaused(h,0) unpauses (ie plays) the song 'h' at its current position.
The current song position can be retrieved/set with GetSongPos and SetSongPos.

SetSongPos

void SetSongPos (int h, int p)

set the current position of a song playing

Example usage:

setSongPos(mysong, 20);
set the current position song 'h' to position 'p'

SetSongVolume

void SetSongVolume (int h, int v)

Sets the current volume of a song playing

Example usage:

setSongVolume(mysong, 100);
Sets the current volume of song 'h' to volume 'v'

SoundIsPlaying

int SoundIsPlaying (int chan)

Returns whether or not a sound is playing

Example usage:

// If there is no sound planning on my_channel, play a sound.
if (!SoundIsPlaying(my_channel))
{
  my_channel = PlaySound(sfx);
}
Returns whether or not a specific channel is currently playing a sound. Useful to help minorly with synching things with sounds, or preventing identical sound effects from overlapping.

StopMusic

void StopMusic ()

Halts current music playing completely.

Example usage:

PlaySong("mysong.xm");

// do stuff.

StopMusic();

Halts current music playing completely.

This is part of the simple mucis API.

StopSong

void StopSong (int h)

Stop playing a song

Example usage:

int mysong=LoadSong("mysong.mp3");
playSong(mysong);
stopsong(mysong);
Stop playing song 'h'

StopSound

void StopSound (int chan)

stops playing a sound

Example usage:

int mysound=loadSound("crack.wav");
int mychannel = playSound(mysound, 100);
stopSound(mychannel);
stops playing sounds on channel 'chan'

Font Functions

1. There is a predefined, tiny, white, variable-width font built-in to the engine. For any of these font functions, use the font handle 0 (zero) to access this font.

EnableVariableWidth

void EnableVariableWidth (int fonthandle)

Turns variable-width mode on for the specified font.

Example usage:

int MainFont;

MainFont = LoadFont( "my_font.gif" );

EnableVariableWidth( MainFont );

This function enables variablewidth mode for the font passed. If you're not familiar with variable-width fonts, this simply means that each character only occupies as much space as it needs when printing.

You should NOT call this with 0 as an arguement, as you might with other font routines to denote the builtin font; the built-in font is always variable width, and passing 0 to this function will generate an error.

FontHeight

int FontHeight (int font)

Returns the height of a font

Example usage:

font = LoadFont("font.png");
fontht = FontHeight(font);

When passed a font handle it will return the height of a character. This is constant, and will include any excess space that existed in the font graphic.

FreeFont

void FreeFont (int font)

Frees a font that you have previously loaded

Example usage:

int MainFont;
//load and use the font
FreeFont(MainFont);
Just use this function to free a font that you don't need any more.

LoadFont

int LoadFont (string sourceimage)

Loads a font from an image file and returns a FONT handle to be used by other font functions..

Example usage:

int MainFont;
MainFont = LoadFont("myfont.pcx");

Loads a font from an image file and returns a handle to the font. sourceimage should be a filename. The width/height of the cells in the font will be automatically detected. Use LoadFontEx() if the autodetection is failing and you need to manually specify a cell width

LoadFontEx

int LoadFontEx (string sourceimage, int width, int height)

Loads a font from an image file and returns a FONT handle to be used by other font functions.. (advanced)

Example usage:

int MainFont;
MainFont = LoadFontEx("myfont.pcx", 10, 10);

Loads a font from an image file and returns a handle to the font. sourceimage should be a filename, and width/height represent the cell width/height in the image file.

PrintCenter

void PrintCenter (int x, int y, int destimage, int font, string text)

Prints a center-justified string at the specified coordinates.

Example usage:

PrintCenter(ImageWidth(screen) / 2, ImageHeight(screen) / 2, screen, MainFont, "Hello World!");
Prints centered text at (x,y). If you pass 0 for the font handle, a builtin font will be used.

PrintRight

void PrintRight (int x, int y, int destimage, int font, string text)

Prints a right-justified string with the rightmost point at the given coordinates.

Example usage:

PrintRight(ImageWidth(screen)-1, ImageHeight(screen)-1, screen, MainFont, "Hello World!");

Prints 'text' at (x,y), with right justification. If you pass 0 for the font handle, a builtin font will be used.

PrintString

void PrintString (int x, int y, int destimage, int font, string text)

Prints a left-justified string at the given coordinates.

Example usage:

PrintString(0, 0, screen, MainFont, "Hello World!  Also Grue is sexy!");

This function, which has a stupid order of arguments, prints text to the screen. All the arguments should be self-explanatory, even if they are in retarded order. If you pass 0 for the font handle, a built-in font will be used.

SetCharacterWidth

void SetCharacterWidth (int font, int character, int width)

Forces a character in the font to be a specific width.

Example usage:

SetCharacterWidth(0, 'a', 20); // Every 'a' is now 20 pixels wide.

Forces a character in the font to be a specific width. Useful for special formatting or for correcting EnableVariableWidth().

TextWidth

int TextWidth (int font, string text)

Returns the width of a string rendered in a specific font.

Example usage:

int text_w;

text_w = TextWidth(MainFont, "Hello World!");

Returns the width (in pixels) of the passed string using the passed font. If you pass 0 for the font handle, it will return the width of the text baesd on the builtin font.

WrapText

string WrapText (int font, string text, int line_width)

Wraps a string in a certain font to fit a specific width.

Example usage:

int font = 0;
string s = "I am the mighty dragon slayer Felgar! I have come to save your wretched little village!"
// Fit our text in 100 pixels wide with the Verge default font.
s = WrapText(font, s, 100);
// Print the wrapped text! The wrapped text has newlines!
// Newlines are denoted by chr('\n'), which can be handled by PrintString.
PrintString(0, 0, screen, font, s);

Wraps a string in a certain font to fit a specific width, by adding newlines. Useful for textboxes.

Math Functions

Trigonometric functions use a certain convention for angles that you may think a little odd. Zero degrees points due east and ninety degrees is due north. If you are using another convention in your game--such as zero degrees due north--then you will have to constantly convert between them when using the trig functions. I advise you not to use another convention in your game. Some things are worth fighting, but not this.

You will need to use Fixed-point numbers with these functions.

fcos(), fsin(), fatan2() and the like are for things that need more than 0 to 360 for angles. Verge defines a constant FIXED_PI, which is approximately the mathematical constant PI * 65536, which is used to measure the angles more accurately since we don't have floats. 2 * FIXED_PI is the same as 360 degrees.

abs

int abs (int value)

Returns the absolute value of a number.

Example usage:

x = abs(0); // 0
x = abs(56); // 56
x = abs(-7); // 7

Returns the absolute value of a number, which is returns the value if it's positive, or -value if it's negative. It's essentially the same as sqrt(x*x); except faster.

acos

int acos (int cos)

Returns the arccosine of a given value in fixed-point notation.

Example usage:

int z = acos(65535/2);

Exit( str(z) );  // acos of ".5" should be 60. 

Returns the arccosine of the input value. As implied by the example, acos() takes its input value in 16.16 fixed point, so the input value should range from -65535 to +65535. The output is in integer degrees.

asin

int asin (int sin)

Returns the arcsine of the input value in fixed-point notation.

Example usage:

int z = asin(sin(30));
Exit(str(z));
Returns the arcsine of the input value. As implied by the example, asin() takes its input value in 16.16 fixed point, so the input value should range from -65535 to +65535. The output is in integer degrees.

atan

int atan (int tan)

Returns the arctangent of the given value in fixed-point notation.

Example usage:

int at = atan(tan(45));
Exit(str(at));
Returns the arctangent of the given value. The input value should be in 16.16 fixed point (eg, multiplied by 65535).




You can also use atan2(), which ensures the result is in the correct quadrant.

atan2

void atan2 (int y, int x)

Calculates arctan of y,x

Example usage:

int x = 0-2;
int y = 2;
//this point should be in quadrant II (northwest)

atan(y*65536/x); //-45
//-45 is in quadrant IV (southeast); not what we expected

atan2(y,x); //135
//135 is in quadrant II, just as we expected

This function will compute the arctan (tan-1) of y/x, and based upon the coordinates of y and x, put the result into the proper quadrant.

Note the odd order of the arguments, y and x. Thats backwards from usual. Beware...

Unlike the inputs to the other inverse trig functions, y and x do not need to be fixed point *65536. Although, it should not hurt anything if they are

cbrt

int cbrt (int value)

Returns the cube root of a number.

Example usage:

int x = cbrt(27); // 3!

Returns the cube root of a number. Like square root, it is sadly not very friendly with fixed point integers.

cos

int cos (int angle)

Returns the cosine of the specified angle in fixed-point notation.

Example usage:

SetPixel(150+(sin(systemtime)*40/65535), 100+(cos(systemtime)*40/65535), RGB(255,255,255), screen);

Returns the cosine of the specified angle. Note that the angle input will be in integer degrees (0..360, which will loop at values >=360), however the return value will be in fixed point 16.16, meaning the value will be effectively multiplied by 65535, thus the return value will range from -65535 to +65535.

facos

int facos (int ratio)

Same as acos but returns 16.16 fixed point radians, for precision.

Example usage:

int angle = facos(596409);
Same as acos but returns 16.16 fixed point radians, for precision.

fasin

int fasin (int ratio)

Same as asin, but returns 16.16 fixed point radians, for precision.

Example usage:

int angle = fasin(43689);
Same as asin, but returns 16.16 fixed point radians, for precision.

fatan

int fatan (int ratio)

Same as atan, but returns 16.16 fixed point radians, for precision.

Example usage:

x = fatan(5472);

Same as atan, but returns 16.16 fixed point radians.

fatan2

int fatan2 (int y, int x)

Same as atan2, but returns 16.16 fixed point radians, for precision.

Example usage:

int y = 67;
int x = 2;
int angle = fatan2(y, x)

Same as atan2, but returns 16.16 fixed point radians, for precision.

fcos

int fcos (int fixed_angle)

Same as cos(), but takes a 16.16 fixed point radian angle.

Example usage:

int xdist = fsin(FIXED_PI);
int ydist = fcos(FIXED_PI);
Same as cos(), but takes a 16.16 fixed point radian angle.

fsin

int fsin (int fixed_angle)

Same as sin(), but takes a 16.16 fixed point radian angle.

Example usage:

int xdist = fsin(FIXED_PI);
int ydist = fcos(FIXED_PI);
Same as sin(), but takes a 16.16 fixed point radian angle.

ftan

int ftan (int fixed_angle)

Same as tan(), but takes a 16.16 fixed point radian angle.

Example usage:

int tangent = ftan(70957);
Same as tan(), but takes a 16.16 fixed point radian angle.

max

int max (int a, int b)

Returns the largest of two input numbers.

Example usage:

int x = max(6788, 1); // x is 6788!

Returns the largest of two input numbers.

min

int min (int a, int b)

Returns the smallest of two input numbers.

Example usage:

int x = min(6788, 1); // x is 1!

Returns the smallest of two input numbers.

pow

int pow (int base, int exp)

Raises base to exp power

Example usage:

int i;
int powerOfTwo;
for(i=0;i<=16;i++)
  powerOfTwo = pow(2,i);
//will yield the powers of two
  

Pow() will raise base to the power specified by exp.

This function is darn well near impossible to use with fixed point.

sgn

int sgn (int value)

Returns if the number is positive, negative or zero.

Example usage:

x = sgn(-7676); // -1
x = sgn(0); // 0
x = sgn(90909); // +1

Returns the sign of a number. If the number is negative, it returns -1. If the number is positive, it returns 1. If the number is zero, it returns 0.

sin

int sin (int angle)

Returns the sine of a given angle in fixed-point notation.

Example usage:

SetPixel(150+(sin(systemtime)*40/65535), 100, RGB(255,255,255), screen);

This returns the sine of a given angle. Note that the angle input will be in integer degrees (0..360, which will loop at values >=360), however the return value will be in fixed point 16.16, meaning the value will be effectively multiplied by 65535, thus the return value will range from -65535 to +65535.

sqrt

int sqrt (int number)

Returns the square root of the given number

Example usage:

int x = 225 * 65536 / 100; //2.25 in fixed point

int result = sqrt(x)*256; 
//returns 98304, which is 1.5 in fixed-point, as we expected

sqrt() returns the square root of the given input number.

To use this with *65536 fixed-point, use the fixed-point number as an input and multiply the result by 256.

tan

int tan (int angle)

Returns the tangent of the given angle in fixed-point notation.

Example usage:

int z = tan(180);

Returns the tangent of the given angle. The input angle is in integer degrees, however the output is in 16.16 fixed point; to convert it to a usable format, you should multiply the return value by your desired range, then divide it by 65535. Unlike sin/cos, this ranges from -infinity to +infinity.

File Functions

A quick overview of verge file i/o functions. The standard procedure is to pass a filename to FileOpen() and get a file handle to use with the data read/write functions, and the close the file with FileClose() at the end. A few important points first. Opening a file in write mode will create a new file if one doesn't exist, but will overwrite if one does exist - just opening the file wipes all the data. Also, all read and write operations go from the current position in the file, which starts at the beginning, and move the position onwards in the process. Finally, the base unit of all everything here is the byte, 8 binary 1/0 switches, which equates to a number from 0 to 255 or one character of ascii text. There are two main uses for file i/o in verge, there's a brief summary of both below.

Reading from plain text data files

Useful for: Managing in-game data in an easy to access and alter form. Load-once purposes.

FileReadLn() to get a sting of data from the file

GetToken() to extract the information from the string

val() to turn string data into numbers where needed.

As it's easy to make the odd mistake when creating or editing datafiles by hand, be sure to add some error checking in case of mistakes, and preferably allow for extra non-data lines, so the file can be commented/explained where needed.

Writing and reading binary data files

Useful for: Recording and recalling data mid game. Fast read and write times.

FileWriteQuad() for writing any integer variables to file.

FileWriteString() for writing any string variables to file.

FileReadQuad() for reading integer variables from file.

FileReadString() for reading string variables from file.

There are several functions that do similar things, but these are relatively safe and simple, just remember to match the read and write formats exactly, and be aware changing either will cause big problems. For this reason, writing a 'version number' at the top of the file, and checking it is up to date on read might be useful.

FileClose

void FileClose (int file)

Releases a file handle when it is no longer needed

Example usage:

int count = 1;
int file = FileOpen("save"+str(count)+".dat", FILE_READ);
while(file)
{
  FileClose(file);
  count++;
  file = FileOpen("save"+str(count)+".dat", FILE_READ);
}
FileClose(file);
// Counts number of save games by opening them and checking if
// The file pointer returned is valid, stopping when it's not
// It's very important to remember to close the files after
// Opening them, so they can be used later

Pass a handle to an open file, and verge frees the file and... stuff. Make sure you do this for each file you open, after you've finished using it. For... lots of reasons.

FileCurrentPos

int FileCurrentPos (int file)

Returns the current byte position in an open file

Example usage:

int file = FileOpen("dump.dat", FILE_WRITE);
Log("Start: "+str(FileCurrentPos(file)));
FileWriteQuad(file, 97);
Log("After Quad: "+str(FileCurrentPos(file)));
FileWriteString(file, "Four");
Log("After String: "+str(FileCurrentPos(file)));
FileClose(file);
// Creates/overwrites a new file and writes some data
// Logging the position after each step, like so:
// "Start: 0"
// "After Quad: 4"
// "After String: 10"
// Position starts at 0
// After writing a quad byte position is 4
// After writing a string of length 4, with 2 byte header
// Incrememnts another 6, for a total position of 10

Pass a file handle opened in either read or write mode, and it returns the number of preceding bytes to the current position. As all read/write functions automatically increment the position, this is will generally return the number of the next byte to be read/written.

FileEOF

int FileEOF (int file)

Determines whether or not the current file has reached its end.

Example usage:

// Read until end of file, or until the max players
// allowed has been met, whichever comes first.
while (!FileEOF(f) && i < MAX_PLAYER_COUNT)
{
  player[i].hp = FileReadQuad(f);
  i++;
}
Determines whether or not the current file has reached its end-of-file (EOF) marker. Useful in loops where the amount of bytes or lines in a file is undetermined, and also good for detecting that end-of-file is unexpectedly early in a given file.

FileOpen

int FileOpen (string filename, int mode)

Opens a file in the directory system for reading or writing

Example usage:

int file = FileOpen("maped3.exe", FILE_WRITE);
FileClose(file);
// Oh dear! You've just replaced Maped 3 with a blank file
// Doh... I actually just did, time to download the verge engine again

Will open or create a file of the passed name, for either reading or writing, depending on the mode passed. It returns a handle to the file as a non zero integer. If the operation fails, it returns 0, which idealy you should check for before reading from the file.

The mode pass is to determine if you want to read from or write to the file, only one can be selected, and the file must be closed and re opened to change to the other mode. The defines used by verge are:

#define FILE_READ 1
#define FILE_WRITE 2
#define FILE_WRITE_APPEND 3

Verge will always return 0 if you try to open a file in read mode that does not exist, however write mode will create a new file with that name. More importantly however, FILE_WRITE will always overwrite any data if the file already exists. This is why appending to the end of an existing file should use FILE_WRITE_APPEND instead.

Verge does not let you access the directory structure oustside your current branch. You can access sub folders, but no overwriting stuff in c:\windows... unless of course verge is run from there.

Like most things in verge, case matters not a whit. You can pass upper or lower case letters for a filename, and it will still find the right thing, even if you are silly: "ReAdmE.tXT" will still open the file (in Windows anyway).

FileReadByte

int FileReadByte (int file)

Reads a byte from file into an integer

Example usage:

int file = FileOpen("readme.txt", FILE_READ);
Log(str(FileReadByte(file)));
FileClose(file);
// This read the first byte and logs the value
// First line is "Welcome to VERGE 3! " so logs
// The number '87' which is the value of 'W' in ascii
Pass a handle to a file opened in read mode, and returns the integer value of the byte at the current position, and moves the position onto the next byte. The returned number will always between 0 to 255.

FileReadLn

string FileReadLn (int file)

Returns data from a file as an ascii string, ending at a new line

Example usage:

int file = FileOpen("README.TXT", FILE_READ);
FileSeekPos(file, 1, SEEK_CUR);
Log(FileReadLn(file));
FileClose(file);
// If you have the same verge readme in the directory
// This will write the string below in the v3.log file
// "elcome to VERGE 3! "
Pass a handle to a file opened in read mode, and it reads bytes from the file as ascii and returns a string. It starts reading at the current position in the file, and stops when it reaches a new line marker. The current position in the file is incremented to the start of the next line.

FileReadQuad

int FileReadQuad (int file)

Reads four bytes from file into an integer

Example usage:

int file = FileOpen("readme.txt", FILE_READ);
Log(str(FileReadWord(file)));
FileClose(file);
// This read the first two bytes and logs the value
// First line is "Welcome to VERGE 3! " so logs
// The number '1668048215' which is a compound
// Of the values of 'W', 'e', 'l', and 'c' in ascii
// Obviously this is more useful as a big number

Pass a handle to a file opened in read mode, and returns the integer value of the first four bytes at the current position, and moves the position onto the following byte. The can be the full value of a verge integer, including negative numbers. The least significant byte is read in first, so effectively performing:

FileReadByte(file) + (FileReadByte(file) << 8) +
    (FileReadByte(file) << 16) + (FileReadByte(file) << 24)

FileReadString

string FileReadString (int file)

Reads a string from file as ascii with a two byte length header

Example usage:

string text = "Check me";
int file = FileOpen("test.txt", FILE_WRITE);
FileWriteString(file, text);
FileClose(file);
int file = FileOpen("test.txt", FILE_READ);
if (strcmp(FileReadString(file), text)) Log("LIES!");
else Log("Truth!");
FileClose(file);
// So, that should should always log the truth
// Don't let strcmp confuse you there, it's always
// The wrong way around, returns 0 on match


int file = FileOpen("readme.txt", FILE_READ);
Log(str(len(FileReadString(file))));
FileClose(file);
// This logs a length of 9318 for the string read
// As it wrongly interpreted the first two bytes
// As a length in word format. Make sure to only
// Use this when the data was written correctly

Pass a handle to a file open in read mode, and it returns a string of bytes in ascii, of length determined by a two byte header. The file reads from the current position, and increments the position to the end of the string. Note the string to be read must have been written using FileWriteString() as it needs the two byte header to know how much of the file to read.

FileReadToken

string FileReadToken (int file)

Reads a string from file as ascii stopping at whitespace

Example usage:

int thefile = loadfile("stuff.txt");

log(filereadtoken(thefile));

This works like GetToken. Each time you call this, it will return a string using whitespace as a token delimiter. It automatically increments which token it will return, so calling it repeatedly will return a sequence of strings.

FileReadWord

int FileReadWord (int file)

Reads two bytes from file into an integer

Example usage:

int file = FileOpen("readme.txt", FILE_READ);
Log(str(FileReadWord(file)));
FileClose(file);
// This read the first two bytes and logs the value
// First line is "Welcome to VERGE 3! " so logs
// The number '25943' which is the value of 'W' in ascii
// plus the value of 'e' raised by one byte
// 87 + (101 << 8)== 87 + 25856 == 25943
// Obviously this is more useful as a big number

Pass a handle to a file opened in read mode, and returns the integer value of the first two bytes at the current position, and moves the position onto the following byte. The returned number will always between 0 to 65535. The least significant byte is read in first, so effectively performing:

FileReadByte(file) + (FileReadByte(file) << 8)

FileSeekLine

void FileSeekLine (int file, int linenum)

Sets the current position in the file based on newline markers

Example usage:

int file = FileOpen("readme.txt", FILE_READ);
FileSeekLine(file, 12);
Log(FileReadLn(file));
FileClose(file);
// For the current verge readme this logs:
// "http://www.verge-rpg.com/docs/"
// Which is line number 13 as count starts at 0

Pass a handle to a file open in read mode, and it will set the current position in the file to the byte after the (linenum) new line is passed. Passing 0 sets the position to the start of the file.

FileSeekPos

void FileSeekPos (int file, int pos, int mode)

Sets the current position in the file based byte ofsets

Example usage:

int file = FileOpen("readme.txt", FILE_READ);
FileSeekPos(file, 25, SEEK_SET);
Log(str(FileReadByte(file)));
FileClose(file);
// Reads the 26th byte from the start of the readme
// Remeber newline markers are two characters
// Logs '97' which is the ascii value of little a
// "Welcome to VERGE 3! "
// "(Readme.txt, 2004.09.28 edition of v3)"
//     ^


int file = FileOpen("dump.txt", FILE_WRITE);
FileWrite(file, "Oh fuck!");
FileSeekPos(file, 0-4, SEEK_END);
FileWriteByte(file, '*');
FileClose(file);
// Going backwards from the end of the file
// We impose a little censorship! Yeay!

Pass a handle to a file open in either read or write mode, an distance in bytes to move, and a mode to determine the starting position.... Pants... I'll do this later.

#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

FileWrite

void FileWrite (int file, string s)

Writes a string to file as ascii with no padding

Example usage:

int file = FileOpen("datafile.dat", FILE_WRITE);
FileWrite(file, "a");
FileClose(file);
// This creates/overwrites a file one byte in size
// Opened in a hex editor the contents will be: '61'
// Which is the ascii code of a little a


int file = FileOpen("datafile.dat", FILE_WRITE);
FileWrite(file, "Hello Number 1");
FileClose(file);
// Always writes one byte per character
// So this is a 14 byte file. In hex:
// '48 65 6c 6c 6f 20 4e 75 6d 62 65 72 20 31'

Pass a handle to a file that is opened in write mode, and a string to be written. The string is written from the current position in the file, overwriting any existing data. It uses a 1 byte ascii representation for each character, with no padding or escape sequence - so bytes used is equal to len(s).

FileWriteByte

void FileWriteByte (int file, int byte)

Writes an integer to file as one byte

Example usage:

int file = FileOpen("datafile.txt", FILE_WRITE);
FileWriteByte(file, 97); // or $61 or 'a'
FileClose(file);
// Opens/Creats a file and writes one byte to it
// Opened in a hex editor gives '61' as value of the byte
// In a text editor it gives the ascii 'a'

int file = FileOpen("datafile.txt", FILE_WRITE);
FileWriteByte(file, 0 - 2);
FileClose(file);
// Negative numbers are not stored properly
// Opened in a hex editor gives 'fe' as value of the byte
// -2 in binary: 11111111111111111111111111111110
// Least significant byte: 11111110
// Decimal: 254

Pass a handle to a file that is opened in write mode, and an integer to be written. The byte will be written at the current position within the file, over any data that was previously there, and position will move to the next byte. As only one byte of the four that make up a verge integer is being written, any numbers bigger than 255 or less than 0 will NOT be written correctly. Use FileWriteQuad() unless sure the number being written will remain within these bounds.

Verge is effectivly only writing the 8 least significant bits of the passed integer, so performing a (integer & 255) operation before writing. Numbers outside the range of 0 to 255 will be written as another number with the range, depending on the value of the least significant byte.

FileWriteCHR

void FileWriteCHR (int filehandle, int ent)

Saves an entity's CHR to the specified filehandle

Example usage:

int f = FileOpen("mychr.chr", FILE_WRITE);
if (f)
{
  FileWriteEntity(f, 0);
  FileClose(f);
}
Writes an on-map entity into a file handle open for writing. Fairly advanced, so this is only recommended if you plan on making a map editor within Verge or something. Although, you can't exactly manipulate the entity's image data at the moment, so this is also VERY limited.

FileWriteLn

void FileWriteLn (int file, string s)

Writes a string to file as ascii with a newline at the end

Example usage:

int file = FileOpen("datafile.dat", FILE_WRITE);
FileWriteLn(file, "a");
FileClose(file);
// This creates/overwrites a file three bytes in size
// Opened in a hex editor the contents will be: '61 0d 0a'
// Which is the ascii code of a little a
// With two characters added to denote the new line

int file = FileOpen("datafile.dat", FILE_WRITE);
FileWriteLn(file, "Hello");
FileWriteLn(file, "Peeps");
FileClose(file);
// Opened in a text editor this reads:
// "Hello
// "Peeps
// ""
// Three lines, with the last one blank

Pass a handle to a file that is opened in write mode, and a string to be written. The string is written from the current position in the file, overwriting any existing data. It uses a 1 byte ascii representation for each character, and appends a 2 byte newline sequence on the end of the string - so bytes used is equal to len(s) + 2.

FileWriteMap

void FileWriteMap (int file)

Writes the current map into a file.

Example usage:

int f = FileOpen("mymap.map", FILE_WRITE);
if (f)
{
  FileWriteMap(f);
  FileClose(f);
}

Writes the currently active map into a file handle open for writing. Change curmap.savevsp to affect what VSP file it references when it writes it. Fairly advanced, so this is only recommended if you plan on making a map editor within Verge or something.

FileWriteQuad

void FileWriteQuad (int file, int quad)

Writes an integer to file as four bytes

Example usage:

int file = FileOpen("datafile.txt", FILE_WRITE);
FileWriteQuad(file, 97); // or $61 or 'a'
FileClose(file);
// Opens/Creats a file and writes four byte to it
// Opened in a hex editor gives '61 00 00 00'

int file = FileOpen("datafile.txt", FILE_WRITE);
FileWriteQuad(file, -2);
FileClose(file);
// All integers are stored in full
// -2 in binary: 11111111111111111111111111111110
// File opened in a hex editor gives 'fe ff ff ff'

Pass a handle to a file that is opened in write mode, and an integer to be written. Four bytes will be written at the current position within the file, over any data that was previously there, and position will move to the next byte. As this writes the full value of the verge integer, it will read back exactly as it was stored.

Note that the bytes are stored in order of least significant to most significant. In effect what happens is:

FileWriteByte(quad & 255);
FileWriteByte(quad & (255 << 8));
FileWriteByte(quad & (255 << 16));
FileWriteByte(quad & (255 << 24));

FileWriteString

void FileWriteString (int file, string s)

Writes a string to file as ascii with the length stored in a header

Example usage:

int file = FileOpen("datafile.txt", FILE_WRITE);
FileWriteString(file, "a");
FileClose(file);
// This creates/overwrites a file three bytes in size
// Opened in a hex editor the contents will be: '01 00 61'
// Which is the ascii code of a little a
// With two bytes before saying the string is length one
// Note the least significant bit comes first

int file = FileOpen("datafile.txt", FILE_WRITE);
FileWriteString(file, "A string here");
FileWriteString(file, "And another one");
FileClose(file);
// Because the length is stored before the characters
// You can write strings however, and still read back
// As distinct separate values

Pass a handle to a file that is opened in write mode, and a string to be written. The string is written from the current position in the file, overwriting any existing data. It uses a 1 byte ascii representation for each character, and writes a 2 byte string length before the start of the string - so bytes used is equal to len(s) + 2. By storing the length first like this, it is possible to use FileReadString() to read a string of abritary length back.

FileWriteVSP

void FileWriteVSP (int filehandle)

Saves the current VSP to the specified filehandle

Example usage:

int f = FileOpen("mytileset.vsp", FILE_WRITE);
if (f)
{
  FileWriteVSP(f);
  FileClose(f);
}
Writes the currently active VSP into a file handle open for writing. Fairly advanced, so this is only recommended if you plan on making a map editor within Verge or something.

FileWriteWord

void FileWriteWord (int file, int word)

Writes an integer to file as two bytes

Example usage:

int file = FileOpen("datafile.txt", FILE_WRITE);
FileWriteByte(file, 97); // or $61 or 'a'
FileClose(file);
// Opens/Creats a file and writes one byte to it
// Opened in a hex editor gives '61 00' as value of the byte
// In a text editor it gives the ascii 'a'

int file = FileOpen("datafile.txt", FILE_WRITE);
FileWriteByte(file, 0 - 2);
FileClose(file);
// Negative numbers are not stored properly
// Opened in a hex editor gives 'fe ff' as value of the byte
// -2 in binary: 11111111111111111111111111111110
// Two least significant bytes: 1111111111111110
// Decimal: 65534

Pass a handle to a file that is opened in write mode, and an integer to be written. Two bytes will be written at the current position within the file, over any data that was previously there, and position will move to the next byte. As only two bytes of the four bytes that make up a verge integer is being written, any numbers bigger than 65535 or less than 0 will NOT be written correctly. Use FileWriteQuad() unless sure the number being written will remain within these bounds.

Verge is effectivly only writing the 16 least significant bits of the passed integer, so performing a (integer & 65535) operation before writing. Numbers outside the range of 0 to 65535 will be written as another number with the range, depending on the value of the two least significant bytes. Note also that the bytes are stored in order of least significant to most significant. In effect what happens is:

FileWriteByte(quad & 255);
FileWriteByte(quad & (255 << 8));

ListFilePattern

string ListFilePattern (string file_pattern)

Searches for a specified file pattern and returns a list.

Example usage:

// Find every .png file in this directory!
Log(ListFilePattern("*.png"));

Searches for a specified file pattern and returns a list. This list is in string form, where every file is seperated by a | character. There is one extra | at the end of the string. Returns a null string "" on failure to find any files.

This does not appear to be able to search pakfiles and dwells in verge's platform-specific code.

Window Managment Functions

WindowClose

void WindowClose (int w)

Closes a window

Example usage:

int debugWindow=windowCreate(0,0,100,100,"Debug");
int debugImage=windowGetImage(debugWindow);
closeWindow(debugWindow);

printString(0,0,debugImage,0,"This is my debug window!"); //ERROR!!!
//why was there an error? BECAUSE THE WINDOW WAS CLOSED DAMMIT!
Closes window 'w'.

WindowCreate

int WindowCreate (int x, int y, int w, int h, string title)

Creates another window

Example usage:

int debug_window = WindowCreate(0, 0, 100, 100, "Debug");
int debug_image = WindowGetImage(debug_window);

PrintString(0, 0, debug_image, 0, "This is my debug window!");

Creates a window at (x,y) with width of w and height of h and a title of title, then returns its pointer.

Note: The window pointer is not the same as the image pointer. To write to the window image, you must use the WindowGetImage() function.

WindowGetHeight

int WindowGetHeight (int window)

Returns the height of the window.

Example usage:

int my_window = WindowCreate(0, 0, 320, 240, "MyWindow");
WindowGetHeight(my_window);
Returns the height of a window.

WindowGetImage

int WindowGetImage (int window)

Returns the image pointer for a window

Example usage:

int debug_window = WindowCreate(0, 0, 100, 100, "Debug");
int debug_image = WindowGetImage(debug_window);

PrintString(0, 0, debug_image, 0, "This is my debug window!");
Returns the image pointer for the specified window.

WindowGetWidth

int WindowGetWidth (int window)

Returns the width of the window.

Example usage:

int my_window = WindowCreate(0, 0, 320, 240, "MyWindow");
WindowGetWidth(my_window);
Returns the width of the window.

WindowGetXRes

int WindowGetXRes (int window)

Returns the horizontal resolution of the window's screen.

Example usage:

int my_window = WindowCreate(0, 0, 320, 240, "MyWindow");
int xres = WindowGetXRes(my_window);
Returns the horizontal resolution of the window's screen.

WindowGetYRes

int WindowGetYRes (int window)

Returns the vertical resolution of the window's screen.

Example usage:

int my_window = WindowCreate(0, 0, 320, 240, "MyWindow");
int yres = WindowGetYRes(my_window);
Returns the vertical resolution of the window's screen.

WindowHide

void WindowHide (int window)

Hides a window

Example usage:

int debug_window = WindowCreate(0, 0, 100, 100, "Debug");
int debug_image = WindowGetImage(debug_window);

// Now you see it!
PrintString(0, 0, debug_image, 0, "This is my debug window!");
// Now you don't! Muhaha!
WindowHide(debug_window);
// Wait... Now you do, again!
WindowShow(debug_window);
Hides the specified window, but does not close it. The window can be brought back with WindowShow().

WindowPositionCommand

void WindowPositionCommand (int window, int command, int arg1, int arg2)

Applies special window positioning logic

Example usage:

n/a
The only valid command is 0. the args dont do anything. I think this positions the specified window to the left of the main window. I think it was used for Pulser. You might not find it all that useful, but maube if you need different logic I can add it.

WindowSetPosition

void WindowSetPosition (int window, int x, int y)

Move a window to a specified position.

Example usage:

// The window is at (0,0)!
int debug_window = WindowCreate(0, 0, 100, 100, "Debug");
// The window is now at (100,100)!
WindowSetPosition(debug_window, 100, 100);

WindowSetPosition moves a given window to the specified coordinates. The (x, y) coordinates are the position of the upperleft corner of the window relative to the screen the window is being displayed on.

WindowSetResolution

void WindowSetResolution (int window, int xres, int yres)

Sets the resolution of the specified window.

Example usage:

WindowSetResolution(debug_window, 320, 240); // Winners use 320x240!

Sets the resolution of the specified window. Differs from WindowSetSize, in that only the width and height of the screen are required.

WindowSetSize

void WindowSetSize (int window, int width, int height)

Sets the size of the specified window.

Example usage:

WindowSetSize(debug_window, 546,  242); // What a bizarre window size!

Sets the size of the specified window. Differs from WindowSetResolution, in that you need to account for the width and height of the panels surrounding the window as well.

WindowSetTitle

void WindowSetTitle (int window, string title)

Set the new title for a window

Example usage:

int debug_window = WindowCreate(0, 0, 100, 100, "Debug");
int debug_image = WindowGetImage(debug_window);

PrintString(0, 0, debug_image, 0, "This is my debug window!");

WindowSetTitle(debug_window, "Not my debug window");

RectFill(0, 0, 100, 100, 0, debug_image);
PrintString(0, 0, debug_image, 0,"This is NOT my debug window... Really.");
Set title of a specified window to a specified title.

WindowShow

void WindowShow (int window)

Makes a specified hidden window become visible.

Example usage:

int debug_window = WindowCreate(0, 0, 100, 100, "Debug");
int debug_image = WindowGetImage(debug_window);

// Now you see it!
PrintString(0, 0, debug_image, 0, "This is my debug window!");
// Now you don't! Muhaha!
WindowHide(debug_window);
// Wait... Now you do, again!
WindowShow(debug_window);
Makes a specified hidden window become visible.

Movie Playback Functions

Movies are complicated things in windows. You can't just take any old movie file and throw it in a game and expect it to work on other people's systems. Besides that, it is rude to put a big movie file in a game. Most people will reflexively hit ESC anyway because thats what they are accustomed to doing when assaulted with an FMV. However, movie functionality is provided for those who have some legitimate need for it. BUT YOU MUST FOLLOW THESE RULES:

DO NOT USE DIVX OR XVID OR MPEG2. These codecs do not come with windows, and the player might not have installed them manually. Use cinepak, indeo, video-1, or even RLE. The compression might be cruddy, but at least it will work.

If you are thinking about making a video an integral part of your game, you MUST CONTACT ME to discuss it so I can help you make sure you're doing it right. If you are including a video for some lame purpose like an intro screen are something then I suggest that you not do it, and if you must indeed do it then I suggest that you contact me to get advice on doing it right.

Even the basic codecs (including cinepack) might not be installed on Windows server platforms. I know for a fact they dont work on my Windows 2003 at the office.

There are basically two modes to movie playback--simple and advanced. Simple mode consists of PlayMovie, which will just play a movie fullscreen through to completion and is suitable for intro movies and such. Advanced mode uses MovieLoad to load the movie and MovieClose to close it and is split into two use cases:

  • MoviePlay/MovieGetImage which will play a movie through to completion but allow you to control the rendering of the movie via MovieGetImage and your own calls to blit(), etc. --and
  • MovieSetFrame/MovieNextFrame/MovieSetFrame which will let you zip around in a movie and pick the frames you want. MovieRender will have to be used to decode the movie after youve skipped around (..i think.)

There are a few other functions which you may find useful

There are likely horrible synchronization bugs in the movie code. If youre using it and run into problems, we'll see what we can do to straighten it out.

AbortMovie

void AbortMovie ()

(simple) Aborts a movie played by PlayMovie

Example usage:

adaw
You should call this from a hooktimer or a hookkey--how else would you do it?

MovieClose

void MovieClose (int movie_handle)

(advanced) Closes a movie handle previously opened by MovieLoad

Example usage:

adawdaw
Try not to close the handle more than once or do other similarly reprehensible misdeeds

MovieGetCurrFrame

int MovieGetCurrFrame (int movie_handle)

(advanced) Returns the current frame index of a movie

Example usage:

awd
The description says it all.

MovieGetFramerate

int MovieGetFramerate (int movie_handle)

(advanced) Returns the framerate of the movie

Example usage:

awd
Currently, this framerate is illogical gibberish. Soon, this framerate will be accurate and in 16.16 fixed point.

MovieGetImage

int MovieGetImage (int movie_handle)

(advanced) Gets an image handle for the current movie frame

Example usage:

awd
This image handle contains the current decoded movie frame. I think it will always be up to date if you are using MoviePlay and not up to date if you are using the frame cursor manipulation methods, but I'm not 100% sure of that. You should not free this image handle!!!! That's one thing I am sure about.

MovieLoad

int MovieLoad (string avifile, int muted)

(advanced) Load a movie file for later use

Example usage:

awdaw
Returns a handle to the opened movie file. If you want to play the movie two different ways concurrently, you had better get two handles. Passing 1 for muted will cause the movie file to shut up.

MovieNextFrame

void MovieNextFrame (int movie_handle)

(advanced) Advances the movie to the next frame

Example usage:

awd
a

MoviePlay

void MoviePlay (int movie_handle, int loop)

(advanced) Starts playing a movie handle

Example usage:

awd
This function does not draw the movie anywhere on the screen. That is up to you, using MovieRender or MovieGetImage. So, this function just keeps an internal timer and progresses the movie at the correct rate. Passing a 1 for loop will make the movie.... loop. The odd thing is, I'm not quite sure how you stop the movie once you play it with this method. I'm sure someone will need that some day. I'm sure someone will be glad to add it.

MovieRender

void MovieRender (int movie_handle)

(advanced) Internally decodes the current frame of the movie

Example usage:

awd
When you think it is time to decode a frame of the movie, use this function to do it. You will have to get access to the decoded frame via MovieGetImage. I think you only have to do this when you use the frame cursor manipulation functions. MoviePlay might render automatically. This function tries not to do work it doesn't need to do. You can call it excessively and if nothing has changed, it won't do anything.

MovieSetFrame

void MovieSetFrame (int movie_handle, int frame)

(advanced) Moves the movie to the specified frame

Example usage:

awd
a

PlayMovie

void PlayMovie (string avi)

(simple) Plays a movie fullscreen

Example usage:

PlayMovie("lame_movie.avi"); //lame refers to the use of movies
NODE

Netcode Functions

Connect

int Connect (string hostname)

Attempts to connect to the specified server host.

Example usage:

int mysock = Connect("127.0.0.1");
Tries to connect to a socket on a specified host server.

GetConnection

int GetConnection ()

Listens for new connections

Example usage:

int i = GetConnection();
if (socket_count < SOCKET_MAX_COUNT)
{
  socket[socket_count] = i;
  SocketSendString(i, "RPL_CONNECTIONOK");
  Log("A new client connected via socket "+str(i));
  socket_count++;
}
else
{
  SocketSendString(i, "ERR_SERVERFULL");
  Log("Socket "+ str(i) +" was refused a connection, because the server's full.");
  SocketClose(i);
}
Checks for new connections at port 45150. Intended for server code. If you encounter problems, it's likely you need to open port 45150 on your firewall or router.

GetUrlImage

int GetUrlImage (string url)

Connects to a URL and returns an image.

Example usage:

void AutoExec()
{
  // Get a picture of Grue wearing a Verge T-Shirt. Bleh.
  int img = GetUrlImage("http://www.verge-rpg.com/images/store/shirt_00_sidebar.jpg");


  Blit(0, 0, img, screen);
  while(1)
  {
    ShowPage();
  }
}

Attempts to connect to the a given URL, and downloads and returns an image pointer. If it fails, the pointer will be 0 VERGE will totally crash!

GetUrlText

string GetUrlText (string url)

Return text from a specified URL

Example usage:

// Log the current VergeC functions from vecna's website.
Log (GetUrlText("http://vecna.verge-rpg.com/v3vergec.txt"));

string username, password;
// Advanced Functionality: Send username and password.
if (!strcmp(GetUrl("http://127.0.0.1/login.php?username="+username+"&password="+password), "Okay, you've connected successfully.")
{
  // Let the clients who successfully login continue.
  SocketSendString(i, "RPL_LOGINSUCCESSFUL");
}
else
{
  // Disconnect clients who fail at the login.
  SocketSendString(i, "ERR_LOGINFAILURE");
  SocketClose(i);
}

Attempts to connect to the a given URL, and returns the contents. If it fails, it will instead return that site's Error 404 (File not Found) message. Could possibly be used in conjunction with a PHP-enabled page, allowing cool stuff like a dynamic online high-score chart, or something. Also, I'm guessing if a webhost is completely down, Verge will crash hard.

SocketClose

void SocketClose (int socket)

Terminates a socket connection.

Example usage:

// Disconnects every socket.
for (i = 0; i < socket_count; i++)
{
  SocketSendString(i, "SERVER_KILL");
  SocketClose(i);
}

Used by the server to end client connections to the server. This is useful to free disconnected sockets, and also restrict connections when the server becomes busy.

SocketConnected

int SocketConnected (int socket)

Verifies sockets for connection.

Example usage:

if (!SocketConnected(i))
{
  SocketClose(i);
}

Checks to see if a socket index is connected to the server. This is useful in order to free inactive clients from a server.

Note: This doesn't always work (in fact, most of the time SocketConnected() doesn't do the job), so you may want to implement some sort of "heart-beat" signal that must be received within a certain amount of time, or else the client will be disconnected.

SocketGetFile

string SocketGetFile (int socket, string ovfname)

Gets a file from the specified socket.

Example usage:

// Parse the command.
string s = SocketGetString(server_sock);
if (!strcmp(s, "FILE"))
{
  // Get the file name.
  s = SocketGetString(server_sock);
  // Retrieve the file.
  SocketGetFile(server_sock, "download/"+s);
}

Retreives an expected incoming file from the server.

SocketGetInt

int SocketGetInt (int socket)

Gets an integer from the specified socket.

Example usage:

int myint = SocketGetInt(server_sock);

Retreives an expected incoming integer from a socket. It's recommended that you usually send all information in the form of strings to avoid problems.

SocketGetString

int SocketGetString (int socket)

Gets a string from the specified socket.

Example usage:

string s;
if (SocketHasData(server_sock))
{
  s = SocketGetString(server_sock);
  ParseCommand(s);
}

Attempts to retrieve a string from the given socket. Useful in conjunction with SocketHasData(). You will want a create parser to interpret incoming string commands and reply according to each command.

SocketHasData

int SocketHasData (int socket)

Checks for data in the specified socket.

Example usage:

// If new data is found, grab it and add it.
if (SocketHasData(socket))
{
  text = SocketGetString(socket);
  TextBoxAddLine(text);
}
Checks to see if new data is available to interpret in the supplied socket. Returns 0 if false.

SocketSendFile

void SocketSendFile (int socket, string fname)

Sends a file to the specified socket.

Example usage:

int myfile = "dennis.png";
SocketSendString(i, "DOWNLOAD "+myfile); // Heads up, dude! We're totally sending you a file.
SocketSendFile(i, myfile); // Now download it!

Sends a file to the specified socket. It's recommended you give the client a good heads-up message before you just bombard them with a file. Note that this ties up the server the whole time the file's being sent, so be careful how you use it.

SocketSendInt

void SocketSendInt (int socket, int i)

Sends an integer to the specified socket.

Example usage:

SocketSendInt(i, 42);

Sends an integer to the specified socket. It's recommended you send strings, not integers to clients, but nobody's stopping you from sending ints.

SocketSendString

void SocketSendString (int socket, string str)

Sends a string to the specified socket.

Example usage:

// Some mean person abusing admin powers sends a KICKBAN message to the server to terminate Overkill's connection.
// (Losers like him take up all his bandwidth.)
SocketSendString(socket, "KICKBAN Overkill < Losers like him take up all my bandwidth.");

Sends a string from the remote server to the local client, or from the local client to the remote server. Has many uses, from error messages, to text messages, to special commands.

Global Variables

Some of these variable can be written to, some cannot. It's not always immediately obvious which. If you get a "Unknown HVAR1" type of error, it's probably because you a trying to assign to a read-only variable.

General System Variables

int screen; // this is a hardcoded image handle for the screen
int systemtime; // read-only timer variable constantly increasing
int timer; // read/write timer variable
int key[scancode]; // read/write key-state array
int lastpressed; // read/write scancode of last pressed key
int lastkey; // read/write last key pressed in ASCII
int window.active; // read-only, whether or not the game window in focus. 
To elaborate:
screen - Is a pointer to a bitmap of the screen's current dimensions (set in v3.cfg or by SetResolution() function at runtime). Anything you want to appear in ther verge window should be blitted here with one of the graphics functions. When ShowPage() is called the screen bitmap is transfered to the display.

systemtime - A read-only timer that stores the time elapsed since your program began, in centiseconds. Not to be confused with the time stored on your system clock. If you want to know what the current time settings are on a computer, see the Date/Time variables instead.

timer - A number than increases by 100 every second and very useful for anything you need to happen within a set timeframe. As you can re-set this value whenever you like, it's also possible to use it to work out how long ago something happened.

key[scancode] - Stores whether a key IS CURRENTLY PRESSED - so if the key was down the last time ShowPage() or UpdateControls() was called. If you want to use is like a HAS BEEN PRESSED state, you'll need to reset the value back to 0 each time manually. Unlike standard ASCII methods key['a'] will not work - verge has its own defines, look at the Scan Codes section to see them.

lastpressed - Stores the verge scancode of the last keyboard key the player pressed. See Scan Codes.

lastkey - Same as above, but stores proper ASCII, so 'a' = 97 = little a

window.active - Used to tell if the Verge game window is in focus or if the user minimized/alt-tabbed out of it for a second. Useful for stuff like pausing gameplay while inactive to go easier on the CPU.

Mouse Variables

int mouse.x, mouse.y;
int mouse.l, mouse.m, mouse.r;
int mouse.w;

mouse.x, mouse.y - The current coordinates of the mouse.

mouse.l, mouse.m, mouse.r - The left, middle, or right mouse buttons' status. [read/write]

mouse.w - The value of the mouse wheel. Has strange values, usually in increments of 120 with default mouse settings. [read/write]

When using the mouse variables, keep in mind they correspond to the position of the V3 screen.

FUSSUSUSUUSUSUSUSUUEROPHOGUS

void FUSSUSUSUUSUSUSUSUUEROPHOGUS (FUSSUSUSUUSUSUSUSUUEROPHOGUS)

FUSSUSUSUUSUSUSUSUUEROPHOGUS

Example usage:

FUSSUSUSUUSUSUSUSUUEROPHOGUS
FUSSUSUSUUSUSUSUSUUEROPHOGUS

Joystick Variables

int joystick;
int joy.active;
int joy.up;
int joy.down;
int joy.left;
int joy.right;
int joy.analogx;
int joy.analogy;
int joy.button[button];

joystick - Current joystick index for joy.* struct. [read/write]

joy.active - Whether or not the joystick's connected and active. [0/1]

joy.up, joy.down, joy.left, joy.right - Whether or not joystick's in "up", "down", "left", or "right" position, respectively [0/1]

joy.analogx - Analog position of joystick x-axis. (-1000 max left, 0 center, +1000 max right)

joy.analogy - Analog position of joystick y-axis. (-1000 max up, 0 center, +1000 max down)

joy.button[button] - Whether or not a button is pressed (buttons 0 to 31 are valid) [0/1].

Entity Variables

For the corresponding entity functions go here

int entities;
int entity.x[entity];
int entity.y[entity];
int entity.specframe[entity];
int entity.frame[entity];
int entity.hotx[entity];
int entity.hoty[entity];
int entity.hotw[entity];
int entity.hoth[entity];
int entity.movecode[entity];
int entity.face[entity];
int entity.speed[entity];
int entity.visible[entity];
int entity.obstruct[entity];
int entity.obstructable[entity];
string entity.script[entity];
string entity.chr[entity];
int entity.lucent[entity];
int entity.framew[entity], entity.frameh[entity];
string entity.description[entity];

entities - (read only) The number of entities currently on the map. Use this an the upper bound any time you need to loop through and check entites for something.

entity.x, entity.y - (read/write) The coordinates of the entity on the map. This is a pixel value from the top left corner of the map to the top left corner of the entity's hotspot. To get an x,y coord of the entity on the screen subtract xwin and ywin.

entity.specframe - (read/write) Similar to setting a z movecode, this sets a frame to display. Remember to set it back to 0 if you want movement animations.

entity.frame - (?read only?) ?Just stores the entities current frame?

entity.hot(x/y/w/h) - (read only) These four variables specify a rectangle on the entity's frame used for collision detection, x,y coords from the top left corner of the frame, width and height. They are read-only. Why, I don't know. You'll need to set them in the .mak when you create your .chr file.

entity.movecode - (read only) reflects the current wandermode of the entity. 0 is not moving, 1 is wander zone, 2 is wander rect, and 3 is movecode. Attempting to setting this variable manually will crash the system, so if you want to change the wandermode, please use one of the following functions: EntityStop(), EntitySetWanderZone(), EntitySetWanderRect(), or EntityMove().

entity.face - (read/write) Returns a number that corresponds to the direction the entity is facing. Changing this will change the direction the entity is facing. Setting it to an invalid value can crash the system.

      (up) 1
           |
(left) 3 --+-- 4 (right)
           |
           2 (down)           

entity.speed - (read/write) how fast this entity will move, in pixels per second (PPS). If you want an entity to crawl aroud at a tile per second (really slow) set this to 16. We commonly set it to 100 or so, although 128 may be a better 'normal speed' for characters.

entity.visible - (read/write) [NEW!] Whether or not the entity will be drawn to the screen. A little testing seems to show it affects BlitEntityFrame() as well as Render() and 0 is invisible.

entity.obstruct - (read/write) 1 if the entity's hotspot is an obstruction, 0 if not.

entity.obstructable - (read/write) 1 if this entity cares about obstructions when moving, 0 if not.

entity.script - (read/write) The movescript currently used by this entity. See EntityMove() for more details.

entity.chr - (read/write) Added to allow read/write access to the CHR for entities. Setting it is the same as ChangeCHR()

entity.lucent - (read/write) The lucency percentage of the entity, 0 is opaque, 100 is invisible.

entity.frame[w/h] - (read-only) The width/height of each frame in the CHR file.

entity.description (read/write) Information about this sprite, usually used in MapEd, to help you figure out which entity is which. You could possibly use the entity's description to locate specific entities on the map by their description instead of an arbitrary index number.

Sprite Variables

For the corresponding sprite functions go here

At the moment, the sprite system is unfinished and basically unusable. Nonetheless, it's there if you want it. In a future build, many more features will be added.

int sprite.x[sprite], sprite.y[sprite];
int sprite.sc[sprite];
int sprite.image[sprite];
int sprite.lucent[sprite];
int sprite.alphamap[sprite];
int sprite.addsub[sprite];
string sprite.thinkproc[sprite];
int sprite.thinkrate[sprite];
int sprite.ent[sprite];
int sprite.silhouette[sprite];
int sprite.color[sprite];
int sprite.wait[sprite];
int sprite.onmap[sprite];
int sprite.layer[sprite];
int sprite.timer[sprite];

sprite.x, sprite.y - The position of the sprite. Depending on other settings, this may be relative to the screen, the map, an entity or even something else.

sprite.sc - If set to 1, the sprite's (x, y) will be a position on the screen. If set to 0, the sprite's position is relative to the map.

sprite.image - When assigned a value other 0, a sprite is considered "active". Otherwise, any sprite with the number 0 for an image could be returned by GetSprite(). The sprite's image must be a valid image reference. The image assigned is the image that will be displayed.

sprite.lucent - The transparency amount for the sprite. [0-100]

sprite.addsub - Determines whether to blit a sprite normally, additively, or subtractively. (-1 = subtractive, 0 = normal, 1 = additive)

sprite.alphamap - If this is 0, the sprite is drawn normally. Otherwise, it takes a valid greyscale image reference as an alpha map and AlphaBlits accordingly. Note that this has priority over additive/subtractive/normal blitting when set.

sprite.thinkrate - The delay, in ticks, between each call to a sprite's "think" procedure.

sprite.thinkproc - The function for Verge to call every time a sprite gets updated.

sprite.xflip - Whether or not to flip the sprite horizontally. (not sure this was implemented)

sprite.yflip - Whether or not to flip the sprite vertically. (not sure this was implemented)

sprite.yflip - Whether or not to flip the sprite vertically.

sprite.ent - If this number isn't -1, it specifies the entity index to attach the sprite to. All x, y becomes relative to the sprite's hotspot.

sprite.silhouette - Whether or not to draw a the sprite as a silhouette.

sprite.color - What color to draw the silhouette, if the sprite is being drawn as one.

sprite.wait - The delay before this sprite appears on screen and begins to be processed. Defaults to 0, which is instantly after they're made. Useful for queueing sprite events in advance.

sprite.onmap - Whether or not this entity is bound to a map layer

sprite.layer - If map-bound: The layer to be drawn above. If entity-bound: 0 = below ent, 1 = above ent. Otherwise, does nothing.

sprite.timer - Duration that this sprite has been active.

Stay tuned for more!

Camera Variables

int xwin, ywin;
int cameratracking, cameratracker;

xwin, ywin - The position of the camera in pixels.

cameratracking - Alters behaviour of the camera. (See below)

cameratracker - An entity index for the camera to follow, even if this entity isn't the player. (See below)

The camera variables are used to control where on the map the screen is looking. By default cameratracking is set to 1, which means the screen will follow the current player entity around as they move. The xwin and ywin hold the top left corner of the screen position in map (x, y) pixel coordinates, and will update to keep the player in the center of the screen on each Render().

Setting cameratracking to 0 turns off this behavior, so you can manually set the xwin and ywin values, and verge will abide by them.

Setting cameratracking to 2 makes the camera follow the target of the cameratracker instead, a reference to a valid entity index which you want the camera to follow.

Map Variables

int curmap.w;
int curmap.h;
int curmap.startx;
int curmap.starty;
int curmap.tileset;
string curmap.name;
string curmap.rstring;
string curmap.music;
string curmap.path;

curmap.w, curmap.h: The width and height of the current map, in tiles.

curmap.startx, curmap.starty: The starting tile coordinate, specified in Maped3. EntitySpawn(curmap.startx, curmap.starty, "mygamehero.chr"); for the win!

curmap.tileset: An image handle to the current map VSP, that you CAN draw to (the image will be 16 pixels wide and 16*numtiles tall). You could duplicate this image a bit, to have the original untouched tileset, and ColorFilter()'d duplicates, that's blit over curmap.tileset to cause things like day-night effects. Neat!

curmap.name: The name of the current map, specified in Maped3. Not to be confused with its filename, curmap.path.

curmap.rstring: Sets the renderstring for the current map. This is in the format "1,2,3,E,4,5,R" - but you can have whatever you want basically. Putting multiple R characters in is useful, that way you can draw between several different layers: use HookRetrace() at the end of each function to specify the next one, or handle in one function with conditionals.

curmap.music: The song that is played upon starting the map. Useful if you temporarily switch the song for a cutscene and then want to switch back the map's default.

curmap.path: The path and filename of the current map, relative to the Verge directory.

Layer Variables

int layer.visible[layer];
int layer.lucent[layer];
int layer.parallaxx[layer], layer.parallaxy[layer];
int layer.w[layer], layer.h[layer];

layer.visible - Toggles visibility of a layer. [0/1].

layer.lucent - Sets the lucency value of a layer. Just as with lucent blits, 100 is completely transparent and 0 is fully opaque.

layer.parallaxx, layer.parallaxy - Affects the parallax settings of layer. In 16.16 fixed point notation.

layer.w, layer.h - Gets the width and height of a specific layer in tiles.

Zone Variables

string zone.name[zone];
string zone.event[zone];

zone.name - The name of a particular zone on the map. [read-only]

zone.event - The name of the function to be called when the zone is activated (by walking over it, or adjacent activation) [read-only]

Event Variables

int event.tx, event.ty;
int event.zone;
int event.entity;
int event.param;

event.tx, event.ty - Triggering tile coordinates of this event, if applicable.

event.zone - Triggering zone of an event.

event.entity - Refers to the entity who triggered the event as well as the entity being rendered when hooking an entity render.

event.param - Parameter meant to be defined in maped next to the entity or zone's script name. currently unimplemented in the editor.

Date/Time Variables

int sysdate.year;
int sysdate.month;
int sysdate.day;
int sysdate.dayofweek; 

int systime.hour;
int systime.minute;
int systime.second;

sysdate.year - The year according to the system clock.

sysdate.month - The month according to the system clock.

sysdate.day - The day according to the system clock.

sysdate.dayofweek - The day of the week according to the system clock (0 = Sunday, 1 = Monday, ...6 = Saturday).

systime.hour - The hour in military time according to the system clock.

systime.minute - The minute according to the system clock.

systime.second - The second according to the system clock.

Clipboard Variables

string clipboard.text;

clipboard.text - A read-write variable that stores the text currently in the clipboard. Allows you to copy from outside applications and paste into Verge, and vice versa.

Trigger Variables

Trigger Variables are global system-event-based callfunction triggers. If they are blank, or if they are set to a string that isn't a vc function name, nothing happens. But if they are set to a vc function name, awesome magic happens!

trigger.onStep
trigger.afterStep
trigger.beforeEntityScript
trigger.afterEntityScript

The Step Triggers

If trigger.onStep is set to a vc function name, that function will be called everytime the player entity crosses a zone activation border, regardless of if a zone is about to be activated. If a zone will be activated, this function occurs right before that zone's script goes off.

If trigger.afterStep is set to a vc function name, that function will be called everytime the player entity crosses a zone activation border, regardless of if a zone is about to be activated. If a zone was activated, this function occurs right after that zone's script goes off.

Both trigger.onStep and trigger.afterStep's assigned vc functions will have access to a proper event.tx and event.ty, regardless if a zone gets activated. Note that this is a change in behavior, as event.tx and event.ty are now updated at a new point. If this breaks anyone's day, please let me know.

These two triggers are good for things like dealing with poison and tintinabar-style effects and step counters, which are more dependant on the act of walking than on any specific zone. I was brought to implement this specifically because there was no good way to deal with decrementing the "steps to battle" counter for Sully, and this seemed like an idea whose time had come.

The Entity Activation Triggers

If trigger.beforeEntityScript is set to a vc function name, that function will be called before any entity's onActivate script is called.

If trigger.afterEntityScript is set to a vc function name, that function will be called after any entity's onActivate script is called.

Both trigger.beforeEntityScript and trigger.afterEntityScript's assigned vc functions will have the proper event.tx, event.ty, and event.entity values available to them, just like the entity's onActivate script does.

These two triggers are great for handling universal pre- and post-conditions for entity onActivate events. Specifically, in Sully it was getting tiresome to have to tell the game to forbid the menu as the first line of every entity's onActivate script, and it was getting tiresome to tell the game to re-allow menus afterwards. If you forgot any of these, you basically created a gameplay bug! Awesome, eh?

Built-in Defines

For information on the nature of the built-in defines, read the Preprocessor directives section of the manual.

Version

_version is a builtin define that will return, in string format, the version of verge you're currently running.

_build is a builtin integer in the form of YYYYMMDD of the build's release.

_os is a builtin that returns a string of either "mac" or "win".

Scan Codes

Verge doesn't use ASCII for reading and comparing keyboard input, but instead uses the keyboard scan codes instead. You will generally only use the scan codes when reading lastpressed or the key array.
EX:

if(key[SCAN_ESC]) exit("");
else if(key[SCAN_ENTER]) map("town.map");

or

switch(lastpressed){
case SCAN_EXIT: exit("");
case SCAN_ENTER: map("town.map");
}

from vergec.txt:
{"SCAN_ESC", "01" }
{"SCAN_1", "02" }
{"SCAN_2", "03" }
{"SCAN_3", "04" }
{"SCAN_4", "05" }
{"SCAN_5", "06" }
{"SCAN_6", "07" }
{"SCAN_7", "08" }
{"SCAN_8", "09" }
{"SCAN_9", "10" }
{"SCAN_0", "11" }
{"SCAN_MINUS", "12" }
{"SCAN_EQUALS", "13" }
{"SCAN_BACKSP", "14" }
{"SCAN_TAB", "15" }
{"SCAN_Q", "16" }
{"SCAN_W", "17" }
{"SCAN_E", "18" }
{"SCAN_R", "19" }
{"SCAN_T", "20" }
{"SCAN_Y", "21" }
{"SCAN_U", "22" }
{"SCAN_I", "23" }
{"SCAN_O", "24" }
{"SCAN_P", "25" }
{"SCAN_LANGLE", "26" }
{"SCAN_RANGLE", "27" }
{"SCAN_ENTER", "28" }
{"SCAN_CTRL", "29" }
{"SCAN_A", "30" }
{"SCAN_S", "31" }
{"SCAN_D", "32" }
{"SCAN_F", "33" }
{"SCAN_G", "34" }
{"SCAN_H", "35" }
{"SCAN_J", "36" }
{"SCAN_K", "37" }
{"SCAN_L", "38" }
{"SCAN_SCOLON", "39" }
{"SCAN_QUOTA", "40" }
{"SCAN_RQUOTA", "41" }
{"SCAN_LSHIFT", "42" }
{"SCAN_BSLASH", "43" }
{"SCAN_Z", "44" }
{"SCAN_X", "45" }
{"SCAN_C", "46" }
{"SCAN_V", "47" }
{"SCAN_B", "48" }
{"SCAN_N", "49" }
{"SCAN_M", "50" }
{"SCAN_COMMA", "51" }
{"SCAN_DOT", "52" }
{"SCAN_SLASH", "53" }
{"SCAN_RSHIFT", "54" }
{"SCAN_STAR", "55" }
{"SCAN_ALT", "56" }
{"SCAN_SPACE", "57" }
{"SCAN_CAPS", "58" }
{"SCAN_F1", "59" }
{"SCAN_F2", "60" }
{"SCAN_F3", "61" }
{"SCAN_F4", "62" }
{"SCAN_F5", "63" }
{"SCAN_F6", "64" }
{"SCAN_F7", "65" }
{"SCAN_F8", "66" }
{"SCAN_F9", "67" }
{"SCAN_F10", "68" }
{"SCAN_NUMLOCK","69" }
{"SCAN_SCRLOCK","70" }
{"SCAN_HOME", "71" }
{"SCAN_UP", "72" }
{"SCAN_PGUP", "73" }
{"SCAN_GMINUS", "74" }
{"SCAN_LEFT", "75" }
{"SCAN_PAD_5", "76" }
{"SCAN_RIGHT", "77" }
{"SCAN_GPLUS", "78" }
{"SCAN_END", "79" }
{"SCAN_DOWN", "80" }
{"SCAN_PGDN", "81" }
{"SCAN_INSERT", "82" }
{"SCAN_DEL", "83" }
{"SCAN_F11", "87" }
{"SCAN_F12", "88" }


Be warned that the values for Insert, Delete, Home, End, PgUp and PgDown listed here are for the numpad keys. The "real" versions are 210 (INSERT), 211 (DELETE), 199 (HOME), 207 (END), 201 (PGUP), and 209 (PGDN). You will need to define these yourself if you want to use them without entering the values directly.

Color Filters

The defines are for use with:
void ColorFilter(COLOR_FILTER filter, int image)

Applies the specified filter to the given image. The following filters are valid:

CF_NONE does absolutely nothing!
CF_GREY converts the image to greyscale
CF_GREYINV converts the image to inverted greyscale.
CF_INV converts to full-color RGB inversion. For instance, the inverse of green would be purple: RGB(0,255,0) -> RGB(255,0,255).
CF_RED gets an average luminosity and then applies that to the red channel only.
CF_GREEN gets an average luminosity and then applies that to the green channel only.
CF_BLUE gets an average luminosity and then applies that to the blue channel only.
CF_CUSTOM uses a user defined color filter set with SetCustomColorFilter(int c1, int c2).
Example:
colorFilter(CF_BLUE, screen); // This will convert the screen image to a full blue-scale image

To see the greyscale filter in action, and how it differs from other methods this program is a good demonstration.

Two notes about this function. It will abide by the clipping region, but you will not gain the full speed benefit of a clip region. This may be optimized in the future. It will abide by Lucency values: you can acheive some cool effects this way. For instance a lucent percentage of a CF_GREY filter will provide a washed-out, color-faded look.

Lua

Verge 3.1 now has support for an alternate scripting engine: Lua

You will enable lua by putting this in verge.cfg:

lua 1
Then make system.lua and bumsville.lua (for map scripts)

I'll be releasing some kind of tiny demo to show you the ropes. Be forewarned that it's not tested very well; but I will be paying close attention to it for a while, and will interact with anyone trying to use it.

When using Lua you might find that the verge.exe mysteriously exits with no interesting feedback. Lua error handling is weird; I havent sorted it all out yet. It will improve.

I have taken great pains to reproduce a VC-style environment within Lua. All the global system variables and functions are there, with practically identical syntax. There are some exceptions:

  • it would be entity[0].x (as opposed to entity.x[0] in verge)
  • there is no `joystick`. you access it with joy[joynum].up
  • in a few places where it makes sense, I am using bools instead of ints.

    I have probably screwed up a few of the bindings. Do you have any idea how many functions and variables verge has!?! To make matters worse, a lot of the logic was mixed in with VC code which I had to refactor. So, I probably made a few mistakes. Let me know if you spot one.

    I made a peculiar decision and decided to reimplement VC quite directly. This means integer image handles and no floating point numbers, etc. The purpose for this was to get the code out there faster. I'll figure out some way to start improving it later. maybe a verge.cfg "lua 2" will enable alternate (and more sane apis). Of course, lua has its built-in math stuff, including floating point stuff, so perhaps that will tide you over.

    Be forewarned that right now, when you 'compile' a map's script with lua, the raw script is concatenated to the .map file. Its not really compiled. This may change.

    I have implemented the system<->map script interaction by simply running the map script whenever the map loads. In lua, 'running' script means that all of the functions will be stuffed into the global namespace. On top of whatever was already there. Which means, remnants of your last map's code will still be available (unless overwritten with functions from the new map). This is a bit sloppy.. but it is powerful. Much like lua itsself!

    Note that it is possible for you to define a function with a certain name in a map script which exists also in your system scripts. That would cause your system script to be permanently overwritten. Be cautious!

    -- zeromus

    Appendix

    The History of Verge

    1. Verge
    2. Verge2
    3. Much lameness
    4. Verge3

    Archived Related Sites


    Originally compiled by rpgking:

    Main Verge Pages


    The Original Verge Page from '97(press CTRL+A to read everything)

    (The Moria Page disappeared without a trace...)

    Verge-RPG.com from '00(site redesign announced)

    Earliest available page of previous Verge-RPG design

    The Verge Source(near its end...LOTS of working links)

    Verge Repository

    Various Old Verge Message Boards(even I make an appearance on these :O)
    Board 1
    Board 2

    locke announces the Repo closing

    FAN PAGES

    Verge Web Ring

    Tarkuss' Galaxy Destroyer(noticed some working links)

    Revelation(Falthorn)

    Verge Mag(Jyrus)

    Final Fantasy: War of the Four Crowns(Jyrus)

    Sheng Long Gradilla's World

    Castles' Homepage(Hyped up a vaporware FF6 battle system...screenshots here)

    Gurv's Page(not too many links work)

    Verge Quick Reviews(Wyrdwad)

    Hypno's Verge Music Guild

    #verge Stupid Quotes(Sir Clay)

    Animesoft(last incarnation)

    Azure Software(Wooly)

    Beyond Eternity: Ascension(Lady Starmage) - has working links to her artwork

    Half-assed reviews(Lady Starmage)

    Zal's Battle System Alliance

    TWiG(Wyrdwad)

    Revelation Fan Page

    Credits

    original verge3 and Xerxes engine:
      Benjamin "vecna" Eirich
      
    Macintosh port and misc new features:
      Jesse Rusak
      
    Miscellaneous code:
      Matthew "zeromus" Gambrell
      Shamus "Kildorf" Peveril
      Charles "aen" Rector
      
    Original V3 Logo design by:
      Jeff "Toen" Hutchins
    
    "Mac" V3 Logo design by:
      Jon "evilbob" Wofford
      
    Icon design:
      Aaron Scott Hildebrandt
      
    This list is not exhaustive.
    
    No clams were harmed in the making of verge 3.
    

    License

    Copyright (c) 1997-2005, Benjamin Eirich (vecna).
      Additional code by:
        Jesse Rusak [mac port]
        Matthew Gambrell (zeromus) [misc code contributions]
        Charles Rector (aen) [misc code contributions]
        Shamus Peveril (Kildorf) [misc code contributions]
        Andrew G. Crowell (Overkill) [misc code contributions]
    
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without modification, 
    are permitted provided that the following conditions are met:
    
    * Redistributions of source code must retain the above copyright notice, this 
    list of conditions and the following disclaimer. 
    
    * Redistributions in binary form must reproduce the above copyright notice, 
    this list of conditions and the following disclaimer in the documentation 
    and/or other materials provided with the distribution. 
    
    * Neither the name of VERGE-RPG.COM nor the names of its contributors may be
    used to endorse or promote products derived from this software without specific
    prior written permission. 
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    Utilizes FLAC 
    Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
    

    Colophon

    The Paradise Isle Matriculated Monovalve

    The clam on the cover is the endangered, yet resilient Paradise Isle Matriculated Monovalve. This much-sullied clam has been blamed of every malady in the Paradise Isle and Lesser Vicaria regions from clogging water lines and polluting water supplies to supplying plucky adventurers with tools to further their quest. Although it's population is in the low odd prime numbers, we still reserve hope that with proper care the species can make a recovery.