I received my first batch of artwork concepts, and I’m very impressed with how it looks so far.
This is at least 3495879283742x better than what I would’ve come up with by myself. I’m glad
There’s a very well-known article called Write Games, Not Engines. Reading it made me wonder about where the development of a game starts and how it progresses. Here are my thoughts:
0. Set up Version Control
I hadn’t planned on including this originally, but it was so important that I decided to dedicate a step for it. USE VERSION CONTROL. There’s really no reason not to use it. It helps you keep track of changes, revert to older commits, and a million other nice things. I personally use Git, but SVN works as well. If you are using Git, I highly recommend setting up a Bitbucket account if you haven’t already. It gives you a place to push all of your commits to, so if all goes to hell and your computer dies a horrible death, you’ll still have everything. Plus, it’s free and lets you setup private repositories (unlike Github, where you would have to pay). I’ve started so many projects without using version control from the get-go, and I’ve regretted it every time. It doesn’t take very long. Just do it; you’ll thank yourself later.
1. Make Something Playable
Seriously. Don’t spend weeks working on an engine if you don’t have at least have a guy jumping around. The way I generally work when starting to develop a game is to prototype something as fast as I possibly can. Even if it’s a red square in a white box, it GIVES YOU SOMETHING TO BUILD ON. Your confidence in coding will go up so much more if you know that you can run it and be able to have something playable. At this point, don’t bother with how the engine will work; just get something working. Once you do, then you can move on to the next step:
2. Build a Foundation
Okay, you have a jumping red square; now what? NOW you can start working on things like the engine and the pipeline. Did you hardcode stuff before? Refactor, refactor, refactor. I usually go through my entire project and try to remove as much code as possible. Remember: when refactoring, it’s ALWAYS better to remove code than to add code. The less code there is, the easier it is for you (and others, if working in a group) to remember and keep track of it. Since you have something playable, the goal here would be to keep that playability there while fixing up the code. Since what you had was so minimal, refactoring at this point is easy and almost trivial (but VERY necessary). By doing this, you are preparing your code for expansion so that it does not become bloated and impossible to look at later. Once you’ve polished the code to a sparkly shine, you can then proceed.
3. Tools are nice
If you’re coding in Unity, Flash, or something similar, you can safely skip this, as they will provide you will all the tools you’ll ever need. If you’re a more traditional programmer, however, you will thank yourself later by doing this.
So what exactly are tools?
Tools are a method for helping you with content creation. Whether it’s level design, event scripting, or animation editing, a solid tool will greatly help expedite your development later on. Trust me, it’s a lot nicer placing tiles in a grid than inputting numbers into a text file. If you’re working with a team, it’s even more important to have robust tools, especially if the ones using the tools have little or no programming experience.
There are two directions you can go here:
Our first podcast! It was our first time doing this, so feedback is greatly appreciated.
These are some observations that I have come to realize in the past few years of being a game developer. I hope you find them to be informative.
1. Success Stories are Misleading
As an indie developer, it’s important to go out there and find out about how other developers have created successful games. But something I noticed was that a lot of people take these games at face value. It’s very rare that any indie developer made a successful game on their first try.
Rovio made 51 games before they made Angry Birds.
Edmund McMillen made something like 37 flash games before he made Gish, Super Meat Boy, and the Binding of Isaac.
In one of his interviews, McMillen guarantees you that your first game is going to fail. Don’t take this as a discouragement, however. These numbers show that it takes a whole lot of persistence and patience to become a successful developer, but you can be successful. Just keep at it, and never give up.
2. Start Small
If you’re just starting out, please, for the love of God, don’t go off planning an MMORPG. It is highly unlikely that you’ll get anywhere with it, let alone finish it. The best thing you can do as a budding indie developer is to make the simplest games possible. I started programming in high school; back then, I did whatever I could with the knowledge I had. My first programming language was C++. The first thing I did? I programmed a text adventure. It was pretty simple; I had a 3 by 3 grid that you could traverse, a house, a shop, a cave, and random encounters.
Looking back on it, it was actually fairly sophisticated, given that I had just a few months of programming knowledge. The point to take away, however, is that it was simple enough that I could code all of it without feeling completely overwhelmed, but at the same time, complex enough to actually provide a compelling experience. For the next year or so, I showed it off to just about everyone I knew.
Coding that game was valuable experience that I still treasure today, years later. After that, I moved on to more complicated stuff like OpenGL. I’d probably choke to death if I looked at the code I wrote back then, given the fact that I had no idea how to organize code and had no knowledge of any design patterns, but the point is that I kept trying. I learned how the graphics pipeline works and even some simple linear algebra (which I didn’t officially learn until my second semester of college).
Since I’m still a college student, I have yet to complete any really ambitious project, but having the experience of coding these smaller projects, I have an idea of scope, as well as what I can and can’t do. This brings me to my next point, which is:
3. Know Your Limitations
I’m good at programming. I’ve known that for a long time. My dad was good at programming too (he was a rocket scientist at one point). As we all know, however, programming is just one aspect of game development. There’s art, music, writing, marketing, etc. Having played piano for ten years, I know that I could easily make my own music. Other stuff like marketing and writing doesn’t concern me very much, either. My main limitation, however, is art. Art is one of those things that I’ve struggled with since my elementary years. I know that if I spent a year just drawing, I could probably get somewhere mildly satisfactory, but if I do that, that’s a year that I didn’t spend programming a game.
It is important to know what you are good at, but I believe it’s even more important to know what you are not good at. I’ve known from the get-go that I’m not good at art, so I’m not going to waste my time trying to become competent when I could be programming. Even if I did spend time drawing, there are a myriad of people out there who could do a much better job than me. I’d much rather just hire someone when I need to.
4. Email is your Friend
This may seem obvious, but people respond to emails. I’ve emailed Jonathan Blow, Greg Kasavin, and the developers of Owlboy, asking questions about how they did certain things in their games. All of them responded. Emailing someone who has seen success can provide valuable input into your own game development. If there’s one thing that I’ve noticed amongst the indie community, it is that everyone seems to be humble, regardless of their success or status. It’s no surprise, then, that these developers would take the time to respond to a nobody like me. In fact, sometimes, they are even willing to guide you in the right direction if you ask nicely. Email is a very underrated way to obtain valuable information for development. Use it wisely.
5. Mistakes are good
So you’ve finally completed your first game, but it is received horribly by the community and no one plays it. Dejected, you decide to never make games again. This is, unfortunately, the inevitable fate of nearly every game developer out there. However, it is no reason to give up. Mistakes are extremely important as part of the learning process and can provide valuable information to you. What about your game did people not like? Was it the gameplay? The story? The art style? How could it be improved upon? Post mortems are especially useful. By writing about why you think the game didn’t succeed, you will be able to reflect upon some of your decisions during the development. Believe it or not, you can learn from your mistakes and ultimately, become a better game developer.
Now get out there and make games!
Even more progress since last time. I’ve added smoothing functions to the generator, as well as choosing colors for tiles. I also, just for the heck of it, implemented a procedural sound engine that creates music on the fly (it sounds… interesting, to say the least). Danger tiles are gone for now while I figure out more important things like WALL JUMPING. My code’s gotten pretty messy, so I’m only providing the executable this time (until I do some refactoring).
So I was experimenting some more with the procedural demo. I added a goal tile and danger tiles. The game uses A* pathfinding to ensure that a generated level is solvable. Source and executable are available for download below. Check out Part 1 for controls.
I discovered a simple, cool way to generate levels that I thought I’d share. I used the Drunkard Walk Algorithm to generate cave-like structures. The process is extremely simple.
First, I create an array of tiles and fill them up:
|
1 2 3 4 5 6 7 8 9 10 |
level = new GameObject[LEVEL_WIDTH, LEVEL_HEIGHT];
for (int i = 0; i < LEVEL_WIDTH; i++)
{
for (int j = 0; j < LEVEL_HEIGHT; j++)
{
GameObject gameObject = new GameObject(Content.Load<Texture2D>("tile"));
gameObject.position = new Vector2(i * gameObject.texture.Width, j * gameObject.texture.Height);
level[i, j] = gameObject;
}
} |
Then, I choose a random location and make it blank.
|
1 |
Vector2 p = new Vector2(random.Next(1, LEVEL_WIDTH - 2), random.Next(1, LEVEL_HEIGHT - 2)); |
I don’t include the edges of the array because I want the level to be bounded on all sides.
From there, I move in random cardinal directions (N/S/E/W) and remove the tiles that I pass through. I do this 1000 times.
|
1 2 3 4 5 6 7 8 9 10 11 |
for (int i = 0; i < 1000; i++)
{
Vector2 direction;
direction = directions[random.Next(4)];
Vector2 newP = p + direction;
if (isValidPoint(newP))
{
level[(int)newP.X, (int)newP.Y] = null;
p = newP;
}
} |
You can also bias the randomness towards the previous direction. This will result in a more corridor-like structures.
There’s probably a lot more I can do to make the levels even cool. If anyone has any suggestions, feel free to comment.
You can download the source and executable for this project below. I implemented a simple side-scroller engine to complement the procedural generation. Use the arrow keys and space to control the red square. Pressing R generates a new level. To spice things up, I also added the ability to change the direction of gravity. Press X and Z to rotate the level and gravity direction.
Have you ever gotten that feeling where you want to just take your code and throw it into a volcano?
That’s how I feel right now.
Everything I’ve done so far works the way I want it to, but I’m not happy at all with the organization. I always feel like no matter how much I plan out my code, I’ll end up doing things that I hadn’t planned. In the end, it often ends up like this:

