First Ludum Dare — post mortem
(This was originally posted on the Ludum Dare compo blog, for competition #23 “Tiny World”)
I’ve known about Ludum Dare for a few years now, but every time it came around I would end up having too much to do in real life to participate. This time I was finally able to get involved, and it was one of the best things I’ve done in a long time, resulting in Humphrey’s Tiny Adventure, a point-and-click adventure game. Here are a few lessons I learned along the way.
Do as little brainstorming as possible
I knew from the beginning that I wanted to make an adventure game. At 9:00 PM the first day, the theme was revealed and we were able to get started. I spent 15 minutes sketching out some basic ideas and then got right to work. Not everything I wrote down made it into the final game, but it allowed me to get started quickly and add details as I went along, instead of trying to develop a complete design doc or storyline.
Get all your tools and libraries ready to go beforehand
This is a bit of a no-brainer, but I thought it was worth mentioning For this project I used FlashDevelop for my IDE, Inkscape for graphics and Chronolapse for screencasting. Since all three of those are necessary to get started, it wouldn’t do to have some programs downloading after the compo officially started.
Pick an art style that you can produce quickly
I’m mainly a programmer, and while I am capable of creating some reasonably impressive vector art, I certainly can’t pump out high-quality assets fast enough to make it a viable option for a game jam. I decided on an art style that consisted only of colored rectangles, which allowed me to keep my art simple, uncomplicated, and abstract enough that realism wasn’t a concern.
Use release-quality art early on
Chances are if I started out using placeholder art I would just continue using it until I ran out of time. Creating final art assets in the beginning helped me have a feel for how much work it would be to bring the project to completion.
Use version control
If you aren’t using version control already, start now. The first thing I do when I start a new project is create a new local Mercurial repository, and it’s saved me many times in the past. Using version control can save you if you mess up your project too badly, or retrieve old versions of your files if you decide that the first iteration of your player class is the better one.
Record a screencast
Keeping a video running of my work helped to keep me from getting distracted. If I wanted to update my progress on twitter, I had to open up Chronolapse and pause the capture, and even that small amount of required action was enough to keep me from constantly tabbing over to check my email.
Take breaks and get enough sleep
Whenever I came across a tough problem or design decision, I got in the habit of getting up from the computer and making myself a hot cup of tea. As much as it might seem like it’s necessary to spend the entire 48 hours in your computer, the best thing you can do for yourself is to take it easy. If you overwork your brain you won’t be able to think clearly and therefore won’t be as productive as you could be.
I think that’s about it! I had a blast participating, and I’m definitely planning on doing it again. :)
Building a better pathfinder
A while back I was working on a project called “Meander”. It was to be a 2D point-and-click adventure game, and later, a versatile engine for my personal use. One of the things I was most proud of was its pathfinding algorithm. It was my single greatest accomplishment, and even though it had its fair share of problems and design shortcomings, it did its job.
Looking back on the code now, I can see that it’s a huge mess. The code for accessing a given node in the grid is convoluted and only works with specific parameters, and there are many places where I iterate through the entire grid just to check if a single node is valid. I’ve thought about refactoring it lots of times, but the problems are rooted deeply in the design.
Over the past nine days I’ve been teaching myself HaXe. I’m a big believer in learning languages by using them, so I took the opportunity to write an experimental game framework called Astral for HTML5, Neko and Flash Player; three of HaXe’s compiler targets. One of the classes I wanted to implement was a pathfinder that met a few specific requirements:
- Operated with any dimensions. Meander’s pathfinder only worked with a grid 40 * 30 nodes.
- Be completely standalone. Meander’s pathfinder had a renderer built in, and returned destinations by pixel.
- Be fast. No matter how poorly optimized Meander’s pathfinder was, it was written in C++, which is orders of magnitude faster than any of the languages I target with Astral.
Here’s how it went down.
Algorithm structure
An A* or Dijkstra pathfinder is really not a very complicated algorithm. The process is explained here, which was invaluable during my first implementation. The basic idea is to simulate a flood of water from node to node until the end node is reached, then follow it backwards to find the path. Essentially, the flow looks like this:
- Check if the start node is the same as the destination node. If it is, the path is already solved.
- Check if both the start and end nodes are in valid positions on the grid. If not, the path can never be solved.
- Create a new grid to keep track of nodes that have been flooded.
- Add the start node to the flooded grid. Each time you add a node to the flooded list, keep track of how far many iterations you’ve gone through and set a “cost” variable in that node.
- Add the start node to a “parent” list.
- Until the flood reaches the end node, do the following:
- For each node in the parent list, do the following:
- Check in each direction around the node to see if the node there is a valid move.
- If it is, check to see if it has been flooded yet.
- If it has, ignore it.
- If it hasn’t, add it to a “next-parents” list, and add it to the flooded list.
- If it is, check to see if it has been flooded yet.
- Check in each direction around the node to see if the node there is a valid move.
- If the next-parents list is empty, there are no more valid moves and the path cannot be solved.
- Otherwise, set the next-parents list as the parent list.
- For each node in the parent list, do the following:
- If the flood reaches the end node, do the following:
- Create a FILO stack or queue to use as the path.
- Add the end node to the path.
- Until the start node is added to the path, do the following:
- Check in each orthogonal direction around the node at the front of the path to see if the node there has been flooded.
- If it has, check to see if its cost is less than the front node’s cost
- If it is, add it to the path and return to the beginning of the loop, skipping the next step.
- If it has, check to see if its cost is less than the front node’s cost
- Check in each diagonal direction around the node at the front of the path to see if the node there has been flooded.
- If it has, check to see if its cost is less than the front node’s cost
- If it is, add it to the path and return to the beginning of the loop.
- If it has, check to see if its cost is less than the front node’s cost
- Check in each orthogonal direction around the node at the front of the path to see if the node there has been flooded.
That’s all there is to it.
So, how’d I do?
- I tested the grid with a number of different size configurations, and all of them worked without a problem. Since this was a concern coming into the project, I was able to plan ahead and make sure nothing was hard-coded in.
- There isn’t one line of code in the whole pathfinding system that deals with any sort of graphics device.
- Obviously it’s not a good idea to run this solver every frame, but the speed at which it calculates a path surprised me. It’ll never beat a pure C implementation, but for most purposes it should be more than adequate.
Don’t take my word for it though, the source is all available over at the Bitbucket project.
Actionscript — likes and dislikes
I’ve been using Actionscript 3 as part of my game programming class for almost a month now. Coming from a C++ background, there were a lot of things I didn’t like about it the first day. Some of those things I’ve grown to like; others…not so much.
Things I like about Actionscript:
The import system
In AS3, libraries are built on the “one class, one file” paradigm. Each class must reside by itself in a file with the same name as the class. At first I thought that this was just a needless imposition; coming from C++ where every class can be in one file, it seemed silly to me that a language would restrict the freedom of the programmer in that way. As it turns out, this is possibly the thing I like best about the language.
AS3 classes are organized in “packages”, in a similar way that C++ uses namespaces. A package is a folder that contains class files, and is usually named according to Java naming conventions; for example since my website is www.jacobalbano.com, my classes are in the folder hierachy com/jacobalbano/, resulting in the package com.jacobalbano.
The beauty of this system is that the source is always exactly where you expect it to be, as opposed to in C+, where hunting down a class definition in a source tree can be a pain. Additionally, there is no concept of definition and implementation, since each class is contained in its own file.
Getters and Setters
In C++ classes, modifying or accessing private member variables requires two functions, usually defined as SetVariable() and GetVariable(). Actionscript streamlines this pattern with getter and setter functions, which take this form:
public function set ID(param:uint):void
{
this._ID = param;
}
public function get ID():uint
{
return _ID;
}
This allows access to the private variable _ID like this:
var Foo:uint = myClass.ID; myClass.ID = 42;
The beauty of this system is that it allows the convenience of a public variable without the problem that setting a variable is often not enough. For example, to start an animation with a class in C++, you’d have to use the following style:
myObject.PlayAnimation("walking");
The PlayAnimation() function in the above case might stop the current animation and start the one specified in the function’s parameters. In Actionscript, the procedure would be the same, but the interface is different:
myClass.animation = "walking";
In this case, the setter function would perform the same actions as PlayAnimation(), but in a cleaner way, in my opinion.
In addition, member variables can be made read-only or write-only by eliminating one of the functions.
Super() and function overrides
When extending a class, functions of the base class can be overridden with a function implemented in the derived class. In addition, the base functions can be accessed with the super keyword. For example:
public override function update():void
{
super.update();
this.DoStuff();
}
The base function update() is overridden by the derived class, but it is preserved so we can still access it.
Function pointers
I’ve tended to shy away from using function pointers in C++, even going as far as to embed a Lua interpreter to bind actions to a GUI. Actionscript makes it easy to store and use function pointers with the Function type.
Things I dislike about Actionscript:
Syntax
This is a big one. Actionscript’s syntax (and that of any other ECMAscript-derived language) is close enough to C that I didn’t have a hard time picking it up, but some of the changes are clumsy. I would say the biggest offender is variable declaration.
var variableName:variableType = new variableType;
This introduces another gripe I have…
Actionscript is a GC language.
I know it isn’t cool to manage memory yourself anymore, but I like the control it gives me over the program. Actionscript is very picky about what may and may not be deleted.
Actionscript doesn’t have Enums
Enums are a fundamental part of my programming workflow. I can’t think why they wouldn’t exist within the language, but they don’t.
Actionscript has limited support for class templates
The only class that has template support is the Vector class, and templates aren’t exposed for implementation into custom classes. I managed to fake it a bit, but it’s far from preferable.
Actionscript is platform-specific
I wouldn’t even consider learning a language if it didn’t run on Linux. Fortunately, Actionscript can be developed, compiled and run on Windows, Mac and Linux natively. In this case I refer to the fact that Actionscript only really runs on the Flash or Air VMs, one of which has been discontinued on Linux, and neither of which has particularly good performance.
Actionscript allows developers to be lazy
The Flex compiler won’t complain if you miss a semicolon. Forgot to define a return type for a function? Don’t worry, the compiler doesn’t care. I compile my C++ with every possible warning enabled, so this is another thing that bothers me a lot.
Actionscript doesn’t support overloading
In Actionscript you can only have one function per function name, even if the parameters are different between declarations. This means that you can only have one type of constructor, which gets awkward. In addition, operator overloading is not allowed, so if you want to trace your custom class you’re out of luck.
There’s a lot to like about Actionscript, but it has its fair share of ugly features and anti-features. If not for Flashpunk and FlashDevelop I would have given up on it by now. Ironically, Flashpunk is the best framework I’ve ever used, period, and Flashdevelop is the best IDE I’ve ever used, period. At least they make the language bearable while I have to use it.
Implementing std::pair in Actionscript
One of the things that bothers me about Actionscript is the lack of templates. The Vector class is their only appearance, and since Adobe hasn’t seen fit to open up the feature for general use it looks like that won’t be changing anytime soon. I’m not very good at using templates in my own C++ classes, but I certainly like to use them as part of the STL.
This week I needed a function to return two values at once. “No problem,” thought I. “I’ll just use a std::pair to store both.” A few seconds later I realized that I was still thinking in C++, so I went around searching for a comparable class in Actionscript, only to find that none existed. This was not to be born.
Therefore I present a class I wrote to fill the gap. It’s compiler safe and mirrors the design of std::pair as much as possible.
Example usage:
// Create a Pair and initialize it to store a uint and a string. var Foo:Pair = new Pair(uint, String); // Store the values Foo.first = 40; Foo.second = "Testing!"; // Create variables from Foo's data var someUint:uint = Foo.first; var someString:String = Foo.second; // Create a new Pair from an existing variable with the static function "copy" var Quux:Pair = Pair.copy(Foo);
I haven’t done a huge amount of testing, but I’m happy with how it works so far. As usual it’s open-source to do with what you want. The repository is here.
GruePunk
One of my two assignments for the first week of my game development class was to create a “Choose your own adventure” game. The result was GruePunk, a first-person adventure based on Zork (playable version here). I’ve been trying to figure out an elegant way of embedding the .swf in my website but I can’t seem to make it work and look right at the same time, so you’ll just have to grab the file from the Bitbucket link.
I’d literally never touched a line of ActionScript in my life until three days before starting the project. The week it took me to finish it was exhilarating, if only for the pace I put myself through. While there are many things about ActionScript that differ from C++ in a good way (function pointers in particular are a thing of beauty), there are many that I dislike, and quite a few that had me hung up for hours until I figured out what was wrong. Still, the fact that I learned an entire new language in a week is something that still makes me all kinds of happy.
What are you waiting for? Go get the source or play the game!
What is a game?
I’m taking a class in “Beginning game development”, because I’m a total beginner at game development don’t you know. Anyway, one of the assignments for the first week was to write a report defining what a game is. I’m posting the text here, because why not. I feel like I did a fairly good job, but I’m a programmer, not a writer.
What is a game?
Among ludologists — philosophers who study what it is to play — the concept of “game” has many varied definitions. According to Wolfgang Kramer, a game is any activity that includes a set of rules, a goal, a measure of uncertainty or chance, and competition. Sid Meier, the developer responsible for classic video games such as Alpha Centauri, and the Civilization series put it more succinctly: “A game is a series of interesting choices”. While Kramer was writing about games such as Go, Solitaire and dice, and Meier referred to video games in his definition, I believe that either of these descriptions can be applied neatly to any type of game, be it a Half-Life, chess or football.
Can a game really be classified as such if there is no choice? While strategy games often consist of nothing more than an endless string of choices to make, and games like Deus Ex provide a tremendous amount of freedom, others such as Portal often provide a single path to a goal. However, while Portal is as a whole very linear, the player is given great freedom while solving the puzzle. Choice in video games is important as a means to an end. While a game’s ending may not be affected by the player’s choices along the way, the ability to choose his actions throughout is what makes it a game and not a long movie with checkpoints and quick-time events.
Similarly, a game must necessarily involve chance or uncertainty; whether it be that data is generated procedurally or, as is most often the case, that the enemy’s strategy is unknown, the player should never be in complete control, or indeed removed completely from control. If there is no possibility of failure, there can be no option to win. This is parodied in Portal 2, when one “puzzle” is solved by pressing one button. If chance is removed from the equation, playing the game is reduced to a rote sequence of actions.
All games must have goals, for obvious reasons: it is impossible to win without them. However,
goals are not always specified, and must be discovered or set by the player. In Minecraft or the sandbox mode of Just Cause 2, where no set goal exists, the player will invariably set a goal for himself, from building the Chichen Itza to destroying an entire enemy camp without taking damage. This is not bad game design; quite the opposite in fact. Sandboxes, even more so than strategy games, are probably the best example of games as a “series of interesting decisions”.
Another thing all games must have is a set of rules to govern player conduct. In board games rules are more intrusive that in video games, as an intimate knowledge of the rules is necessary to proceed. However, rules in a video game, while it is not necessary to know every one, are equally important, and even the most nonrestrictive game has hundreds of rules that are essential to maintain consistent behavior. Without order there is only chaos.
Finally, a game must have competition. In games like Call of Duty, Battlefield or Unreal Tournament, the competition is supplied by other human players striving for the same goal; whereas a single-player game like Half Life provides competition in the form of computer-controlled enemies. In this context, however, “competition” can refer to anything that prevents the player from reaching his goal. In Portal, for example, the competition comes not only in the form of hazardous environments, turrets and time limits, but also from the player’s own ability to look objectively at the puzzle and solve it given the tools at hand.
Personally, I think Kramer and Meier’s definitions go well hand-in-hand. I feel that the most important requirement for a game to deserve the title is that of choice. In recent years video games seem to have been straying towards a more cinematic style, frequently removing control from the player to ensure that he sees what the game designer intended, or to perform some action that would be impossible due to the rules of the game. For similar reasons, I don’t consider “You have to burn the rope” to be a real game. An excellent parody, to be sure; but not a real game.
Hurricane Irene — Day one
To be honest I didn’t think Hurricane Irene was anything to worry about. Turns out I was right — what ended up hitting my part of New Hampshire wasn’t even classified as a hurricane anymore; just a tropical storm. No matter what you call it, Irene hit us hard enough to put a damper on my day.
It started out like a normal Sunday…the kids awake, dressed and ready to go, the parents sitting infuriatingly in bed having coffee while I wander around wanting to leave. I hadn’t even considered going to church this morning because of the rain, but my Dad said he was going, and that was good enough for me.
On our way down the road we watched out the windows at the stream that runs alongside. Usually it’s a tiny little brook, but today it was a raging torrent, easily two feet higher than normal. At one point when the road dipped too low we had to drive through water that came a few inches up the wheels. We decided to leave church as soon as it finished to get home before the roads washed out. Of course, even that was too late.
On our way back the water had carved huge gashes in the road. We tried a few different routes but no luck; our best option literally got us within an eighth of a mile from our driveway before we couldn’t go on. Some friends offered to put us up at their place until we could get home, but we needed to get home and make sure everything was okay. We managed to get a ride most of the way up the mountain, then walked the rest of the way. Here are some pictures from our walk.
- Ben in the ditch
- Ben in a bigger ditch
- Water is quite a thing
- This ditch is just brutal.
- There’s the driveway
We’re home now and the power’s out, so we hooked up the generator to the sump pump to pump out the eight inches of water that got into the cellar. It just finished now, two hours later. Even though the power is out the phone lines are fine, so our DSL modem is plugged into the generator now. I’m anticipating that it’ll be a few days at least before we can get out of here, but we’ve got food in the fridge and enough gas to keep the generator running for a good long time. Life could be a lot worse.
Sleeping Ugly
So my siblings and I spent yesterday working on a movie that my little brother wrote. I don’t appear in the film (which is just the way I like it), since I was the cameraman. It’s live on Youtube now, so here it is for your viewing pleasure:
Sleeping Ugly is production of epic proportions, filmed on location in a grand castle in the highlands. Produced, directed, edited, written and starring the famous Benjamin Albano, this film has critics everywhere raving.
Praise for “Sleeping Ugly”:
“Fabulous! My mouth was open the entire time.”
~ Kate Winslet, Actor
“This film brought me back to my childhood as a wee lad in the old country. I wept throughout.”
~ Billy Connelly, Actor
“The score took my breath away.”
~ Hans Zimmer, Composer
“Some of the best battle scenes I’ve seen in any movie. Ever.”
~ Yuen Wo Ping, Martial arts choreographer
“After seeing Sleeping Ugly, I don’t think I could ever make another movie again. With this production, film-making has reached its zenith.”
~ Baz Luhrmann, Director/Producer
“I ask myself, why didn’t we ever think of this?”
~ Michael Palin, creator of Monty Python
Should have seen that one coming
Well, as happens most times when I think I’ve got it all down, further investigation reveals quite the opposite. Long story short, my camera doesn’t work in all cases. Long story long, keep reading.
To determine the furthest distance between focus points (the 2d positional vectors that my camera must keep in view at all times) I was using std::max_element and std::min_element, like so:
sf::Vector2f max = **std::max_element(FocusPoints.begin(), FocusPoints.end(), Vec2Predicate); sf::Vector2f min = **std::min_element(FocusPoints.begin(), FocusPoints.end(), Vec2Predicate);
where FocusPoints is a container of const references to 2d vectors, and Vec2Predicate is a function pointer for sorting the container by. This is where I made my fatal mistake.
How do you determine whether one point on a Cartesian grid is greater or lesser than another? As far as I know, you can’t. You can tell which is greater on an axis, but that’s it. My function Vec2Predicate compared two vectors on the x axis only. At first it seemed to work fine, but I ran into problems when the focus points were aligned with each-other on Y. As best as I can figure, min_element and max_element were returning the same element. Thus, the distance between the two points was always zero, and the camera never zoomed out. This resulted in actors getting awkwardly close to the edges and, in some cases, going off screen while the camera did nothing.
For obvious reasons, I’ve decided to do away with the entire system involving distance between points and instead use bounding circles. Here’s my plan for the new implementation:
Each frame, loop through the list of focus points
Find which Cartesian quadrant each point lies in
Test a point three meters towards each of the two nearest walls
If either point is off screen, break the loop and zoom out
If the loop finishes without any test points extending past the bounds of the screen, zoom the view in.
I’m really hoping it’ll work…I’ve spent far too much time on this facet of the engine and I’m longing to move onto something else.
Building an intelligent camera
My graph system is working nicely with multiple resolutions, but I realized while working on it that I’ve essentially locked myself into having every scene the same size. While not necessarily a problem, from a design standpoint it really isn’t conducive to the type of levels I want to implement. Of course, allowing scenes to exist that are larger than the size of the screen introduces several new problems, namely:
- The camera needs to keep all actors in view at all times
- Additional detail will be needed to surround the accessible area
That doesn’t seem too hard, right?
Hah!
Easy stuff first: The camera is going to need to center itself between all points I tell it to focus on. All I have to do is get the average value of all positions. Fortunately this actually happened exactly as I thought it would.
Now on to zooming. Essentially, I check distance between the two focus point furthest from each other. If it’s over a certain length, zoom out. If it’s under, zoom in. Stop zooming in once the view is a certain width, so it doesn’t zoom in to eternity.
Seems simple enough, right? That’s what happens when I write up a blog post after the fact. I really should start writing these while I’m in the thick of things…




