ADventure Virtual Machine
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.
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.
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:
|
< prev | next > |
Note: Comments are owned by the poster. We are not responsible for their content.