With that said, I’m planning to go through a couple phases of refactoring so that I don’t get scared away from my own code.
Naturally, for any side scrolling game, a good camera system is of the essence. After some research on the internet, I found that a little linear algebra goes a long way. In my Camera.cs class, I have a function that computes the matrix of the camera.
|
1 2 3 4 5 6 7 |
void updatematrix()
{
matrix = Matrix.CreateTranslation(-position.X, -position.Y, 0.0f) *
Matrix.CreateRotationZ(rotation) *
Matrix.CreateScale(scale) *
Matrix.CreateTranslation(viewport.X / 2, viewport.Y / 2, 0.0f);
} |
If the idea of linear algebra makes you want to hide in a cave, fear not, for this deceptively complicated method is actually quite simple. The matrix is computed by multiplying matrices together in a certain order. The first matrix offsets the position to the center of the camera, the second rotates about the center, the third scales, and the last translates to the desired position. The order here is important; if the rotation happened first, it would rotate about the top-left corner instead of the center. Likewise, if the rotation happened last, the translation would be relative to the rotation. Here’s an image that shows this:
Once you have this, all you need to do is use the matrix when you call spriteBatch.Begin():
|
1 |
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive,null, null, null, null, camera.matrix); |
Everything that is drawn in this Begin/End block with be drawn relative to the camera’s position, rotation, and scale. Thus, with one simple method, it’s possible to create an entirely independent 2D camera. Enjoy!
I have found a God among men.
Up until now, I have been using the GLEED2D editor for level design, but I ran into the problem of having to serialize xml files so I could use this tool for XBox 360 and Windows Phone. After a little searching on the internet, I came upon this gem. This guy rewrote GLEED2D so that one, it is entirely plugin-based, and two, it can utilize the content importer for loading levels in the code. The best part? I can even import my old GLEED2D files and save them in the new format. I thought the original tool was good to begin with, but when I saw this, I was completely dumbstruck. It still has many bugs, some of which are quite problematic, but they shouldn’t be hard to fix. Steve Dunn, thank you so much for making this. I will use it to its fullest extent.