Arcade Game Designer Copyright 2008 Jonathan Cauldwell. This document is probably best viewed in a monospaced font. Instructions for version 1.1 ---------------------------- Like PGD and SEUD, Arcade Game Designer is a tool for writing your own simple arcade games. While it isn't as easy to use as those 2 utilities and won't help you create snazzy shoot-em-ups or platform games, it should be capable of producing a variety of basic arcade affairs, as long as you're patient and prepared to stick at it. That is, of course, provided that PGD does not crash horribly or something. Games produced using the utility are stand-alone and can be distributed freely. Now for the bad news. AGD has its own built-in language, a rather simplistic affair with simple functions and a few built-in variables which you'll have to pick up. In truth the lexicon is quite small, it's mostly a question of understanding how to use each particular command or function. While the program will tell you if it finds a word it doesn't understand (although it won't say where), syntax checking is non-existent. Unlike PGD and SEUD, AGD is decidedly user-unfriendly. Because I wanted to produce a games designer for everyone to use, the program is free to download from my website. Copyright, however, remains with the author. Donations are not wanted, so if you really must show your appreciation go out and buy a copy of SEUD or PGD from www.cronosoft.co.uk or something. AGD comes as you find it, cobbled together in a few weeks and very probably riddled with bugs I haven't found and for which I do not have the time to test. As such, please do not expect email support - I will be happy to answer questions and hear requests for enhancements on the WoS forums instead. I may get around to an update at some point in the future, other projects premitting. Until then save your work as often as possible, and preferably as a snapshot if you are using an emulator. Most importantly of all, have fun. In the meantime, I'm off to Ripley to get hideously drunk. Jonathan Cauldwell, 4th April 2008. http://jonathan6.fortunecity.com/egghead/ Release history 0.3 04.04.2008 - first public release 0.4 05.04.2008 - corrected memory management bug which caused many knock-on problems - fixed a problem with the sound compilation - added code to display message number in the message editor 0.5 06.04.2008 - fixed bug moving to next level - fixed bug whereby only 6 sprites appeared on screen, instead of maximum 12 0.6 12.04.2008 - added functionality for ADD and SUBTRACT - added events for restart and initialise sprite - games are now saved properly, so should now be entirely stand-alone - fixed bug in scoring routine 0.7 13.04.2008 - fixed anti-flicker sprite sort - fixed delete message bug - removed debug code which prevented saved games being reloaded 0.8 18.04.2008 - added map layout code - added DISPLAY command to display numeric values - code editor now makes use of as much RAM as possible - now returns address of score string in USR 34600 0.9 27.04.2008 - window resize now shows character squares in a chessboard pattern - fixed lock up caused by delete block routine 1.0 29.04.2008 - should be fairly stable now, so we'll call this version 1.0 ;) - added new deadly block, and new DEADLY collision test - replaced missing code for sprite copy and paste - fixed a bug in the sprite initialisation event 1.1 07.05.2008 - fixed bug in SPAWN routine - added WAITKEY command Constructing a game ------------------- Basically, games are a combination of different elements: * character blocks are combined together to form screens * sprites (including the player) are positioned in their starting positions on each screen, and assigned a type characteristic * logic is then written for each type of sprite - player, enemies, objects etc. There's not much more to it than that. Main Menu --------- Enables you to select a function of the game you wish to design. The amount of memory remaining available to your application is displayed in the top right corner of the this screen. Window area ----------- You can vary the play area's size and position in the Window/scrolling option. The cursor keys allow you to position the window anywhere on screen. Changing the window size and/or scrolling direction can alter the amount of data required for each column or row of blocks in each screen, and thus invalidate the present levels. If this is the case, the program will ask if you wish to destroy the map data before allowing you to proceed. It is a good idea to select the size of the play area first, and stick with it. 1 - narrow window 2 - widen window Q - shorten window A - lengthen window Keys ---- This allows you to define the keys your game will use. 7 Keys are permitted. Character Block Design ---------------------- Blocks are used to construct the screens. Each block is 8 x 8 pixels in size, and has a different type assigned to it. There are a number of different types, each with its own different set of attributes. These are: EMPTY SPACE - player can move freely through free space blocks. NORMAL PLATFORM - player may move freely past platforms from left, right or below. SOLID WALL - a block which is impassable from any direction. LADDER - player may move freely through ladder blocks in any direction. FODDER - treated as solid wall, but these can be removed with certain functions. DEADLY - sprites move through this, DEADLY function tests for contact Move cursor around the character with the cursor keys. Use SPACE or 0 to set/unset a pixel. ENTER returns to the main menu. Q = Move left through list of block properties W = Move right through list of block properties L = Last block N = Next block P = Paper colour I = Ink colour B = Toggle brightness M = Copy current block to clipboard K = Paste block from clipboard C = Clear current block X = Create a new character block D = Delete current character block ENTER = Return to main menu Screen Layout ------------- Move cursor around the screen with cursor keys. Use 1 and 2 to select the character block you wish to place at the current cursor position. SPACE or 0 places the desired block on the current screen at this position. ENTER returns to the main menu. 1 = Move left through block table 2 = Move right through block table N = Next screen P = Previous screen X = Create a new screen D = Delete current screen ENTER = Return to main menu Sprite Images ------------- Sprites are 16x16 pixel images which make up moving parts such as the player, player bullets, enemy craft, etc. Sprites may have any number of frames. Move around the grid with the cursor, fixing and deleting pixels with SPACE or 0. X - insert sprite D - delete sprite C - clear sprite grid M - copy sprite or tile to clipboard K - copy sprite or tile from clipboard N - next sprite P - previous sprite I - insert frame R - remove frame F - next frame Sprite Positions ---------------- This allows you to position sprites in their start positions for each level using the cursor keys. 8 sprite types are available, and sprites can be set up as any of these, allowing you to position bonuses, enemy sprites, the player sprite's starting position or any other type of sprite you have set up. N - next screen P - previous screen Q - move next sprite I - change sprite image T - change sprite type D - delete current sprite from screen X - add new sprite to screen Map Layout ---------- AGD will allow sequential levels, but also has the ability to create explorer games where the player can explore a map. The "map" of your game is arranged as a grid of 10 x 8 locations, all of which start off empty. Empty locations appear as two hyphens "--", rooms appear as the screen numbers, eg "01" or "12". As each room is designed in the screen designer it can be placed in this grid at a chosen location. To move around the map simply use SCREENUP, SCREENDOWN, SCREENLEFT, SCREENRIGHT commands. During the game it will not be possible for the player to move into an empty grid space. commands such as NEXTLEVEL or LET SCREEN=9 will not alter the current map position, so are best used in games with sequential levels, unless you are confident of what you are doing. The red cursor can be moved around the grid using the cursor keys, to change the room at a particular grid location move use keys '1' and '2'. Rooms are displayed in the bottom two thirds of the screen as they are selected to make matters easier. Your map will follow the rules of Euclidean geometry, but you can bend the rules to create a warped playfield should you desire. Moving left from a room situated at the left edge of the map will cause the player to re-appear in the room placed at the right edge of the next row up, if one is placed there. Similarly, moving right from a room at the right edge will take the player to the room at the extreme left edge of the room one row below. If you don't want this to happen you should construct walls on the relevant screens to form a physical barrier. It is also possible to re-use a room, that is to make it appear more than once in your map. Moving from one screen to another will not alter the player sprite's coordinates, so these should be set manually at the same time as the SCREENLEFT, SCREENRIGHT etc. is performed. Any player sprites set up for a screen will only be used for the very first screen, or to spawn a new player sprite should he die on that screen. Should the player die on a screen where he has no default position he will not be respawned. Press 'X' to declare a grid location as the point at which the player is to begin the game. 1 = Select previous room from list 2 = Select next room from list X = Select room where player first starts the game ENTER = Return to main menu Sound ----- H - Hear present sound N - Next sound P - Previous sound X - Create new sound D - Delete sound Move around the values with the cursor keys, increasing and decreasing them with 1 and 2. SPACE or 0 will toggle noise or tone off. To play a sound in your game, use the SOUND command in the relevant event. Save Game --------- Prompts for a filename, then saves your game as a code file which can be loaded in later and edited, or used as a stand-alone executable. If you wish to run your game independently of the utility you will need to record a BASIC loader program onto the tape first - if you are using emulation this could prove to be tricky. the simplest program to do this would be: 10 CLEAR 34599: LOAD ""CODE : RANDOMIZE USR 34600 Of course, you might want to set up a few other things first, such as the BORDER, PAPER and INK colours, plus a title page and maybe even a border around the status panel. If this is all too complicated, you may wish to take advantage of Intro Maker, another free utility by the same author, which creates the BASIC loader and introduction screen for you automatically. Load Game --------- Loads a new game from tape. If you are using an emulator, you will have to operate the tape browser yourself. Emulators with no tape browser, and those which automatically load inserted tapes are not recommended for AGD. AGD will only load code files which have been created with the utility. Test Game --------- Allows you to test your creation. Press ENTER at any point to return to the editor. Messages -------- This is where you can define the text messages your game will use. Press ENTER at any point to return to the main menu. N = Next message P = Previous message X = Create new message D = Delete message Events ------ This is the part where you get to have a say about the game logic, and can change the way it works in a variety of different ways. While the editor and compiler are not going to rival a proper language like BASIC, AGD does provide a very limited number of statements, functions and variables which should enable any number of fundamentally different arcade games to be created. Think of it as an arcade version of GAC - you may need to be very inventive about how you implement the features you want, but then that is half the fun. To modify the events, use cursor up/down to select the event, then press space or 0. Once selected, the code editor allows you to edit the code for that particular event. Symbol shift and A returns to the event selection screen. The editor will quickly run over your code, and report back if it does not understand any of it. Aside from events which occur at certain times in the game, there are events associated with 8 sprite types. These are the events which control the movement and logic of each type of sprite. Sprite type 0 is usually reserved for the player's sprite, so this code should test for keys and move the sprite around accordingly. The rest are all yours to do with as you wish. You could choose to make sprite types 1 and 2 different alien nasties with different movement patterns, and perhaps use sprite type 3 for bonus sprites which the player picks up. Functions can only be used after an IF. IF Test. If the following condition is true the code up to the next ENDIF statement is executed. IF can be used with a function, or to test variables or sprite parameters against each other, or against specific numeric values. ENDIF Marks the end of the conditional code. LET As in BASIC, this allows you to assign a value to a variable or sprite parameter. The value assigned can be a number, or another variable or sprite parameter. KEY Function. Expects a single numeric argument and condition is true if the key is pressed. CANGOUP, CANGODOWN, CANGOLEFT, CANGORIGHT Functions. Condition is true if the current sprite can move up/down/left/right. LADDERUP, LADDERDOWN Functions. Condition is true if the current sprite can go up/down a ladder. X, Y Sprite parameters. These are the coordinates of the current sprite. A, B, C, D Global variables. These hold 8-bit values. SCREEN, LIVES Global variables. These contain the current screen number and the lives remaining. TYPE Sprite parameter. This is the type of sprite being processed. Best used in conjunction with the IMAGE parameter, setting this parameter will completely change the sprite's behaviour - handy for turning a nasty into a bonus, or making a sprite stop and explode before killing it. There is no reason why you couldn't change a sprite to type zero and put it under the player's control, or change the player's sprite type to something else with a slightly different set of controls. So long as the new sprite type has appropriate code set up in the relevant event, there's no limit to what you could do. If you haven't set up any code for the sprite type your sprite will just sit there - which may be okay if that's what you want. IMAGE, FRAME Sprite parameters. These are the sprite and frame numbers shown in the sprite editor. You can change the sprite according to whichever direction the player is facing, or perhaps you might want to give the player a choice of vehicles to control. Setting a frame number beyond the limit of the sprite will result in a different sprite image being displayed, so use FRAME with caution. DIRECTION, PARAMA, PARAMB Sprite parameters. You can use these as you see fit, perhaps to indicate the direction in which a particular sprite is moving, or the particular phase it is going through. Invaluable for any form of enemy AI. ANIMATE Command. Animates the present sprite, automatically cycling through the frames. NEXTLEVEL, RESTART Commands. Move to next level, and restart current level respectively. SPRITEUP, SPRITEDOWN, SPRITELEFT, SPRITERIGHT Commands. Move the current sprite accordingly. No check is made for blocks in the way, or out-of-screen conditions, so you will have to do that yourself with functions such as CANGOLEFT or LADDERUP. SPAWN Command. Expects 2 parameters for sprite type and image. This spawns a new sprite with the specified type and image at the current sprites's position. The new sprite is created with FRAME, DIRECTION, PARAMA and PARAMB all set to zero. The current sprite is unaffected. REMOVE Command. Removes the present sprite from the table. Useful for destroying enemies or picking up objects. DIGUP, DIGDOWN, DIGLEFT, DIGRIGHT Commands. These remove any fodder blocks above, below, or to the left or right of the current sprite. The attributes for all removed blocks will be set to the same colours as those used for block zero. Any other blocks are unaffected. COLLISION Function. Requires one numeric argument to specify the sprite type. Condition is true if the current sprite is in collision with another sprite of the type specified. SHOWSCORE Command. Shows the score at the current cursor position. Should be immediately preceded by instructions setting up the line and column position for the cursor. SCORE Command. Expects to be followed by a number to add to the score. SCORE 100 will add 100 points to the player's total. Values 0 to 255 are valid. SOUND Command. Starts a sound effect. Expects a single parameter for the sound number to play. CLS Command. Clears the screen. BORDER Command. Expects a numeric argument from 0 to 7 inclusive. Sets the border colour. COLOUR Command. Expects a numeric argument. Sets the permanent display attributes. Format is 128 * FLASH + 64 * BRIGHT + 8 * PAPER + INK. Can be used prior to displaying text or clearing the screen. DELAY Command. Expects a numeric argument. Pauses for the duration specified. MESSAGE Command. Expects a numeric argument for the number of the message to display. KILL Command. Initiates the kill player event and decrements the life counter. You should set up the lives counter in the initialisation event using something like LET LIVES = 3. LINE, COLUMN Variables. These determine the position at which the score or message will be displayed. They are temporary and change every time a sprite is displayed, so always use them immediately before a MESSAGE or SHOWSCORE command. GETRANDOM Function. Generates a random number between zero and the argument, and places it in the RND variable. GETRANDOM 100 will generate a number from 0 to 99, GETRANDOM 2 will generate a zero or 1. RND Variable. The last random number generated by GETRANDOM. ADD, SUBTRACT Commands. Add or subtract to or from a sprite parameter or variable, eg. ADD 1 TO A or SUBTRACT 5 FROM B. SCREENUP, SCREENDOWN, SCREENRIGHT, SCREENLEFT Commands. Move up, down, left or right one screen if possible. DEADLY Function. Condition is true if the current sprite is in contact with a deadly block. WAITKEY Command. Waits for a keypress.