General Game Making Intro
Clone this wiki locally
If you're reading this tutorial, you're hopefully looking to make a game with frogatto's engine, but don't know where to start.
Frogatto has a pretty general 2d engine that can do almost anything you'd want from a 2d game. We have some shortcomings; it's impossible to build a new game using our engine unless you're willing to learn to program in FML/FFL, but we're very fast, very stable, we run on most platforms already (mac/win/linux/mobile) and we're open-source. We also have a laundry-list of obscure features desirable to a 2d, sprite-based game, since we've wanted these in our own work.
So... how do you get started? First, of course, is to get a copy of frogatto. To mod the game, you'll want to get at the data files; on windows or linux, these are wherever the game's exe got installed; these will be in the same directory as it. On a mac, you can right-click on the frogatto app, and you'll get a command in the menu that pops up, to "show package contents"; this will open a new folder, and the game's data files are in
./Contents/Resources/. By changing these data files, you'll change frogatto - without changing anything in our C++ code, you can transform frogatto into Pong, into a top-down scrolling space shooter, into a tile-based strategy game, even into an RPG. I mention all these examples; these are not pie-in-the-sky possibilities, these are things we've already done.
If you're making a game, you're gonna want new art and sound. Our setup for these is pretty straightforward; you drop the files in either
music, and they're available for the game to use. Sounds and music don't need any special listing, but a few kinds of images (tiles and backgrounds) need to be added to a global list to make the game aware of them. There are special restrictions on image sizes and such, which are described in this wiki page - along with info on which image/audio formats to use.
Objects and Game Logic
The heart of making a new game is making the game logic. The stuff that responds to button presses, tracks hitpoints, makes the player move around, decides what gets drawn when. All of this in frogatto, is handled in something we call "objects" - practically speaking, there are only two interactive elements in the entire game, objects and tiles, and they control everything. By changing the logic inside objects, you can turn frogatto into a completely different game. Our objects are written in a programming language we've designed called FML/FFL; by changing the things written in this, you change how things behave.
Objects in frogatto are built around an idea of having variables - numbers like hitpoints, and events - things that trigger small, freely-scriptable sets of behavior. Anything that happens in the game, such as two objects bumping into each other, or an object touching down on a solid surface underneath it, will trigger an event. In response to this event, an object will run a small snippet of code that decides what it's supposed to do in response to it. For example, I described "two objects bumping into each other". Each object can have its own code to handle this; if frogatto bumped into an enemy, frogatto's event to respond to this checks the enemy, and checks if you bumped into a harmful part of the enemy - if you did, it subtracts a few hitpoints from frogatto. Events can do virtually anything; move objects around, change objects from one type to another, change the current level, play sounds, change the current music, make objects start different animations, change the current offset in an animation, create other objects, apply complex mathematical formulae to an object's variables - anything you'd need to control the workings of a game. Some events have sensible defaults; when an object gets the "die" event, it will automatically be removed from the game, but most events are entirely up to you to provide the logic for, and you're free to make up new ones, and trigger events in other objects whenever you want.
Frogatto allows objects to store variables, and to define functions to encapsulate commonly-used behavior. It has a wealth of built-in functions that give access to a lot of commonly-needed stuff like trig functions, and such. Variables are cleanly split into groups; basic ones have direct implications on the game, such as hitpoints, or zorder (which determines what layer something is drawn on). User-defined variables do only what you explicitly make the game do in response to them changing.
How to use FML/FFL is beyond the scope of this intro; we've got a whole series of tutorials on the subject, though (TODO: link these, organized by task).
Objects and visuals
Objects are also used to draw the majority of the art onscreen. Because tiles are such a basic thing, we do have a special, hard-coded system for supporting them, but objects provide almost everything else, including many stationary pieces of prop art that appear to be part of the scenery and blend into the tile art.
Each object has a set of animations inside it - objects actually have to have animations, and although we often use invisible "control" objects just to provide pure snippets of game logic, we don't distinguish between these in-game. Control objects are regular objects like any other; even though their position is usually meaningless, they still have one, and they still require a graphic (we usually use a cheap trick to make them invisible in the actual game, such as
on_create="set(alpha,0)"). Many objects, like frogatto the player, and the enemies he fights, are both interactive elements that can affect each other (hurting each other, colliding, killing things), and also handle their own display onscreen. Many objects, though, exist for no purpose other than displaying a visual effect, and have no effect on the actual gameplay itself. Defining animations is a full subject of its own, covered in TODO
Almost every case of a moving sprite is done with an object; we have one exception; when the player needs a large number of small moving sprites or dots, we have a special thing (which can be embedded inside objects) called a particle system to draw those graphics quickly - particle systems, however, are purely visual, and can't have any effect on the game. So if you wanted to make a harmful fire out of particles, the parent object would have to handle the act of detecting the player's position, and dealing damage. Particle systems are a subject of their own, covered in TODO
Tiles are a very limited, hard-coded system that lets you draw 16x16 graphics onto the screen, and lets you define automatic areas of solidity that correspond to those visuals. Tiles are a special system for two reasons; they're really fast, but they're also really easy to place thanks to a system called "auto-tiling". Tiles are drawn as different types that are meant to arrange together in a scheme; there are edge tiles, and interior fill tiles. Auto-tiling allows us to not have to worry about these when placing tiles in the game; you can just select a very general type, such as grey rocks, draw a blob of them, and the game automatically puts edge tiles on the edge of the blob, and fill tiles on the interior of the blob.
We have a special system that's able to apply large, indivisible graphics, made up of multiple 16x16 tiles, onto specific arrangements of underlying tiles; this is meant to help break up how inorganic it looks to have a repeating graphical motif every 16 pixels (which is strictly necessary to make 16x16 tiles seamless with themselves). Tiles are covered in TODO
Frogatto has special, hard-coded support for parallax backgrounds, and foregrounds, made up of large, repeating graphics. We can have as many layers as you want, our only limitation is that stuff has to be a power-of-two in size (unless it's a small, isolated thing like a cloud separated by empty, transparent space), and our horizontal backgrounds can't stop at a certain point (though this can be faked). Note that our tiles and our objects can also be given parallax, so using the special hardcoded backgrounds is not your only option! Backgrounds are covered in this tutorial TODO.
This concludes the overview. We're hoping to build up a series of special examples, each of which is a tech-demo of a specific game genre. We currently have some of these littered in our game data directories (often inside /experimental) but they're not well organized. Certainly, one of the best things to consult in just other objects in frogatto, if you want to see how something is done.