---------------------------------------------------------------------------------------------------- Technique ---------------------------------------------------------------------------------------------------- There are many ways to create a game, depending on the game and your own preferences. Here's a possible outline of a normalized technique, in order to keep everything clear and consistent. - Definition - Specification + Presentation - What should it look/sound like? + Operation - What should it do? - Construction - Media + Visual + Audio + ... - Code + Divide building blocks + Options - How can it be done? + Solutions - How will it be done? - Realization - Implementation + Order + Build - Finalization + Limitation + Optimization + Expansion ---------------------------------------------------------------------------------------------------- Outline ---------------------------------------------------------------------------------------------------- Now, allow me to explain how it works. - Definition ---------- Before you can create the game, you'd have to know what it is exactly. More time spent on preparation usually means an exponential speed-up in development. - Specification ------------- In the first phase you can simply specify what the game is all about. Actually you can describe the game in two ways: externally and internally. E.g. what the game should look/sound like, and what the game should do, respectively. The clearer the specifications, the less time it will take to build the game. It doesn't really matter whether you do this on 'paper' or in your head, so long as it's clear :) + Presentation - What should it look/sound like? ------------ This part describes the exterior of the game, so basically the game's output. Usually there are some sketches, drawings or ideas of what it should look like. The point is to get the general idea of the game's content as clear as possible. For example if you have a simple shoot'em up game, you'd have to know (perhaps just a little bit) what the player ship looks like or some of the enemies, backgrounds, etc. + Operation - What should it do? --------- The operation part should tell much, or better, everything about the inner workings of the game. Such as what you first see when you start the game. As well as any events that may occur, such as pressing the fire button, which would be the game's input. Maybe the game also has a main menu with certain options to choose from. Or you could, for example, describe how the ship or the enemies should move. Like there could be gravity that would only affect ships. So basically this is where you can sketch the framework of the game. - Construction ------------ Moving on to creating the technical design document for the game. Which specifically describes what to construct, media, code and anything related. As before, the clarity of this document directly affects the time needed to build the game. Having some unclear details can interrupt or even compromise the development. Try making the design document as language and program independent as possible. Unless you find a unique tool which accelerates your development like there's no tomorrow :) If there are a number of tools available, you could make a list to weigh the benefits of each. The line between constructing a design plan and the actual product can be pretty thin. For example you can test things during this phase, which code could directly be used in the final product. - Media ----- Usually a game's content consists of at least visual and sound elements. Maybe there are also various levels, maps, worlds or a storyline. All these can easily be added to this section. + Visual ------ Try to divide each type of graphic in different categories. For example having static, rotating or animated images. If you want to know which sizes they should have, or maybe you want to know how fast something should animate, you can always try it out in a program. If you test things out a lot, it's not unlikely that the game will benefit from it :) + Audio ----- Actually the same goes for sound and music. Think about things like duration, volume, panning and maybe even what it sounds like :o) - Code ---- Start by sketching the outlines of the game - finding the building blocks. Then you can fill in all the gaps by chopping everything up into little pieces. Once you have mostly (or only) undividable pieces, bringing you to the most technical side of the code, you can check out in which ways it can be done. Like, if you have gravity that affects a ship, how would you do this in code? By reviewing a number of options you can pick the right solution for your game. + Divide building blocks ---------------------- You can find the building blocks in your game by elaborating on what you have defined in the specification phase. For example if you have a player, bullets and a map, this is where you'd start. If you want, you could also use an event table to systematically describe when everything happens and under which conditions. But you could also just divide each main block into smaller blocks until you can no longer divide them :) For example a player could be controlled by the keyboard. Maybe there's gravity that affects the ship. You'd also have to display the ship somehow. And maybe you'd want to see if it collides with other objects. You can divide these all the way down to for example knowing exactly which keys control which part of the player. + Options - How can it be done? ------- Experience will usually come in handy when looking for possible solutions. Take gravity for example. If it's gravity that pulls objects towards the bottom of the screen, you'll know that's your starting point; having to increase (or decrease) an object's vertical position in a way. By trying this out in a program, or multiple programs even, you can get most clear results. + Solutions - How will it be done? --------- Selecting the best option for your game usually depends on how much time you want to spend on it. Some options are harder than others, taking up more time. You could also implement an easy solution first, to see how it feels or looks. And upgrade to a more advanced solution later on, although this isn't always applicable. - Realization ----------- This is basically the actual building of the game after at least in some degree knowing what the game will be like. And after implementing, maybe fixing bugs, finalizing media or perhaps optimizing the code. - Implementation -------------- Choose what kind of implementation suits you most. Maybe you want to create all media first. Or maybe you like starting out with some code. Also decide on which tools to use. + Order ----- Determine the order of implementation. If you want to build the code first (e.g. the least artistic part), you can use place holder graphics, music and sound for the time being. So all media can grow as the code progresses. Besides, for some parts of the code you do not need any media anyway. But for others you need at least some place holder. Use nice place holders to get inspiration back from what you create. + Build ----- At this point you're ready to construct the entire game. Being code, media and anything else part of the game. Please do divide this task in any parts you like. But make sure to be building block for block. Implement one thing at a time. If you get an idea, write it down - save it for later. Distractions can be very dangerous :) Use any tools that are available to you. Try to adjust the tools to suit *your* needs. When seemingly impenetrable walls appear, remember your original thoughts and feelings to reach your goal. The creation of media usually flows from your own artisticity. But the creation of code can be constructed using a logical system. For instance the difference between design-time and runtime. Runtime means all the things going on when your game is being executed. Design-time indicates the things that do not change when your game is run. For example constants are design-time and variables are runtime. For the code you can use a template to begin with, a framework. In the Blitz Full Foundation tutorial you can find some of these. You can expand each part of the template by adding each related item. For example in a display routine you could display a player, enemies and projectiles. If you don't like coding, try to mix it with the creation of media. For example, first create an image you want, then write the code to display it. - Finalization ------------ After everything is implemented or after implementing each little thing you may encounter bugs, due to your code, media, tools or language you're using. You don't have to fix them right away, but it usually improves a healthy state of mind ;) You may also find that your game is running too slow; maybe you want to speed it up by optimizing certain parts, upgrading used solutions or implementing an advanced algorithm. + Limitation ---------- In creating your game you could find various problems, limitations, boundaries. Boundaries by language (or tools); Unsupported features, bugs, etc. And boundaries by design; Unforseen complications or bugs in the code or media. + Optimization ------------ And then there's boundaries by environment; Slow computers, operating system quirks, video driver issues, etc. + Expansion --------- In case you want to keep updating the game with new features which does not apply to most games, the more modular you make your game, the easier it is for you (or anyone else) to modify or add new things to the code. Heck, even if it's just to hunt down a bug. You may want to make your game modular anyway, even though it can take more time to make it so, it will pay off in respect to things like accessibility and readability. E.g. highly recommended for most commercial projects. The BlitzBasic Full Foundation tutorial displays a number of code examples of modular design; where code is logically separated in various parts. ---------------------------------------------------------------------------------------------------- Specification -> Operation -> Events ---------------------------------------------------------------------------------------------------- You could also for example create an event table to see all game events in 1 table. Cause Effects Conditions ----------------------- ----------------------- ----------------------- Player presses Thrust Ship (re)spawns Player is dead Player presses Thrust Ship fires bullet Player is alive Play fire sound Ship spawns Play spawn sound Ships collide Ships explode Ship explodes Ship disappears Create ray of bullets Play explosion sound ---------------------------------------------------------------------------------------------------- Specification -> Operation -> Flowcharts ---------------------------------------------------------------------------------------------------- And diagrams for gameflow, as an example. .-----------------. | Game is started | `-----------------' | v .-----------------. | Intro music | | Intro screen | | Load media | `-----------------' | v .-----------------. | Game is playing | `-----------------' ---------------------------------------------------------------------------------------------------- Construction -> Media ---------------------------------------------------------------------------------------------------- Remember: Making everything yourself takes a very long time. To establish specifics like image sizes, we should try it out in a testbed or testing program. So we take an adequate place holder graphic ship to start with and place it on the screen in a resolution of our own desire. It would be nicest if the resolution would give us the most horizontal space compared to vertical space for horizontal split screen. In Gravity Force the screen was split vertically which doesn't seem too logical too me. So I've chosen the horizontal approach. A resolution of 1280x720 gives a lot of horizontal space compared to vertical space (ratio = 1.8) but not all videocards and/or drivers support this resolution. That's why I think we should incorporate a detection feature which detects if the resolution exists. Some people said it doesn't always work, so I'm following my gut and prayers on this one :-) The idea is to strive for compatibility <-> possibility; Free yet clear. In Gravity Force, there are 2 player ships. So we'll also need 2 ship images. The ships can fire, so there have to be bullets. The ships can also fly around in some kind of world. We can build this world like a puzzle. Being a grid of tiles, e.g. a tilemap. And for that we'll need a tileset, e.g. a collection of images for our tiles. And maybe there's also a background. ---------------------------------------------------------------------------------------------------- Construction -> Code -> Options - How can it be done? ---------------------------------------------------------------------------------------------------- Resolution: Go with 640x480 for max compatibility Or detect if strange res exists If not, go back to more normal res Autodetect if 1280x720 is possible Else autodetect 640x400 Else 640x480 Can add more if needed Graphics: Ships, test the image size on the selected res Determine size: Image size: 32x32 Bullet, ditto: Size: 2x2 Tiles, ditto + use Tilemap with a Tileset: All contained in an animstrip Tile size: 32x32 Gravity: Something exponential with maths and stuff Simple thrust vertical down Frame limiting: Making the game run with the same speed on every computer, options: Using built-in routines (easy, not so smooth) Using easy external routines (easy, smooth) Using fast external routines (medium, smooth) Image rotation: Options: Rendering rotated images at runtime (easy, slow): Using built-in routines (easy, slow) Using easy external routines (medium, medium) Using fast external routines (hard, fast) Creating rotated images with another program (medium, fast): Using a paint program Using a custom blitz program Prerendering rotated images before game starts (medium, fast) Object collision: Finding out when things bang into each other, options: Simple: Single level (easiest, slowest) Double level (still as easy as eating pancakes, a lot faster than slowest) Triple level (medium, medium) Smart (medium to hard, faster to fastest) Split screen: Dividing the screen in 2 using: Built-in commands (easy, fast) External functions (medium, medium) Ship movement: Any 2D space movement with more than 8 directions or free angles (0-360 degrees) will require the use of Sine and/or Cosine, options: Manually using Sin (and/or Cos) (medium difficulty, fastest) Using easy external routines (low difficulty, slower) Using fast external routines (high difficulty, faster) Visual orientation: Displaying all objects relative to the player ship centered in view Making use of logic (internal) and visual (screen) coordinates Tilemap: Internal: Hard-coded (It's the only solution if you have less than 1024 Bytes of RAM :P) Using Data command: Characteristics: Low flexibility Easy to edit Medium-slow loading Advantages: Takes least time to create Disadvantages: No way to easily export or import maps when compiled Unable to use custom editor when compiled Unable to edit (or use custom maps) once compiled External: From file with specific format: ASCII (textfile): Characteristics: High flexibility Easiest to edit Medium-fast loading Advantages: Easy to understand format Easy to edit Disadvantages: Have to consider linefeeds, ASCII readability and map size detection Binary: Characteristics: Medium flexibility Requires editor Loads fast Advantages: Optimal design Fastest method (when processing) Disadvantages: Requires custom (external) editor Spawn positions: Random: silly Custom routine to find free space in map: * algorithm can take some time * simple algo not suitable for maps with gaps Location specified in separate file: on our way to 1000 files Location specified in map by special tile number: easy and fast ---------------------------------------------------------------------------------------------------- Construction -> Code -> Solutions - How will it be done? ---------------------------------------------------------------------------------------------------- Gravity: Simple thrust vertical down Frame limiting: Using easy external routine: Using built-in routines (WaitTimer) Image rotation: Creating rotated images with another program (medium, fast): Using a custom blitz program Prerendering rotated images before game starts (medium, fast) Object collision: Simple: Double level: (For all objects) If images overlap Then If images collide Then collision Split screen: Built-in commands: ViewPort Ship movement: Using easy external routines: T-C's vector functions Visual orientation: Using built-in command: Origin (with screen center) In combination with formula: (visual) object Coord = (logic) object Coord - (logic) player Coord Makes all (logic) object Coords (visually) relative to Coord (0,0) Thus turns any (logic) player Coord into (visual) Coord (0,0) In combination with Origin making the (logic) player Coord the (visual) screen center Tilemap: External from file: ASCII (text) Ability to understand the format when looking at it in a text editor Ability to use an external editor which can be created later on, if required Still having the option to upgrade to a binary format Note: Frame limiting can be implemented later. ---------------------------------------------------------------------------------------------------- Realization -> Implementation -> Code ---------------------------------------------------------------------------------------------------- Even though you could create the game's skeleton in an event-based language like GameMaker(tm), I chose Blitz for power and flexibility. Options: ; Definition (all or per section) ; Constants ; Objects ; Variables ; Initialization ; Main ; Input ; Logic ; Visual ; Sub routines ; Main ; Input ; Logic ; Visual ; Initialization Gameflow (level 0): Definition (per section) Initialization Main loop: Update Logic Update Visual Shutdown (obsolete) Note: Blitz will cleanup everything automagically. Gameflow (level 1): Definition: (per section) Const Type Dim Var Initialization: Intro music Intro image Load graphics (ship, bullet, tiles, background) Load audio (sounds) Load tilemap Var Main loop: Update Logic: Update Players Update Bullets Detect Collisions Update Visual: Draw Background (static) Draw Player 1 area: Draw Tiles Draw Players Draw Bullets Draw Player 2 area: Draw Tiles Draw Players Draw Bullets ---------------------------------------------------------------------------------------------------- Finalization -> Limitation ---------------------------------------------------------------------------------------------------- Format: Problem - Possible solution Problem: After dying, 'press fire' mode, if player in dogfight and rapidly hitting fire, player will instantly spawn again. - Force a delay and flush keys when delay is over (easy). Problem: Player spawn position - where to store. - Integrated in tilemap with special tile (easy). - Separate file (medium). Problem: Player spawn positions must not be too near to each other. - Test for collision before spawning (see below) (medium). - Omit near spawn positions by choosing most dominant spot (hard). Problem: Player spawn position must not be the same - to avoid spawn killing. - Don't spawn (easy). - Test for collision with existing player by (medium): - Pixel-perfect collision detection (easy). - Box overlap checking (medium). - Distance calculation (medium + maths). If collision, find another spot and do the same (medium). If all spots are occupied (you never know), don't spawn! (example: 1 spawn spot in map) (easy). Problem: Keys are remembered when game paused. - Flush keys before game unpause. Problem: Unrealistic bullet movement when player explodes. - When player explodes, the bullets from the explosion must have player's velocity added (medium + maths). Note: Compared to a lot of other languages Blitz will need a low amount of time to complete the Limitation phase. Flexibility is the reversed of limitation. For example GameMaker has a lower flexibility, so a higher limitation, meaning even less time needed to complete the limitation phase. ---------------------------------------------------------------------------------------------------- TheChange@yahoo.com (2003) ----------------------------------------------------------------------------------------------------