Making a good RPG engine: Setting Up Michael Dowling (typosoft@hotmail.com) http://www.geocities.com/typosoft/ May 29, 2002 ----------------------------------------------------------------------------------- I am writing this to help people get started on making their own rpg. This probably won't be for people just starting to program. --------------- Getting Started --------------- How to make and RPG engine. First thing to do is draw some tiles. I used 16x16 (pixels that is) tiles. The best program to use for drawing sprites to use in QBasic hands down is PP256. You can download it from my site. Make a grass tile or two and a nonwalkable tile. Put the walk tiles in one file, and the non-walk tiles in another. Write down how many tiles are in the walk file and the nonwalk file. The next step is to choose a library to use. There is no way you will make a good RPG without a library, unless you are some sort of god. I used DQB as my library. I removed all the subroutines from it that I wouldn't need, because as you will learn, you are going to need all the memory you can get. The next step is to make the engine. ------------------- Modular Programming ------------------- If you are going to make any sort of huge game, then you will have to learn what modular programming is and how you can use it. I don't proclaim to be an expert, but I do know how to use it. First step, make a main module (or BAS file). Save it. Then you will have to put all your variables that you want to be global (able to be used in all modules) in an include file. A good place to put them at is in the DirectQB.BI, since you already will have to include it in each and every module. =pretend this is the include file= DEFINT A-Z 'Not sure what this does, but you need it COMMON SHARED Map() 'How to declare that an array will be used in each 'module. Notice COMMON SHARED Player() as Ply 'that 'I didn't set the number of indexes yet. You do 'that in the main module. The as Ply defines the 'player array to use the already defined type of 'player. I will explain types and what should be in 'them later on. All types should be defined before 'anything else in an include file. COMMON SHARED A, B, C, D ' This would be how you could use A, B, and C in 'each module with the same attribute in each =pretend this is the main module= '$INCLUDE: 'Directqb.bi' 'include the include file DEFINT A-Z 'again you need this 'DECLARE SUBs... 'where all your declare subs would go. DIM Map(1 TO 12, 1 TO 20) 'Notice that HERE you set the indexes of MAP DIM SHARED Player(1 TO 15) AS PLY 'Again you will have to use the AS Ply 'thing. Also notice the dimmed arrays that 'are listed in the include file have to be 'in sequential order. If later on in the game you have to add in more COMMON SHAREDs to the include file, then be smart about where you add them in at. If it will just be a single variable, then add it to the very end of the COMMON SHAREDs. If it will be a new global array, then place it below all the other arrays, but above the variables. Then be sure to DIM it in your main module and make sure to leave everything in sequential order. The main advandtages to modular programming are that you can organize your code, and have lots more memory. Each module should have a "theme" to them. You should have an engine module, a graphics module, and a hanlding module (handles AI, triggers, and everthing else). If any module gets too big, then just make a new module, or bring a few subroutines from the big module to another module that has more room. --------------------- Setting up the engine --------------------- The arrays you will use and what they handle are the basis for the whole engine. We'll start by just brainstorming about how each thing in your "world" wil be handled. Here is how I did it. TYPE WorldMap 'Holds important info like the screen, music file, NPCs, triggers Screen AS STRING * 8 Players AS INTEGER Triggers AS INTEGER MusicFile AS INTEGER Detail AS INTEGER END TYPE 'add in as much as you need for your engine TYPE Player 'Handles Ped Xing and all the other NPCs X AS INTEGER 'x position Y AS INTEGER 'y position Tile AS INTEGER 'tile to draw him with Frame AS INTEGER 'frame of animation Delay AS INTEGER 'how many frames to wait before updating Fwait AS INTEGER 'when this hits the player's set delay then the frame goes up AI AS INTEGER 'defines the player's AI Eff AS STRING * 8 'what happens when you rub against them HP AS INTEGER 'hit points HPmax AS INTEGER 'maximum hit points MP AS INTEGER 'magic points MPmax AS INTEGER 'max magic points END TYPE 'That seems good for now. TYPE Trigger 'holds objects and effect squares X AS INTEGER Y AS INTEGER Tile AS INTEGER Frame AS INTEGER Delay AS INTEGER Fwait AS INTEGER Effect AS STRING * 8 HitEffect AS STRING * 8 'if a spell hits it, the scripting will handle the file END TYPE Of course then you will have to handle all of the players, triggers, and everthing else. The types should be at the top of your include file, so all the subs and arrays can use them. --------------------------------------- Subs you'll need and where to put them --------------------------------------- MAIN Module Init start the game up Menu navigate through your options Script (File$) most important sub in the whole engine Draw Module DrawMap (L) Draws the map to a specified layer DrawPlayer (P) the player to draw DrawTrigger (T) the trigger to draw DrawPlayers a FOR/NEXT loop that calls DrawPlayer on all the players DrawTriggers ditto with the triggers and any other special effects would go in this module Handle Module HandlePlayer (P) handles the players movement, animations, and AI HanldeTrigger (P) Ditto for the triggers HandlePlayers Call this to handle all the players HanldeTriggers Call this to handle all the triggers -------------- The Map Editor -------------- The map editor is one of the most important things you will need when creating a game. I think I made about eight different map editors and spent about a whole month just to create the one I use. A map editor will need to be mouse-driven and flexible. No one wants to use a map editor that't going to crash after making a thirty minute map (it's happened to me before). What I would suggest is to make the base engine of your game, and save two versions of it. One version will be the new map editor, and one version will be the game you will continue to develop. A map editor needs the following things Mouse support Save/Load feature Place tiles on the screen Place NPCs and Triggers and probably some other stuff I'm forgetting Saving a map will require you to translate the actual values that are stored in the NPCs and triggers to SCRIPT code. That means that in your script, you will probably have a command that says: MakePlayer X, Y, Tile, Frames, Delay, Effect, HP, HPmax, MP, MPmax, etc... You would have to do this in the map editor FOR I = 1 TO WorldMap.Players IF Player(I).HP THEN PRINT #1, Player(I).X, Player(I).Y, Player(I).Tile, Player(I).Frames, Player(I).Delay, Player(I).Effect, Player(I).HP, Player(I).HPmax, Player(I).MP, Player(I).MPmax, etc... END IF NEXT ----------- Ending Note ----------- I think that is a good start for now. I didn't really touch on the real coding, but there are a million and one tutorials out there that do. If you need examples, then download the source to Ped Xing's Quest.