Category: games

5 Stars of Ambiguity

Originally posted at my Ludum Dare blog

(more…)

Game Review: Iron Tank (NES)

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:

  • Radio communications screen for narrative elements (Bionic Commando, Metal Gear). The radio will sometimes give you warning about upcoming challenges, or some mission background to explain why you’re here and what you need to do. This is mostly inessential because the mission is always “Stay alive, destroy enemies, and advance, and destroy a boss.” but it still gives the game a story of sorts. Often the radio message will be “too late” advice, warning you to be careful about a challenge you just got through. Toward the end, the enemy starts broadcasting to you, threatening/begging out of desperation to get you to turn back. This boosts your ego, and is a neat reward for the player.
  • Configurable power up system (many NES games featured this, but Iron Tank’s is unique in its implementation, but perhaps could be described as a combination of Mega Man and 1943.) Your main gun has four different types of power boosts — Long range, Rapid fire, Armor Piercing, and Bomb shells — which you refill through pickups.The pickups are odd in that they are letters which sometimes don’t have an obvious relationship to the power boost they represent. L = Long Range (ok, fair); V = Rapid (velocity?); F = Armor piercing (huh?); B = Bomb Shells (right). Rather than remain enabled until expended or a timer runs out, you can enable/disable them on a sub-screen as needed. This means there’s strategy to the game — you can save up your power and use it when you hit a really tough spot in the game. Managing your power-up resources is critical to winning. Knowing when you need them, and deciding what you need at a given time, and balancing that against the yet unknown challenges that lie even further ahead makes for a cerebral game that layers on top of the action game. There are times when an obvious approach of using power-ups isn’t really necessary, because a subtler strategy will enable you to get by with a stock configured tank, and it often pays off to take the harder challenge now, conserving the power boosts for an even more difficult challenge later.
  • The most interesting power-up mechanic is the [R]efuel tank, which gives you a secondary life bar that extends your primary life bar — but only if you choose to have it enabled. Another interesting thing is that you can both shoot and run over foot soldiers — and the game seems to encourage you to run them over, as doing so gives you a tiny but vital boost to your main energy.
  • Infinite continues, and a password save feature, allowing the game to be longer than would otherwise be practical to beat in one sitting, and not punishing the player too severely for not being able to make it through the challenging parts of the game, and allowing therefore for those parts of the game to be even more challenging.

Basic gameplay

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

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.

Graphics

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.

Music

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.

Enemies

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.

Terrain

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.

Destructible terrain

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.

Multi-path map

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.

Map x-wrapping

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.

Overall

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.

See Also

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.

LD48 #24 picks

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…)

D’oh! Game Maker Studio requires a Mac to build an OS X game

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 generation in game programming

Random number generators are extremely useful in game programming. I have found a lot of uses for randomness in my projects.

What can you do with randomness?

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:

Unit stats

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.

Sprite generation

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.

Colors

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.

Map generation

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.

AI

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.

GameMaker/GML random functions

These are built in to the Game Maker Language (GML):

  1. random(N): returns a random floating point value between 0 and N, not including N.
  2. random_range(A, B): returns a random a floating point value between A and B, not including B.
  3. irandom(N): returns a random integer value between 0 and N.
  4. irandom_range(A, B): returns a random integer value between A and B.
  5. choose(a,b,c,d,e,f,g,h,i,j,k…): Randomly returns one of the arguments, up to 16 arguments may be passed into a GML function. You can weight the likelihood of one result by repeating it in the arguments list. (e.g., choose(dog, dog, dog, cat) would be 3/4 likely to return dog, 1/4 likely to return cat.)
  6. random_get_seed(): Gets the current seed value for the randomizer.
  7. random_set_seed(): If you need a randomized, but deterministic function, you can set the seed for your random function. (This approach of setting a known seed is how the levels in Pitfall for Atari 2600 were always the same even though they were generated by the Atari’s random number generator.)
  8. randomize(): Sets the seed of the randomizer to a random value.

These are scripts you may import into your project:

  1. gauss(median, deviation): Returns a random value with a gaussian (“normal”) distribution around a median value. From GMLScripts.com.

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!

Keeping randomness under control

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.

Know your math

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.

Testing

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.

Game Maker HTML5 and WordPress

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.

Karyote (Enhanced)

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.

 

Ludum Dare 24 Postmortem

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:

(more…)

LD48 24: Evolution. Karyote alpha

It’s not much at all yet, but I have an alpha build of my entry for Ludum Dare 24: Evolution up and running in HTML5.

Karyote

It’s not really playable yet, at the moment I’m just working out some motion and object prototypes. Graphics are all placeholders. You’re always in the center. Move with the arrow keys. Left/Right turns, Up moves forward.

Somehow, I’m doing another game with a microorganism theme. LD#23 was Bactarium, LD#24 will be called Karyote. You control a single celled organism that mutates as you play.

I still need to figure out what exactly you’re doing in the game, but I have some ideas that I haven’t implemented yet, so I’m a little further along than it looks as far as the concept goes. I’m designing as I go, mainly this is design by fiddling around. That’s a dangerous way to go on any project, but when I don’t have much of an idea to begin with, I find it’s one of the most reliable ways of getting me going. Hopefully I’ve learned enough lessons from previous projects to avoid messing up the code architecture, so debugging and feature changes don’t turn into a nightmare toward deadline.

Ludum Dare 24 This Weekend

It wasn’t that long ago (late April, in fact) that I participated in my first Ludum Dare. I really enjoyed that experience, and am really looking forward to Ludum Dare 24 this weekend. I’ll be hanging out this weekend at our Cleveland Game Developers LD48 site, generously hosted at the Shaker Launch House space.

I plan to work solo, and entering my game into the compo, again, but one of these times I’d really like to get into a team and work on something as a group. For the weekend, I’ll be blogging on my page on the LD site, so be sure to check there and see how I’m doing.

I’m trying to think about my goals for the last LD48, and how I’ve grown since then and what my new goals should be.

LD 23 goals:

  1. Finish a solo project in 48 hours. Achievement unlocked!

LD 24 goals:

  1. Blog my progress as I go, self-documenting the development process. Last time I blogged a little bit, this time I want to take that further.
  2. Post playable builds as I go, not just at the very end. Last time I saw other people doing this, and I felt envious as they got feedback from people playing sneak-preview releases of their projects. I was super impressed that they managed to release something playable so quickly, but I have some ideas about how to accomplish that.
  3. Produce builds for Windows, OSX, and HTML5 to reach a wider audience. Last time, I was still using Game Maker 8.1 Professional for my project, which limited me to Windows. This time I’ll be using GM:Studio. This will be my first project targeting multiple platforms, so kindof a new thing.
  4. Use fellow CleGameDevs people for feedback and encouragement. We used IRC for this, and had our first night at a common space, which was good. I just want to do this more.
  5. Play and rate more entries. Last time I did play a lot of games during the rating period, and played even more after the rankings were posted.

Incorporating music into my game will probably remain a future goal, for now. I’ve experimented a little with FamiTracker, and may attempt to produce a little music for my game, but I still think becoming a chiptune artist is a far-away goal. I think music is a really important element of videogame design, but it’s probably better to have no music at all, rather than bad music. There are certain game themes which lend themselves to silence, so I can possibly use that, or I can make a game that has an overwhelming amount of sound effects in it, like my last LD48 entry. Or maybe I’ll get lucky and one of our musically talented CleGameDevs people will throw me some resources, and I’ll make it a Jam entry instead of a Compo entry.

Tonight and tomorrow I plan to go over my preparation checklist and make sure I am ready. Gotta make sure all my software is up to date and working properly.