AGIWiki/Creating an AGI Game

From ScummVM :: Wiki
< AGIWiki
Revision as of 08:21, 19 May 2012 by Sact (talk | contribs) (syntax indeed)
Jump to navigation Jump to search
AGIWiki


NOTE: This text, originally by Rainer De Temple

Part 1

Introduction

By now no doubt you know what AGI is and you have downloaded AGI Studio by Peter Kelly. This tutorial or introduction to AGI game editing will show those who have little or no programming knowledge how to get started.

First, you must familiarize yourself with AGI Studio and what each button and menu item represents. Take the time to explore and experiment with each.

Resources

AGI games consist of 4 file types, or resources, all combined together into one file called vol.0 (or vol.x for multi-disk games).  These file types are PICTURE, VIEW, SOUND, and LOGIC. The maximum amount of these in any AGI game is 256.

PICTURE

These are the background images for the game. They don’t include anything that animates on the screen. The only time PICTURES are changed is when the room changes. You can create picture resources with Lance Ewing’s Picedit. The pictures are stored in vector format as opposed to bitmap format. This means that you can’t create your pictures in your favorite graphics editor, because instead of storing the pixel data for the picture, it stores the actions taken to draw it. This was done to save considerable space. For example, imagine the size of a picture with a single line in bitmap format - 160x168 which would equal 26880 bytes on the disk in bitmap form with no compression. But if we were to store it in vector form, like normal, it would only take roughly 7 bytes, because it only stored the action to draw a line.

VIEW

These are all of the animations or moving images in the game. They are generally small in dimensions, and unlike PICTURE resources, they are stored in bitmap form, with compression(RLE). They can have a maximum of sixteen colors from a fixed palette. One of these colors must be chosen to be transparent. When the VIEW is drawn in the game, it will only display the colors that aren’t transparent. The editing of VIEW resources is done with the VIEW editor built into AGI Studio. Each VIEW contains up to 32 loops. Each loop contains a single animation, hence the name loop. The loops can have up to 32 cells each.

Important: It is important to know that when I mention bitmaps, I'm not referring to the Windows file type of BMP. Although BMP stands for bitmap, bitmap is a general term in graphics as well and describes the way an image is stored.

SOUND

These are the sounds you hear in the game including music and sound effects. Each sound has three tracks, which can all play sound at the same time. This means that if you were writing music for your game, you could only have three instruments playing at once. For more info on creating sound resources consult the AGI message board.

LOGIC

These are the heart of an AGI game. An AGI game depends on at least one LOGIC resource, numbered 0. Each game cycle(every frame of the game) it reads this resource(ie number 0) and follows the actions or commands contained in it. Peter Kelly’s Template game has the system set up slightly different. He has added LOGIC resources 90-95 and 98-99 which all handle different aspects of the game such as death, etc. These are all called each cycle from LOGIC 0, and return back to LOGIC 0 when finished. For a better understanding, it is best to examine the Template Game.

Inside a LOGIC resource, there are many types which you may use, these are the most common:

Variables (example v234 )

Variables may store a number up to 255.  Variables v0 up to v26 are reserved.

Flags (example f56 )

Flags can have two states, set or not set.  To set a flag, use the command set(flag number).

Objects (example o2 )

These are used to control animations on the screen.  When a view is loaded, it is assigned to an object.  To move the view around the screen, you must refer to the object number and not the view.  Objects are not to be confused with Inventory items, which are completely different.

Creating a new room from the Template Game

Over the years I have followed AGI editing, a lot of the so-called demos that have been released have just been rehashes of the Template Game. They would only have one room, and one view - the player. This I believe is because it is very easy to work out how to print text, but these people couldn’t work out how to create a new room. Well, it is actually quite simple.

  • First you will have to create the PICTURE resource for the room.  Once created, add this to the game using the menu RESOURCE-ADD.  Browse to the PICTURE and press OK.  Set the resource number to 3 and make sure that the resource type is PICTURE.
  • Now that this is done, all that we have to do is create the logic.  The best thing to do is just copy and paste from LOGIC.002.  So, double click on LOGIC.002 in AGI Studio. An editing screen will appear with the source code for room 2. Drag the mouse button from the top of the file to the bottom to select all of the text. From the edit menu, select COPY.  Now close this file, and start a new one, by clicking on the button labeled Logic editor on the toolbar. Select PASTE from the edit menu.
  • At the top of the file are 5 comment lines. All comment lines begin with "//". You may delete these or change it to suit this new room(3).
  • Next, comes an if statement. This statement checks if we just entered the room.  The flag new_room will be set if we did.  Everything after the brace( { ) will be done until we get to the closing brace for the if statement ( } ).
  • First the picture of the room number is loaded into memory, using the load.pic(room_no) command. Keep in mind that every command has either a semi-colon(;) at the end or an opening brace.  In this case, it’s a semi-colon.  If you wish to change the number of the PICTURE resource which is loaded, you must first set a variable(say, v200)  to that value and invoke the command like this:

<syntax type="C++"> v200 = 4; load.pic(v200); </syntax>

  • discard.pic(room_no) just rids the PICTURE from memory once it is drawn.
  • set.horizon(50) sets the screen horizon. When the player’s Y value is lower than this(ie is above the horizon), then a new room will begin.
  • As you can see from the next comment, the next six lines may be deleted because this isn’t the first room of the game.
  • Now if you wish you may reposition the player on the screen, by uncommenting(removing the //’s) the code.
  • draw(ego) and show.pic do exactly what they say.
  • The rest is mostly self-explanatory, where all you have to do is replace numbers to their appropriate values.

That's basically how to create new rooms from the Template Game. Using this method you should be able to create as many rooms as you like.

Part 2

Introduction

Each part in this series will become more advanced. It is recommended you read part one before continuing.

NOTE: The work in this part is all done in a new game based on the template.

Creating room objects(animations)

Creating an object to add to a room is very easy. First, you must understand that the AGI system needs to have a name for everything. In this case, it needs a name for your view. There are 256 names available from o0 to o255. When you end up having many objects in one room, it can become very confusing, which one is which. That is why we can define our own names for each object. You may have noticed already, that ego has been defined as o0. Many of the variables and flags have also been defined to have easier to remember names.

Adding your object name definition

So, to add your object definition, add this code to the room(in this case room 2 - LOGIC.002), just under the line: <syntax type="C++">

  1. include "defines.txt"

</syntax>

add

<syntax type="C++">

  1. define your_object_name_with_no_spaces o1

</syntax>

So it should read like this:

<syntax type="C++">

  1. include "defines.txt"
  2. define your_object_name_with_no_spaces o1

</syntax>

The reason we use o1, is because ego, is always o0.

Initialising your object

Now, in the initialisation section of the room, we decide which view we want to use for our object, and where we want to put it. The initialisation section is everything between <syntax type="C++"> if (new_room) { </syntax> and

}

We want to add our code after the line: <syntax type="C++"> draw(ego); </syntax> The code we will add here displays a view on the screen: <syntax type="C++"> animate.obj(object name); //this tells the interpreter, that we're using this object load.view(2); //load the view we want to use into memory set.view(object name,2); //this assigns the view to the object we've created set.loop(object name,0); //set the current loop in the view to this value set.cel(object name,0); //set the current cel in the view to this value position(object name,43,104); //where to position the view on the screen. set.priority(object name,11); //set the priority of the object(change accordingly) ignore.objs(object name); draw(object name); //finally, draw the view on the screen. </syntax> Set.loop, set.cel, and set.priority aren't really necessary, but can be useful, if they need to be changed later on. Ignore.objs makes the object oblivious to other objects. If this is not set, then another object may stop if it hits this object when moving.

That's basically all there is to add an on-screen object. Remember, when using object commands, always refer to your object's name, and not the view number.

Creating Inventory Items

An Inventory item is one of the key elements to your AGI game. So unless you know how to add them, your game will be a flop.

There are many steps to adding an item to the game, and may seem daunting at first, but once you get the hang of it, it's very easy.

Creating the views for the Item

Each inventory item typically requires two views:

  • A view for the item on the screen
  • A view for viewing the item once acquired.

When you have done this, save the on-screen view as VIEW.002 and the Inventory view as VIEW.220. The inventory view may also have a description added.

Editing the OBJECT File

For the item(object) to be viewed in your inventory, it must have it's name put in the OBJECT file(not to be confused with onscreen objects). Just change object 1 to the name of your item, and the room number to the room in which it is found(2 in this case).

Putting the Item in the Room

After you have completed the first two steps, you are ready to add your Item to the room. This is done with the following code, added to the room: In the defines section(after the #include line):

<syntax type="C++">

  1. define item name o1 //replace item name with your own.

animate.obj(item name); load.view(2); set.view(item name,2); set.loop(item name,0); set.cel(item name,0); position(item name,43,104); //use your own position and priority here. set.priority(item name,11); ignore.objs(item name); stop.cycling(item name); draw(item name); </syntax> Modifying LOGIC.090

This logic, in the template game, handles non-room-specific functions, like get item and look item. Add this code under the section that says put various input responses here: <syntax type="C++"> if (said("look","your item name")) { // your item name must be replaced

 if (has("object name")) {           // object name is the name you put in the OBJECT file
    show.obj(220);                      // 220 is the number of the view with the
                                       // close-up and description of your item.
 }
 else {
   reset(input_parsed);
 }

} </syntax> Also needing to be added is the code for getting the object: <syntax type="C++"> if (said("get","your item name")) {

 if (has("object name")) {
   print("You already have it.");
 }
 else {
   reset(input_parsed);
 }

} </syntax> Getting the item from the room

The above code was necessary for looking at the item in your inventory, or trying to get it if you already have it, but it's not good enough for getting the item from the specific room it's in. Use this code for that: <syntax type="C++"> if (said("get","your item name")) {

 v255 = 2;                                 //obj.in.room only accepts variables
 if (obj.in.room("object name",v255)) {  //so we make v255 equal to 2(the room number).
   if (posn(ego,37,111,51,124)) {          //substitute these values with your own.
     print("Ok.");
     erase(your item name);
     get("object name");
   }
   else {
     print("You're not close enough.");
   }
 }
 else {
   reset(input_parsed);    // let logic 90 take care of it
 }

} </syntax> Of course, we don't necesarily have to use v255, we can use any available Variable. The posn(ego,x1,y1,x2,y2) command, requires that x1,y1 is the top left corner of an imaginary box, and x2,y2 the lower right corner. Don't forget to enter the words you use into the WORDS.TOK file! This code is for looking at the item: <syntax type="C++">

if (said("look","your item name")) {
  v255 = 2;
  if (obj.in.room("object name",v255)) {
    print("Here is where you describe the item in the room.");
  }
  else {
    reset(input_parsed);    // let logic 90 take care of it
  }
}

</syntax> Finally, if you do not wish the item to be drawn when it isn't in the room(ie you have taken it), then replace the line above which said this: <syntax type="C++">

draw(your item name);

</syntax> to this: <syntax type="C++">

v255 = 2;
if (obj.in.room("object name",v255)) { draw(your item name); }

</syntax>