Originally posted at my Ludum Dare blog
5 Stars of Ambiguity
Originally posted at my Ludum Dare blog
Originally posted at my Ludum Dare blog
Iron Tank (1988, SNK) is a mostly-forgotten title for the NES, but deserves more recognition than it’s gotten. I think of it as a spiritual companion to the other great NES WWII Shooter, Capcom’s 1943.
Many of its features were successful in other popular games, but it has enough of its own unique strengths that it can stand up proudly as an innovative game with an experience you will find similar to many other games, but still feeling original and well done, not generic or derivative:
There’s a very good “Let’s Play” series on YouTube, if you aren’t familiar or need to get reacquainted. You are Iron Snake, commander of the Iron Tank, invading Normandy and liberating Europe from an implied but unnamed Nazi occupation. And by “liberate” I definitely mean “blow the hell out of.” Actually, there are occasional resistance fighters and POWs who you’ll rescue throughout the game, as well.
Controls are often a weak point in games featuring tanks. Not so in Iron Tank. Your tank features an aimable turret, which allows you move and aim independently. The way this was implemented on the standard NES gamepad was effective — hold button B and the D-pad controls the turret. This takes a little getting used to, but is very effective and you can be quite nimble with practice. Being able to aim to the side or diagonal and strafe is an important tactic, and makes the game more realistic and more fun.
There is a huge variety of tile-based backgrounds, for simulating the European countryside, cities, docks, airplane hangers, the Normandy beach, cliffs, trees, roads, paths, rail tracks, fortresses, you name it. Even for the 8-bit NES, these are a little rough in spots, though never truly bad, and the variety makes up for it.
The music in Iron Tank is really first rate. It is heroic and epic, evokes both the military marches and the WWII era, adds drama and tension, and provides cues to when more challenging areas are up ahead. Most of the music is in the lower and mid octaves, which gives it a characteristic unlike most other background music on the NES, while seeming suitable for a game about tanks.
There really isn’t anything in Iron Tank sophisticated enough to call AI. The enemies all move in basic, simple patterns and pre-set routes, but a lot of variety makes the game challenging. Some tanks sit still, others chase you, while others seem to stand off at a distance and duck and feint, and still others will enter, make a quick attack, and then retreat before you can retaliate.
There’s also a great variety of enemies: infantry, officers, tanks, train guns, fortresses, turrets, and boss tanks called “Think Tanks”. I guess they’re hard enough that you need to think about how to defeat them? You even do battle with airplanes and submarines. Of course tanks are the star of the game, and there is a satisfying variety of enemy tanks, different styles of light, medium, and heavy, which vary in their speed, armor, and armament. Some are barely any threat to you, while others necessitate caution.
This variety of enemies invites a variety of tactics, which keeps the game fresh and challenging. The key tactic is avoiding being in range of the enemy cannons, flanking the enemy’s turret when you can, or when that isn’t possible, waiting for a pause in their fire and placing a well-timed shot to take them out. You can also sometimes use your long range shots to safely take out enemies before they’re able to engage you with their own armaments. Individually, their cannon fire is usually not too hard to dodge, being limited to 8 directions, resulting in predictable pie slices of safe zone. It’s not too hard to take out enemy tanks when they don’t outnumber you too badly and there’s plenty of room to maneuver. Sometimes moving slowly and cautiously, taking out the enemies one at a time, picking apart their defenses is the best approach, other times it’s better to just run for it.
Some terrain is more open than others, however. The variety of terrain matches the variety of enemies and enemy tactics, and itself influences the tactics that will be most effective in a given area. Although the game is 2D, there are simulated ledges, cliffs, and rooftops where placed guns can harass you, sometimes out of your own reach unless you have some power boosts enabled. There are walls and buildings and natural barriers that can constrain your movements, but provide cover in return. Water likewise blocks your path, but leaves you exposed to fire.
There are wooded areas where the tree canopy foregrounds partially obscure the action beneath them. The NES didn’t have a capability of alpha channel, but they still made the forest sprites partially see-through, so that when you go under them, you can see the unobstructed part of your tank (or lurking enemies) through them. This is really cool.
Insta-kill anti-tank landmines will block your progress along otherwise open and inviting pathways. They blink, being invisible half the time, so can be difficult to spot.
While not dynamically destructible, there are enough buildings and walls that you can blow up to uncover secrets or alternate paths that it’s worth mentioning. Being in a tank and not being able to destroy these things just wouldn’t feel right.
I don’t know of any other NES game that did this, so Iron Tank deserves special recognition for this design. At several points in the game, you’ll encounter road signs that point out a fork in the road. Depending on which path you take, you’ll proceed to a different level, with different terrain and enemies. One path might be more difficult, but you have no way of knowing before you make your choice. This means that in order to experience every bit of the game, you’ll need to play through it multiple times.
Instead of having an edge, the map wraps on the x-axis. There are certain places on the map where there are no side walls, and you are unbounded in your horizontal direction, but in these locales, the map wraps around. While not exactly realistic, it does make for some potentially useful tactics, as you can return to an area by continuing in one direction, without needing to double back.
Iron Tank is a solid effort from SNK. The game integrates a lot of the features and design elements of successful NES classics, and does it well. While mainly an action game, the story elements provided by the radio communiques and the configurable power-ups give an element of strategy almost like a proto-RPG. It’s one of my favorite lesser-known games on the NES.
If you liked this game, you’ll want to check out 1943, Guerrilla War, Commando, Jackal, Heavy Barrel and Ikari Warriors. All have a similar WWII/war theme and vertical scrolling shooter gameplay.
Yoyogames just released Game Maker Studio 1.1. It looks like there are a lot of positive new developments happening with the platform, and I’m really excited about a few of them. Lots of good new features!
YYG has changed the pricing structure again. The exiting news (for those who may have been reluctant to try Studio due to its higher cost) is that there is now a free edition, which gives beginners a way to get in to try things out. Unfortunately, Studio Free is more feature-restricted than the old Game Maker Lite. The 8.x line is still available for download and purchase, at the same prices as before, but the old version is a bit further deprecated now, lacking prominent position on the YYG homepage.
The new Standard Edition is still just $49, no different than Game Maker 8.x Standard. Professional remains at $99, with the same price for the additional modules that you can buy separately. Or, if you want everything all at once, you have the option of spending $499 for Master Edition, which saves you $99 over the cost of Professional + all the additional modules.
I haven’t heard whether they’re planning to allow early adopters of Professional to move to Master Edition at a discounted price yet, but even if they don’t it’s nice to see the price coming down.
Another nice freebie is that Professional allows you to test Android apps, even if you don’t have the license for the Android module. I’m particularly looking forward to finally getting into mobile development. I had not yet spend the money on the mobile app modules, so the free testing on Android is a great thing for me to get my start on Android.
Gone from the site is any mention of a Symbian module. I’m assuming that since even Nokia is giving up Symbian OS and has gotten in bed for better or worse with Microsoft’s Windows Phone 7, we may in time see a module to allow Windows Phone as a build target. [Update: on 9/20/2012 YoYoGames announced that Game Maker Studio will target Windows 8 and Windows Phone 8 platforms.]
I’d like to voice a desire for a linux build target module. Since Android and OS X are both based on unix, I’d hope that extending support to Linux would be feasible.
The new audio engine and room designer are welcome, and I’m interested to see what they offer. One of the audio limitations in Game Maker that I’ve wished to overcome is generating sounds procedurally. I see a lot of potential in musical games where the game objects can generate different tones and pitches depending on what’s going on in the game. Whether the new audio engine allows this or not remains to be seen — I haven’t had time to play with it yet.
The room editor improvements are always good to see, as well. I’d like to see YYG continue to develop the editor into a more usable level editor, with faster UI access to the different objects and tiles, so that building rooms becomes less tedious.
I’d also really like to see them provide some built-in room templates for “boilerplate” things such as the title screen, configuration screen, achievements and high scores, load/save screens, etc.
The really exciting new feature is the Developer’s Portal, with its analytics and monetization features. This will make it far easier for independent game developers to realize a return on their investment in the more expensive Professional license, and hopefully will help quell criticism of the higher pricing. Reducing the effort needed to make money with Game Maker is huge. I’m really looking forward to delving into these features and learning all about them.
Anytime a new version gets released, I think about features I’d like to see. My current list:
I am probably going to curl up all weekend with betterexplained.com and brush up on my math. I haven’t been this excited to read about mathematical concepts since I was a high school senior and discovered William Poundstone’s The Recursive Universe. Which was really more about information theory, but that’s a type of math.
What compelling reads in math can you recommend?
There were 1406 games submitted for Ludum Dare 24. I probably won’t get to play more than a tiny fraction of that number before the judging is over.
As a judge, I believe my goal should be to play every game, but given the time window and the number of entries, that’s not very likely to happen. So sadly, I end up picking games somewhat arbitrarliy from among the entrants, usually based on the thumbnail screen shot and/or title being interesting.
One strange thing I’ve noticed about LD’s website is that when browsing through all 1406 entries, I will notice that the ordering seems to be random. I expect this is to shuffle the games up so people will have a better chance of playing games that otherwise would be buried at the bottom of the list. But a side effect of this is that no matter how many times I page through all roughly 50 pages of games, I invariably miss many — it seems the shuffle re-randomizes while I’m paging through, and I end up seeing some games twice and therefore obviously must be seeing some games zero times. This is kindof annoying and I wish I could get all 1406 games on one page somehow.
I’ve just taken a walk through the submissions and grabbed the title and URL of the pages of the entries that looked like they might be interesting. This is a completely arbitrary process and I spend maybe 2 seconds looking at each game before deciding whether to pick it up and play with it, or skip it and move on. So don’t feel slighted if I missed yours — if it was any good, most likely I’ll discover it anyway after the judging is over.
I don’t want to skew the judging by recommending games, but for non-LD participants who can’t judge, there’s no harm in sharing a list of links to games I think look like they might be cool. In all likelihood, probably a lot of these are terrible. I haven’t played them yet and this should not be considered a recommendation or endorsement; it is merely a list. (more…)
So, last night, for the first time I tried building a Game Maker Studio project to OS X. I was a little surprised to discover that apparently GM:Studio needs to connect to a Mac OS X system in order to complete its build process. This makes it a little bit of a problem to build OS X projects.
I guess the upshot of that is that it means that it is impossible to create OS X builds in a dev environment where there is no means to test them. On the other hand, I guess the true cost of Studio is around $2500 since I have to buy a Mac. But hey, I suppose that could be a tax deductible expense if I’m buying it for business purposes. I know they make them cheaper, but I probably wouldn’t buy a mini. Eh, maybe. I’ll have to kick it around and decide, but I’m more into the idea of getting a MacBook Pro.
Random number generators are extremely useful in game programming. I have found a lot of uses for randomness in my projects.
Man, all kinds of stuff. Nearly any value that you want to initialize in a game object is a candidate for possible randomization. Randomness fuzzes up your game, making less deterministic and therefore harder to defeat with simple patterns and more replayable.
Pretty much any time I would normally use a literal or a constant number in my code, anymore I step back and ask myself what range of values might work in that place, and then create a random function that will provide me with a number in that range. The only time I don’t do this is when I really do need a precise value, or when performance is too important to sacrifice the computation time needed for the random function to return its result.
Here are just a few ideas for how you can use random numbers to improve your games:
Nothing makes a video game feel more like a video game than when every enemy you encounter is an exact clone of all the other enemies that look like it. You can use randomness to give your enemies some personality by giving them randomized stats. Instead of fixed values for Attack, Defense, Speed, Damage, etc., use a random range of values to generate stronger and weaker versions of your enemies. It takes a little more time to compute these values on the fly, but modern processors can handle this load easily, unless you’re generating a huge number of units.
Why spend a lot of time hand-drawing every sprite in your game? Create a generator system that randomly puts pieces together, and create random sprites on the fly. If you’ve played around with an avatar generator such as eightbit.me or the Mii generator on Wii or the XBox Live Arcade avatar generator, imagine that kind of model system, but with a random selector in charge of picking the hair, eyes, etc. You can do this to randomly generate other things, such as buildings, procedurally, as well.
If you’re calling drawing functions, randomizing colors can give your game a lot better visual appeal. If you’re clever in how you pick your random colors, you can come up with color schemes that work nicely, yet are always slightly different each time you play. You can either pre-define a palette of colors and randomly select one, or you can randomly select R, G, B or H, S, V numbers and create a color at runtime. You can experiment with different mathematical tweaks to shape and constrain the randomness.
If you can write a good random map generator, you can save yourself from having to hand-design all your maps. GOOD random generation may be very difficult to accomplish, however — especially for more complex games. But even if you can’t guarantee a good random map at runtime, an almost-good random map generator can save you tons of time or spur your creativity by doing most of the work for you, leaving you with something almost good enough, that just needs a little hand-polishing to make shine.
Procedurally generated content in general is a good use for random functions. You can use a random number function to create a deterministic sequence of generated values that is always the same. This is because computer hardware actually does not have a means of creating a truly random number — it fakes it, approximating randomness with a pseudo-random algorithm.
This is used to good effect in one of my favorite Atari 2600 games, Pitfall. A pseudo-random function, using a fixed seed, is used to generate each screen in the game. This achieves a very high information density, since the data that was needed to represent each screen could not be stored on a 4kb ROM, but a generator function that creates that data easily could. This technique is not used very much in modern game development since storage isn’t much of an issue any more, but it is still a very interesting technique and one which merits study.
There are many potential applications of randomness to AI. Whenever your AI needs to make a decision, you potentially can use randomness to make that decision less predictable. Weighted probability is important here, as completely random AI behavior is erratic and seems crazy, while an AI that occasionally does something unexpected will seem tricky or deceptive or clever. Dynamically weighting the probability according to context at runtime will make your AI seem smarter.
These are built in to the Game Maker Language (GML):
These are scripts you may import into your project:
All programming languages have similar random functions or classes built into them. Whatever tool you happen to be using, it pays to learn about how it can produce random numbers, and how you can use them to do useful and interesting things.
If you have any favorite ways of using random numbers in your programs, post a comment below and share it!
One of the mistakes most game developers will make when using random functions is to use too wide a range of random values, or failing to control the range of values returned by the random function.
Randomness feels most random when the probability distribution is flat. However, this often does not make for the most interesting gameplay mechanics. It’s often more useful to have a weighted function that has a greater probability of returning a value in one part of the range than in another. Understanding probability math is key to getting your randomized functions under control. The other key is to develop your intuition to know what range of values will work best for a given situation.
If you’ve ever played tabletop role playing games, then you know about dice. Dice are good analog randomizers, and can help us understand probability and randomness in a computer program. In classic Dungeons & Dragons, character ability scores are randomly determined by adding the values of three six-sided dice. This results in a bell curve, meaning that the results of a 3d6 roll are distributed in such a way that an “average” score between 9-12 is far more likely than an extreme score of 3 or 18. So one way to directly simulate this type of dice rolling in a computer program would be :
N = 0;
repeat(3){N+=irandom_range(1,6)}; // generates a value between 3-18, distributed around 10.5
In computer programming, there are more efficient ways to achieve a bell curve distribution than this. Calling random() multiple times, and writing loops will make your code slow, so if there’s ways to avoid doing that, it’s a good idea. The gauss() function from gmlscrips.com creates a “normal” distribution around the agrument passed into it, and is fast and efficient.
round(gauss(10.5, 3.5)); //simulates rolling 3d6, approximately
Note that this will not return exactly the same distribution of values as a true 3d6 roll will. But this is because 3d6 is actually an approximation of a gaussian distribution — the gauss() distribution is more accurate to a “standard normal” statistical distribution. If you compared graphs of the bell curves of 3d6 vs. the gauss() function, the gauss curve would be smoother, and would include values outside the 3-18 range (2 and 19 would show up a tiny percent of the time).
There are other types of distibutions that you might want to achieve with your randomized functions, for some purpose. Knowing your math is important here. Learn the graphs of common functions, and understand the relationship between the shape of the graph and the probability distribution of a randomized function modified by each function. For example, random(x), ln(random(x)), and random(x)^2 have very different looking distributions. Knowing this, you can tailor an equation to fit your needs.
Once you get comfortable with the math, it’s actually fun. Play around with a graphic calculator and see what different graphs you can come up with. Each time you discover an interesting or useful shape, make note and file it away for a time when it might be useful.
Because adding randomness to your functions make the game non-deterministic, it can make things more difficult to test. Certain conditions become hard to duplicate, because you don’t directly control them, and this can make repeatable testing of your game seem impossible.
There are approaches you can take to ensure that your code works, still. First, when you are building up your functions, ensure that the non-random parts of the code work well before you introduce randomness. If necessary, temporarily remove the randomization and replace it with a literal value, a constant, or a variable. Once you are have tested thoroughly and are sure the code is working correctly with a range of controlled values, you may safely replace the controlled values with random values that are constrained to the ranges you tested.
In some cases, you may need to go back and re-test code. It would be a pain to have to find/replace every random() call in your code. Not only would it be time consuming, it would increase the opportunity for errors to creep in. A better approach may be to comment out the equivalent non-random code next to the random code, and leave it in your code file. That way you just have to comment out the randomized function and un-comment the deterministic version.
Even this is time consuming and error prone, however. You may want to create randomized and non-random versions of your functions, and introduce a configuration variable that you can toggle to enable/disable randomness. Then you can pepper your code with things like:
if settings.random {randomized_function()} else {deterministic_function()};
All this extra branching in your code can get ugly and unmangeabeable too, so try to limit this to keep it to a minimum.
You could also use polymorphism to create sibling classes, one which inherits randomized functions, and one which doesn’t, and just spawn the appropriate class instances according to the game configuration at runtime.
The great thing about being able to turn randomness on or off at runtime is that it allows you to very quickly see the difference, reducing the lag time between test runs. This could even turn into a feature of the game, rather than a debug exercise.
With proper care taken during development, randomized functions can be just as reliable as deterministic functions. It just takes a little extra forethought and planning.
Site traffic on the WordPress portion of csanyk.com is up due to Ludum Dare. According to my Jetpack stats counter, got about double my usual visits on Saturday, mostly as a result of posting my alpha build of Karyote. Traffic yesterday was about at the same level. It’s too early to know whether the increase in traffic will be sustained or not, but I’d expect there might be a small bump with a long tail.
This does not include hits of the actual Karyote game url, which is not hosted within my WordPress site. I haven’t looked at the awstats numbers yet, but I’m kindof curious to know many people are playing the game now.
I’d like to get my Game Maker HTML5 games better integrated to WordPress, but (as of the last time I played with doing that, during the GM:HTML5 beta, at least) it is tricky, and I haven’t gotten it working right yet.
Game Maker Studio auto-generates a basic HTML5 page for your game when you build it, but it’s not a simple matter to cut and paste the necessary code from that page into a WordPress page.
YoYoGames should probably think about providing CMS integrators so that people can have an easier time packaging their games in a way that allows them to integrate with WordPress, Blogger, Drupal, Django, and other CMS frameworks.
While I’m wishing, it’d also be cool if Studio has a feature allowing you to modify the template used to generate their HTML5 page. That feature could exist for all I know, I need to get more familiar with the HTML5 features of Studio.
Hopefully if they don’t, at least the dev community will step forward and address it.
I’ve patched a few bugs and added some enhancements to Karyote, and plan to make several more changes in the next few days as I’m able. There’s a post about it on my Ludum Dare journal.
I thought I’d write up a little postmortem of the enhancement here:
After struggling with the idea and trying to come up with what the game should be all weekend, and being disappointed with what I was able to deliver by the compo deadline, it’s really interesting to me that I’m actually starting to like this game now that I’ve fixed the first two high priority issues.
What I take from that is that I am better at critiquing and improving something that exists than I am at coming up with something new. That’s consistent with how I know myself, too. What’s interesting to me about this is that I somehow am able to switch from being a “whole cloth designer” coming up with a new game design to a “critic” and when I’m in critic mode, I know just what the game needs, while when I’m trying to develop the design that “designer” mode me came up with, I get frustrated and hate what I’m making. Maybe it’s not so weird, though — it could be all I really needed was to play it enough to figure out what it needed.
Comments I’ve received on my game have been generally positive, as well, which surprises me. I wonder whether commenters/raters apply a sliding scale of expectations when it comes to providing feedback. I mean, it’s one thing to compliment someone on an effort that was good relative to their current ability and constraints. It’s another to say that a game stands up relative to other entries, or even among all games of all time. I think it’s safe to assume that the comments I’ve gotten aren’t expecting LD games to be among the all time greats, and that people are generally inclined to deliver positive feedback and encourage the developer, rather than slam it.
I tend to judge myself more along the “all time” basis, though, which is harsher but also a higher standard to aspire to, and pushes me to do better. So it’s surprising to me when people say they enjoyed something I made when I don’t think holds a candle to Pac Man. But it is really nice to know that people have tried my game and that some of them have even enjoyed it. Getting comments, good or bad, is extremely positive for me. Just having the knowledge that people tried it out makes me feel like it was worthwhile to make it.
I’ve posted a postmortem of my LD48 #24 project, over on my ludumdare.com journal.
After poking around for my old journal entries on ludumdare.com, I think they may purge content, so in case that’s true I’m mirroring the post below, after the cut: