adVM

ADventure Virtual Machine

Documents

adVM compiler documentation
Browse in : All > Sections > Documentation > adVM compiler
Creating a basic adventure


This article will describe how to create a working adventure game.

NOTE: Everything that's shown in this article works already.

Please note: This is preliminary information and may be outdated at the time of the first release of the adVM engine which is planned for September 1st 2006.

The adVM engine consists of two parts: a compiler and an interpreter. The compiler is used by you to create the adventure game.

The interpreter is shipped with your adventure game. It is responsible for handling all the boring (yet important) stuff like accessing audio/video hardware, handling navigation; scripting, inventory, save/load, etc.

The interpreter is distributed under the terms of the new BSD license which means that you can give away an unlimited number of copies of it without having to pay a dime. You can also make modifications to it and distribute those without having to release your own source code.

Your adventure game consists of graphics, sounds, music, text and scripts.

  • The graphics define how your adventure game looks like.
  • The sounds are used to make the game more realistic (footsteps, usage sounds, screams, ...
  • The music can be used as background music only or event-driven; whatever you choose is best for your adventure
  • Texts are mainly used for conversations which can be very complex. Conversations can include conditions, scripts and choices that are presented to the player.
  • Scripts are the essence of your adventure game. They are used to implement all the logic of your adventure. Do not worry; scripting if _very_ easy. Promise. We're using one of the best scripting language out there: python!

You'll learn how to put all these things together for your first adventure.

First of all, find an editor that appeals to you. For the first test, notepad will sufice if you're using windows. If you're using unix, you'll know what editor to use.

We assume you're using windows. These steps apply equally for unix.

Open notepad. You'll enter the definitions for your adveture here.

You start by defining in which file the finished adventure will be stored in. This is done by the \\outputfile{filename} directive. Note that all commands start with a backslash (\\). Next, you'll set the title and author of your adventure with the title and author directives.

Finally, you have to define some global settings.

NameMeaningValue in the example
startroomThe room the adventure will start inthefirstroom
startpointThe area of the room the player will start from (obsolete)0
maincharacterThe character the player controls when the adventure startsindy
charspersecondIf you haven't recorded your conversations, so they're displayed only as text, this defines how many characters (letters) the player can read per second20

So, the first lines you write in notepad:

\outputfile{default.avm}

\author{H. Ch. Esperer}
\title{adVM sample script}

\setting{startroom}{msgroom}
\setting{startpoint}{0}
\setting{maincharacter}{indy}
\setting{charspersecond}{45}

Next, you'll define a room. The room will consist of a background picture, a key the player can pick up, a door that the key will open and an exit that is accessible only if the door is open.

Also, an important issue is to tell the engine where the player can move. For that purpose, you need to create a special image. In this example, you'll just use the one we supply. There's another tutorial explaining how to create these special images (it's not hard once you understand the principles)

First, you'll tell the compiler to load the pictures of the door, the key and the background. Also, each room has to define its mouse cursor.

In order to define these pictures, you'll first have to import them. The statement for this is

\resource{image}{IMAGE_NAME}{PATH_TO_IMAGE}

So, in our case that means:

NOTE

Note that these statements are global statements. That means, if you have more than one key in your adventure, you'll probably not want to name a picture of a key key but rather housekey, labkey or something else that is more descriptive.

The last statement, \pathlayer, imports the picture that contains the path data and does some processing. (It creates polygons that approximately match the areas you created as a picture

\resource{image}{firstroom_background}{img/bg.pcx}
\resource{image}{key}{img/key.pcx}
\resource{image}{door}{img/door.pcx}
\resource{image}{mousecursor}{img/mouse.pcx}
\pathlayer{pfirstroom}{img/bccolors.pcx}

A room definition is started by the \room directive. The room directive contains a set of sub-directives that are only valid within a room directive.

That's what our first room, firstroom, looks like:

\room{firstroom}{
  \mouse{mousecursor}{0,0}
  \roomscript{sfirstroom}
  \pathdata{pfirstroom}
  \backgroundpicture{Background}
}

Now, we need the door, the key and the exit:

NOTE

Note the fact that the three objects are completely independent of the room. You tell them that they are in the room. That's it. They can be moved out of the room, into your inventory, to another room, to a temporary room,... The Exit To Reality (etr) item was not assigned a location at all, meaning that it will be loaded but not reachable from anywhere. We'll move it to some actual location during gameplay, namely when the door is opened.

The hotspotx and hotspoty parameters define the point of "force" of your object. This the point where the object "touches" the ground. Each object has an x and y coordinate. This point specifies where the hotspot of the object is, not the top-left point of the object.

Also note the event directives. They define what to do when a certain action is being taken. There are predefined actions, like actorsay or pickup, but also custom actions. They can be defined by using the execscript directive. Next, you'll learn how to write the doorscript|TryToOpen script.

\object{door}{
  \location{firstroom}
  \roompicture{idoor}
  \title{Door to reality}
  \setevent{leftclick}{actorsay}{indy|It's the door to reality}
  \setevent{rightclick}{execscript}{doorscript|TryToOpen}
  \pos{220}{600}
  \size{197}{251}
  \hotspotx{102}
  \hotspoty{251}
}
\object{key}{
  \location{firstroom}
  \roompicture{ikey}
  \beltpicture{ikey}
  \title{Key to freedom}
  \pos{480}{300}
  \size{45}{35}
  \hotspotx{23}
  \hotspoty{35}
  \setevent{leftclick}{actorsay}{indy|Looks like the key to freedom}
  \setevent{rightclick}{moveto}{indy}
}
\object{etr}{
  \title{Exit to reality}
  \setevent{leftclick}{execscript}{doorscript|ETR}
  \size{197}{52}
  \hotspotx{102}
  \hotspoty{52}
}

Okay, scripting is simple and easy, but you'll need to know some basics. So I recommend you to look at a generic python tutorial. If you are familiar with some programming language then you can skip the tutorial. (no matter which one you know -- (x) html is not a programming language, though)

Well, here goes the script:

\script{doorscript}{
def TryToOpen(avm, roomdata, myself):
  if avm.characters.indy.Has('key'):
    avm.RemoveItem(myself['name'])
    avm.Set('M_WayToReality_Open', True)
  else:
    avm.Say('indy', "I don't have the key")
}

Now, we're gonna add another function to the script, one that gets called when the player walks to the "Exit To Reality". Here, we see how to create a simple Graphical User Interface (GUI). Add this to the doorscript (right before the final closing backet '}' )

NOTE

The \script block defines a python module. In this case, it is called doorscript. It can be imported elsewhere by using import doorscript. The import function will retrieve the module from the adventure game file.

Note the parameters of the function. avm is a reference to the AVM module. You can obtain a reference yourself by calling import AVM. For backwards compatibility and convenience, it is passed as a function parameter. The second parameter, roomdata, contains a dictionary of the room properties. The third parameter, myself, contains the properties of the object that caused the function to be executed. That way, you can use one function for multiple objects.

The second method of avm, Set, sets a global variable (commonly referred to as "flag", as a hommage to Deus Ex!) Use these global variables to save game states. In this case, the fact that the way to reality is free, is noted.

def ETR(avm, roomdata, myself):
  if avm.Get('M_WayToReality_Open'):
    avm.CreateWindow('winQuit', 0, 0, 800, 600)
    avm.AddLabel('winQuit', 'lblCongrats', "Man, you've made it!", 120, 120)
    avm.AddButton('winQuit', 'btnQuit', "Yes, I'm cool", 120, 135)
  else:
    avm.Say('indy', "There's no way through this door!")

Now, we need to define our character. Let's call him indy.

NOTE

Note that we import the resources directly before we define "indy". It is totally unimportant in what order we do this. All objects, resources, scripts, etc. can be arranged in any way in the game file.

\resource{image}{indyl}{img/indyl.pcx}
\resource{image}{indyr}{img/indyr.pcx}
\person{indy}{
  \unique
  \title{Indy}
  \sex{male}
  \color{0}
  \hotspotx{52}
  \hotspoty{99}
  \display{
    \left{indyl}
    \right{indyr}
  }
}

Next, we need to tell the engine where indy is supposed to be when the game starts up. The engine doesn't support that. It won't let us tell it where it shall let indy start. What do we do!? Write a script.

We write a roomscript. A roomscript has a special method, EnterRoom, which gets called when the player enters a room.

\script{sfirstroom}{
def EnterRoom(avm):
  avm.SetCharacterPos(550, 450)
}

Speaking of scripts, we need to define two more of them. The first is the main script. It has predefined methods that get called during certain game stages (startup, save, load, quit,...). We're not gonna need it for the hello world example.

\script{main}{
}

The second one is more interesting. It handles GUI events. In our case, we need to write code that gets executed when the 'Quit' button gets pressed.

\script{guievents}{
def btnQuit(avm):
  avm.Quit()
}

Finally, save the thing as example.tex in the directory where you placed the images.

Then, open a command line window. Go to the directory your script resides in, and issue

advmcompiler example.tex
hc.slayer ~/advm/advm_example> ../advmcompiler/avmcompiler example.tex
AVM Compiler (C) 2005-2006, Hans-Christian Esperer
All rights reserved
Pixel-to-vector conversion by Wolfgang Keller! Thanx for that!

Importing types:(0x000a01 bytes): 0x080eb5e0.
Importing copy_reg:(0x0012f5 bytes): 0x080f42a0.
Importing processpl:(0x000151 bytes): 0x08098960.
ERROR: can't open img/greetings.pcx (2)---.M----.M---.....-..........
.......................
Writing dictionaries...done, 2087 bytes.
writing hdrlen...done, 4 bytes.
All finished. 69 chunks compressed, 149 uncompressed.
ZLib reduced size by 4089231 bytes.
Total bytes written: 11451229

If no errors occured, you'll now have default.avm, containing everything your adventure needs to run. You can now feed it into advm.exe.

Here's the full script we just created. The full hello world example can be found in the svn repository. A copy of it will be released at September 1st 2006.

Attention:

  • Currently, only jpeg and pcx are supported for the background; only pcx is supported for all other pictures
  • All pictures must be 256 color images
  • Right now, you have to use a 800x600 pixels pcx image for the background


< prev     next >

Note: Comments are owned by the poster. We are not responsible for their content.

Comments Settings





Action
Comment this hcdenton August 29, 2006 01:42 PM
You could post a comment if you were logged in.

#

Ratings
Options :
View Article Map