I have been using Game Maker for over 4 years now. From past experiences (= failed projects!) I have developed the way I work on & structure my projects. I hope the following game design tips are useful for my fellow indie devs!
In my last post on Dungeon Scroller, I mentioned a few methods I use when working on projects. One of these was to keep the game “scalable” – what do I mean by that?
This is something I learnt from previous failed prototypes: If the project structure isn’t designed properly from the start, it's very easy for the Game Maker project to become completely unmaintainable.
What can go wrong with game design?
Let’s start with the mistakes I've made in the past:
- Growing the code organically: When a project builds up from the prototype stage, it can easily grow messy and inconsistent. Copy/paste might be the quickest way to create new objects or rooms, but any duplicated code multiplies effort when bug fixing or making changes.
- Scope creep: It's very easy to add new objects and logic to a project. However, if not done in a structured way this can easily lead to cryptic code, as special cases & complexity builds up. Adding new features should always be carefully considered. What impact does it have to the core design? And what is the best way to implement it?
- Losing hold of the project: As a result of the two previous items, when code & objects are all over the place, it becomes very hard to navigate a project and build on it.
How to set it right!
How do I address the issues above? Instead of writing a game, I create a “framework” for the game. This means I focus on having the backbone of the game in place before adding content. The content comes second and is gradually added as the framework is in place.
- No hardcoding: That’s my rule of thumb for all parameters & variables in the game. I use constants for any hardcoded general variables (e.g. size of the map). Having named variables also makes them easily retrievable, using the Game Maker search functionality.
- Content files: I use tables (saved as text files) to retrieve all values linked to the game content (e.g. monster stats, weapons, etc). Not hard coding values, forces me to think of the game in a structured way. For any new item I add to the game, I first need to think what its underlying attributes are. Since everything is modeled as tables, new content can then be incrementally added.
- Tighten the scope: More can always be added to a game – but should it? I seriously question the pros & cons of a new feature before fitting it in. Does it fit with the games general design? Does it impact other areas? Would the game really benefit from it? My #1 priority is to finish the project, so more than once I've opted against adding new stuff.
- Tidying up: On several occasions working on my current project, I have revisited previously written code & design choices. I've then tidied them up! Sometimes looking at things with a fresh pair of eyes, allows you to figure out easier, more elegant solutions.
As an illustration of the above guidelines, here are some screenshots of the game documentation I've created for my current project. This is central to my way of working, as all the game content basically holds in a single spreadsheet. Nothing new goes in the game, unless it is first thought through, designed and fit in a table. I use Excel for convenience, but Google docs also works. The stats inside each table are then later copy/pasted into text files read by the game.
Each sheet & set of table relates to a specific object type in the game – whether this is loot, monsters or weapons stats. This is heavily inspired from Diablo 1 & 2; Those who remember the monstat.txt and treasureclass.txt files will know what I mean! Sheets are then copy/pasted into text files, for which I have a routine in the game to read from & push to in memory arrays. All game logic refers to these arrays, whether it's monster creation, generating loot or combat calculations.
Here’s the TO-DO list I use to store my ideas. As the project evolves, I decide which feature to tackle next. Colour codes show what I am currently working on (orange), what I've completed (green) and what I decided not to implement (red!), to keep the scope in check.
I also keep a log of progress + related version file; I backup my project by zipping the whole folder. Since I work on my own, there isn’t a need for elaborate version control! It's also nice to track progress & gives me an idea of the time spent so far.
Something still WIP, but one of my concerns is game balance. Since all the game data is in one Excel file, I am however able to mimic the game logic and derive stats from it. Here’s an example of Damage Per Seconds based on class, level, resistance, loot bonus, etc. This allows me to compare and tweak the various game parameters in document. This hopefully will help me strike a nice balance between the various in-game monsters, hero classes etc.
Game Maker Nitty Gritty
More specific to Game Maker & general maintenance, there are several ways I further organise my projects:
- Use of inheritance: Game Maker allows objects to inherit from others. This has two major benefits: code doesn’t need to be repeated, and all objects of the same type can be invoked with a simple “with” statement. This makes it very easy to structure both code and the elements of the game.
- Centralised Logic: In Game Maker projects, code can be written in scripts or directly inside objects. Using scripts is a great way to structure your project and I tend to avoid writing logic directly in objects. The only exception is if I know the associated code is specific to that object and unlikely to be reused anywhere else. Otherwise I organise my scripts per object type (Hero, Monster etc) and mimic Game Maker core events (Create, Draw, Collision etc) with a context relevant name. I find this helps navigating through the project.
- Hungarian Notation: proper developers would likely scream at this one, but I use Hungarian Notation in all my projects. Hungarian Notation basically means prefixing items with its type (i.e. all objects start with “o”, sprites with “s” etc.). This is thrown upon when writing .Net/Java but I have a good justification for my use of it: Game Maker does not allow two assets in a project to have the same name, whether they are of the same kind or not (e.g. sprite/object/script etc). This means if I create an object called Goblin, I cannot then create a sprite with the same name. Instead, I typically create an object oGoblin and sprite sGoblin, which I find more intuitive and clear!
- Folders: That’s a simple one, but I use folders to store scripts, objects and sprites in an organised fashion. It makes it way easier to find my way to a given piece of code when needed! Game Maker also has a convenient Search in Scripts function (Shift + Ctrl + F), which is a great and speedy to retrieve a piece of code.
I am pretty sure a lot of the above crosses with real-life / development guidelines. Do Not Repeat Yourself springs to mind! The Game Maker help is also stellar - complete with examples, it is my go to resource when coding. There are also a lot of blogs / forums out there which have nice little tricks and snipets of codes that can be re-used in your projects. As an example, Zack Bell's blog is absolutely stellar - I learned a lot from his platformer posts.
Let me know what you think!
There you have it – how I basically work on my current project! Hopefully someone will find it interesting. I would love to hear from you if you have any comments or further ideas!