(Post by William John Holly, read more at www.duelingdevblogs.com)
This week, I began tackling the programming for my game. Hammering out a prototype, as Gabe had started doing a week ahead of me.
A little known fact about programming is that it's actually really easy as long as you can follow logic, understand order of operations, can work within a structured environment, and (most importantly) can use Google to see how other people approach it. To the surprise of those who have never programmed before, code is just a lot of mostly interchangeable instructions written in a very specific language.
I'm actually mostly self-taught as a professional programmer. I've programmed since I was 11 years old and it wasn't until I turned 19 that I started my first programming class. Now, having completed quite a few programming classes, there's really only one thing that I learned from them that I hadn't already taught myself: a clean coding environment is what separates professionals from amateurs.
Clean coding is a pretty big deal when you get into professional stuff. People have to be able to read what you code if you're working in a team, and if you're not working in a team you at least want for your code to be clean enough that you can come back to it later and understand it at a glance in case you ever need to implement a patch.
If you have a really good attention span, you can probably pack tons of internal translation for what your code means in your head for a time, but after a while you're going to look back at it and it's going to look like a word search from Hell.
|Like this, but hundreds of lines long|
You want to write your code as if you have zero attention span and it's always easy to read the previous couple lines and know where you are. That's why my code in my game looks something like this:
That's just a chunk of my programming and it's already way, way simpler than what it needs to be because I effectively break down every programming task into individual working parts, and the script that runs these individual parts is usually so cleanly set up that it reads like a glossary of what each individual sub, function, and macro is useful for.
That's what clean code should be. It should be natural to follow to its works parts. Now, since I'm still working very hard on the prototype and have little to show this week, I wanted to go over organizing the working parts a bit. It's going to be pretty technical, but unless you're already a seasoned programmer you can't say that you didn't learn anything!
So, in my movement code I have a part that looks like this:
Remember what I said about good code looking like a table of contents? Now, you can see, in order, the scripts that do each part:
1. Check to see if the user has inputted keys that will affect the player's movement
2. Take the input and communicate it into variables that will determine the player's movement
3. Take those variables that determine the player's motion and actually move the player
4. Adjust the player's depth to ensure that they are properly drawn over objects according to their new location
If you want to update the game to include a new type of controller, you know where to make that change:
These broken apart pieces of the code are called "subroutines" ("subs" for short) and the most commonly cited benefit to using subs is that you can cut down redundant coding: instead of repeating yourself, you can just make a sub and execute it multiple times. While that's definitely one use I get out of subs, I tend to get my most value out of using them as organizational tools. It's so easy to get lost in programming, being able to give a name to a specific operation is incredibly handy.
But there's more tricks you can do once you get into something called a "function":
That's all of player movement. Pretty nifty, right? 11 lines of code, 3 of which are comments, 1 of which is the function's definition, and 3 of which are totally empty. How is it done so simply?
Well, the majority of the work done for the player's actual movement is in those "player_movement_indvfunc()" functions. Admittedly, I gave this function a bit of an ugly name, but I know what it means at a glance so it works for the necessary purpose.
Within those functions is the following:
That 81 line monstrosity (giggling to myself a bit because I know that's not as large as scripts can get) takes the player's movement variables and uses them to push the player through the room, slide along slanted walls, and feed back information about whether or not the player has come to an obstruction.
That's the difference between a subroutine and a function. A sub just executes a cute chunk of code, but a function executes a cute chunk of code and returns a value. You can set variables to be equal to a function, you can compare functions, and you can use functions in an algorithm. In this case, the function is one gigantic subroutine that moves the player along and then returns a value that will determine if the player cancels their momentum.
That "if" is taking the function and determining if it will return a "1" or a "0" (or "true" or "false") and setting the variable of "hs" to 0 if the function is "1". This makes the function not only useful in completing an action, but useful in helping the code that calls it to make a decision about whether or not the player needs to cancel their momentum.
So, if you were able to follow all of that, that's how I organize my code. Not only that, but I essentially just gave you my top-down movement engine for the player. Some parts are missing, but if you can follow the logic they shouldn't be too hard to fill in if you're making your own project. It'll look something like this:
|Enthralling enough gameplay footage that I made this entire blog post about programming technique.|
I hope you learned something valuable reading this, because lord knows this wasn't much of an entertainment value post.
Meanwhile on my project...
We would love to hear what sort of posts our readers are most interested in. Maybe you thought this was too technical, maybe you were craving move details. Let us know!