csanyk.com

video games, programming, the internet, and stuff

LD38 results for TARJECTORIES

I think this may have been my best showing to date. I’ve ranked higher in individual categories before (Bad Puppy: #70 in Humor, Alamogordo: #71 in Humor) but I think this is the best that I’ve ranked in Overall and in Fun, which are perhaps the two most important categories. I’m very happy with how the game was received by the LDJam community this time around.

Thanks to everyone who played TARJECTORIES!

ld38 results

 

Great Plays from Ludum Dare 38

Planet Desumaton – siegfriedcroes

Planet Desumation

The gif speaks for itself… Control a small small planet, picking up Asteroids into orbit, and smash them into a large “boss” planet.

Path of the Rabbit – Managore

Path of the Rabbit

A turn based tile strategy game similar to Pipe Dreams. Managore’s games are always top notch, and this is no exception.

Sticky Keys – thevaber

Sticky Keys

A really well polished typing game, with a twist. The keys keep popping off, due to some nasty creepy crawly insects that have infested the keyboard. You have to interrupt yourself and pop the key caps back on in order to keep typing.

Monolith – samlo and david-carney

A rail shooter bullet hell game where you have to lock on to your target by holding still, leaving you vulnerable to enemy fire. It’s high speed and frenetic. The art style is b/w, with what looks to be a procedurally generated fractal landscape, and a monolith that looms over the horizon, and seems to never get any closer.

TARJECTORIES – csanyk

Tarjectories by csanyk for LD48-38: A Small World

Yes that’s right! My own game, this time I think is good enough to qualify as a recommended play. It’s a casual target shooting game played on tiny planetoids that rotate, with procedurally generated levels for added replayability. Patience and accuracy are the keys to doing well. Learn to estimate the gravity and rotation speed of the planet so you can aim your shots correctly. I plan to develop this one a bit further, so stay tuned.

Antivirus – kappaixAntivirus

A nicely designed 2D top down shooter, reminiscent of classics like Gauntlet, 2D Wolfenstein, Berzerk, and Frenzy. When you die you get a fake BSOD game over screen, which adds to the fun. Battle through an area and the size scale changes, making for an interesting and novel transition mechanic.

Plutus – jason-varnell, nathan-hicks, and Apostate Games

Plutus

Hilariously written backstory makes this charming katamari-like feel special. Control the jealous planet (let’s not quibble) Pluto on a quest for revenge and ever greater mass.

Space Mailman – kepons

Space Mailman

Gorgeous but bare-bones wireframe graphics and hard core difficulty make this game tough to play. Deliver mail between planets to make money.

Flight of Claude – lyxil and colm-eccles

Flight of Claude

A beautiful, touching visual story about a baby bird and his nest mates.

Aphosis – urban-logic-games

Aphosis

Divert a doomsday rock on a collision course with Earth by attaching thrusters to stabilize its spin, then attaching a main thruster to push it away. Beautiful graphics, a fantastic musical backing, and extremely challenging game play make this one to try.

That Tiny Pea – thendash

That Tiny Pea

A fairly realistic update of the classic Lunar Lander. Land safely and you are rewarded by being able to step outside and take in the view. It’s hard!

The Life Amoebic – baby-dino-herd

The Life Amoebic

A convincing simulation of an amoeba. Control your amoeba by extending pseudopods with the mouse, and try to grab food to survive, grow, and divide. It’s pretty challenging.

Vixa – spav

Vixa

Spin the world around to dump balls into the green-lit sections and away from the red-lit sections. Green multiplies your balls, red destroys them. Lose all your balls and you’re done. Great graphics and sound, and solid game play make this one a trip to play.

Tiny World Defense – ianmorrison

Tiny World Defense

Fly your spaceship over the surface of the planet, defending it from enemies who want to shrink the planet into nothingness. There were a number of other entries in LD38 with a similar look and feel, a 3D orb-based shooter, where your shots skim over the surface of the planet. Almost like it were a newly-invented genre or something. But out of them all I think this one is probably my favorite of them.

Super Kaiju Dunk City – radmars, emarcotte, steakzzz, ninjavitis

Super Kaiju Dunk City

This is an amazing entry in the Jam category. Super polished, it’s a cross between an infinite runner and a rhythm game, where you control a basketball-dribbling Godzilla-like Kaiju creature, as you relentlessly smash through level after level of targets. I had a blast playing this, and would love to see it as a full-fledged title. There’s not much more to ask for, except maybe an epic boss battle against another Kaiju or super robot, and some kind of breath attack.


That’s all for now… I still have a lot more games left to play. As I find more “great plays” I’ll be adding them here. If you have played something that you think deserves a larger audience, post a comment below.

Until next time!

GameMaker tutorial: high speed collisions

If you have a small object, such as a bullet, collisions can be problematic for GameMaker if the bullet’s speed is faster than the length of the bullet. Any time an object moves faster than its width, it is possible for the object to skip over object in its way that it should have collided with.

The illustration below shows why:

high speed collision skipping

Here’s a simple, elegant solution for your high speed object to avoid this problem, regardless of its top speed.

Make the bullet sprite’s length as long as the bullet’s speed. If your bullet moves 16px per step, then its sprite should be 16px long.

If the bullet’s speed is variable, then the thing to do is vary the length of the bullet as the speed of the bullet varies. You can use this using the image_xscale property to scale the bullet.

Say the base bullet speed is 16px. If the bullet can somehow accelerate to 32px per step, then it should lengthen to 32px, by setting the image_xscale to 2. We can see from this that a general expression that solves the problem for any sprite width and speed would be:

image_xscale = speed/sprite_width

But it’s probably a good idea to use image_xscale = max(1, speed/sprite_width), to keep the bullet from shrinking if it is moving slowly.

A nice thing about this effect is that it makes high speed bullets look like elongated streaks, very similar to a blurry action photo where the subject of a photo is moving too fast for the shutter speed. In effect, that’s exactly what’s happening in GameMaker, if we consider the game speed to be like the shutter speed of a camera. So this creates a very natural looking visual effect, and solves a problem with high speed collision skipping.

This technique may be applicable to other objects besides bullets, but it works best with smaller objects because the stretching isn’t as noticeable. As the instance is moving at a high speed while being stretched, it can trick the eye into thinking it’s just a motion blur effect. With larger objects, this illusion is not as convincing, and the apparent distortion is more obvious.

Pinpointing the point of impact

Let’s say you need to know the exact point of impact from your high speed bullet. Since the bullet is stretched out, the x, y coordinates are no longer approximate enough.

high speed bullet point of impact

We an use point_direction to find the angle at which the impact occurred.

point_of_impact = point_direction(other.x, other.y, bullet.x, bullet.y);

If the target object is a circle, then calculating the point of impact is simple from whatever angle:
impact_x = other.x + lengthdir_x(other.radius, collision_direction);
impact_y = other.y + lengthdir_y(other.radius, collision_direction);

The above will work as long as the high-speed bullet isn’t positioned such that the x,y origin of the sprite is on the far side of the target object. If it is, the point of impact will be on the opposite side of the target object. If this is a problem, you can do additional calculations using the direction of the bullet’s travel as a clue to determining where the true point of impact was. You can also reduce the problem by making the bullet sprite’s x-origin 0, so the bullet’s [x,y] position will always be at the rear of the bullet.

If the target object is non-circular, or non-centered, you’ll need to do a bit more work to determine the point of impact, and exactly how to do that is outside the scope of this article. But using built-in variables image_xoffset, image_yoffset, bbox_top, bbox_bottom, bbox_left, bbox_right, you should be able to figure it out, at least approximately enough to be useful.

Writing files in GameMaker Studio

The levels in TARJECTORIES are procedurally generated, using a lot of calls to the Random Number Generator. Since the output of the RNG is stable for a given seed, the only variability from one runtime to another is the number of calls made to the RNG. Since the number of calls to the RNG in TARJECTORIES is deterministic, this gives the game the same random procedurally generated levels each time the game is played. Fortunately, those levels aren’t too bad to play.

The RNG sequence will vary if you die and play a new game without quitting/relaunching the game, but if you do quit/relaunch it will be the same sequence of levels every time.

I became worried that the game was too sensitive to the RNG, and wanted to capture the level data so that I could re-generate any of the levels in the procedurally generated sequence if I wanted to, even if the game ends up getting modified in such a way that the number of RNG calls changes, which would otherwise screw up the level generation.

To that end, I just wrote up a little script that writes the level data to a .json file, and played through the game, going through two cycles of the 18 procedurally generated levels, so I could get the original sequence plus the level sequence from GE Mode. This was pretty straightforward, except the part about where GameMaker writes the file.

It’s complicated and not easy to understand. GameMaker runs sandboxed, so you can’t just write files anywhere you want. There’s documentation that explains this in the manual, but even after reading it several times, it’s still not entirely clear where you should look to find a file.

My intent in this post isn’t to write a tutorial that guides you to a complete understanding of where GMS writes its files, but I will explain how I found the location.

GML has a built-in variable, working_directory, which is a path on the filesystem where the game.exe is running. The confusing thing about working_directory is that it can return two different values. In certain contexts, the working directory is literally the location where the game.exe is located. You can read files from here, so if you have any “included files” in your project that you need to read from, this is where they’ll be. The thing is, this location is read-only (to GameMaker) so you can’t have your application write any data here, not even to update existing included files. You have a separate location where GameMaker (and all well-behaved Windows applications) can write files, in %LocalAppData%.

This is where it gets weird for me, and I still don’t entirely understand what’s going on.

I run the project out of GMS, and to help me find the file I’m writing, I draw the working_directory to the screen, and I get this:

C:\Users\XXXXX\AppData\Local\gm_ttt_20698\gm_ttt_1803\

So I go there, and I do not see the file that I wrote!

Eventually, I found the file I was looking for in C:\Users\XXXXX\AppData\Local\[project_ name]

I was able to find it because I went to %LocalAppData%, sorted by date last modified, and looked for the most recently updated directory until I found it.

What’s the first directory, then? That’s where GMS builds your project when you run it through the IDE! GMS also uses %LocalAppData% to store the temporary build that it creates when you click Run Project. But this is the read-only working_directory location that is where the game.exe resides. The game.exe then creates its own directory in %LOCALAPPDATA% which is named whatever you named your project (eg., [project_name]) and this is the directory that GMS will allow itself to write to. And of course you can also read files from here, too.

The confusing bit is when you call working_directory in the context of, say, draw_text(x, y, working_directory) and working_directory returns the read-only path, but when you call working_directory in the context of fileID = file_text_open(working_directory+"file.txt");
file_text_write_string(fileID, "text")
, working_directory returns the writeable path.

The behavior of working_directory is what’s confusing. It would be a good idea, I think, if YYG were to create a GML variable called “working_directory_writeable” which was an alias of the writeable working_directory that always returns the writeable path. There should then also be a companion variable called working_directory_readonly They could leave the behavior of working_directory as it is, to avoid breaking anything already written. It can return the readonly directory or the write-able directory, just as it does currently. But if you need to be sure the path to the writeable directory, then you could use “writing_directory”.

So, moral of the story, if your your GameMaker Studio project wrote a file to working_directory, you will find it in C:\Users\XXXXX\AppData\Local\[project_ name] — not the location given by working_directory if you draw it to the screen.

Debugging TARJECTORIES: a Ludum Dare 38 postmortem epilogue

If you haven’t played TARJECTORIES yet, I encourage you to download and give it a try first.

Next, I encourage you to read the project postmortem article I wrote about the experience I had creating TARJECTORIES over a 48 hour period.

Back? OK.

In the wee hours of Sunday morning, in the midst of my debugging hell hours, I posted this on Facebook:

Debugging a program sometimes is like converting one system of thinking into an equivalent system of thinking, only one that works where the other one fails.

Since you can do this only one keystroke at a time, it’s pretty rough when you’re looking at transitional code and are looking for signposts to remind you of where you are. It’s common when you get distracted briefly to come back to looking at your code, desperate for these signposts.

This can end up making you very confused and waste a lot of time.

How to avoid this?

To put it in more familiar terms, pretend you’re writing a novel, and you want to change some of your characters around, so you need to update the text so that everything Smith says is now said by Roberts. Halfway into this, you’ve forgotten who’s who anymore, and there’s nothing in the manuscript that can help you tell what’s been changed already and what still needs to be changed.

If you keep versions of files, you can run a diff of the current manuscript against the most recently checked in version. If you check in versions at the right time, when things are self-consistent, not in a transitional state, this can be very useful.

If you don’t have, or don’t make use of, these tools, you’re putting a massive cognitive burden on yourself that prevents you from higher order thinking about the problem you’re trying to solve. If you get distracted in the midst of your transitional revision work, it’s like a juggler dropping their balls. One hiccup in the routine and the entire thing falls apart, and the only thing left to do is try to pick it all back up and start over.

The hardest thing is when you keep having ideas and thoughts about what else you’re going to need to do next. Often times a change will have a cascade of changes. Not necessarily code changes, but feature changes, or new features. Each one of these is like someone throwing another ball at the juggler. Even the best juggler can only handle so many things before they slip up and have to drop it. And while a person is juggling, there’s very little else they can do.

If you want to get real work done, don’t be a juggler. They spend most of their time repeating a cycle of familiar tasks that just maintain a status quo, and hardly have time to make any progress with anything else. It looks impressive, but it’s monumentally wasteful.

Learning not to juggle is even harder than learning to juggle, though.

The thing is, when you’re doing game development, design and development are tightly interwoven. It’s not even iterative, it’s sub-iterative. You’re figuring out what’s possible, what’s fun, what you can make work, and figuring out how to make it work, making it, and then seeing what else it needs — all at the same time. It’s inevitable that you will have ideas at every step in that process. And each idea is a ball to juggle. I found it works best to leave myself “TODO” comments throughout the code whenever I have an idea come to me while I’m still in the middle of working on something else, and keeping a notepad handy for things that I observe at runtime. Otherwise, you need to be able to split your conscience like a fractal if you want to have any hope of being able to do all the things that occur to you while you’re in the middle of development.

Holy s—. I’ve been at it since 10pm, and I think I finally just fixed a bug that I’ve been puzzled by for several hours. I can’t even begin to explain all the stupid details that I’d need to in order to convey what I just did.

But here goes anyway.

In my project, I have a planet which has a player on it. I had this working just fine with a single planet.

I wanted to create mutli-planet levels, but when I added a second planet to the game all kinds of things started going wrong because of all these hidden assumptions my code was making about there always only ever being one planet.

So I started disentangling the planet, which was really doing a lot of extra stuff that it didn’t really have any business doing. This stuff was managing other game state, and when you had multiple planets, they ended up screwing with each other as they both were updating the game state. Sort of like a race condition, I guess.

It caused some REALLY bizarre bugs, though.

The level counter went up smoothly until it hit 11, and then it started repeating itself a few times, then skipping a head several numbers, like 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 11, 11, 14, 16.

It also had a strange tendency sometimes to not spawn any player at all, on the second level 11.

I fiiiinally got the problem solved, without realizing that was what I was doing. I just started to give up and work on other problems, when I decided that the planet object should not create its own player. I’d done that early on because it made sense when there is only one planet. With two planets, each would create its own player instance, and then I’d have to go back after and delete one of them at random. This SEEMED to work, but somehow became responsible for the weird level number glitch, and the missing player object on the second level 11.

I STILL don’t get how that exactly worked. It still doesn’t make any sense to me. But when I decided to de-couple the player-spawning duties from the planet object, and instead of two planets each creating a player on it, and then randomly selecting one of those two to delete, I re-did the code to spawn two planets, then randomly choose one of the planets to spawn a single player on.

That fixed it. Like, whoa.

Update: A day later, it finally occured to me what happened, and why. This may not interest many, but for posterity, here’s what was going on:

When I made the game, I started out with a 1-planet room. I had this working so well that I didn’t want to screw it up, so when I was ready to start work on a 2-planet room, I created a new room so I could mess around in it. I had my level counter set up in such a way that after level 8, it would switch rooms to the 2-planet room for planet 9.

I had some code in the LevelUp object that handles this. But the thing about the Level Up object is, it doesn’t do those things when the game room loads. So on the transition into the 2-planet room, there were certain things that weren’t happening. To compensate, I (this was a bad move on my part) copied some code out of the LevelUp object and put it into the Creation code for the 2-planet room, and then failed to maintain this code adequately as I continued to make further changes on the LevelUp object.

So what happened was, when Level 8 is cleared, the LevelUp object does its end=of-level thing, and increments the global level variable, and creates new planets for the next level. It then checks to see if the level is 9, and since it is, it moves to the 2-planet room. The 2-planet room starts, and there’s 2 planets there from the room editor, not from the LevelUp object resetting the level. So nothing weird happens until after Level 9 is cleared, because that’s the first time the LevelUp object levels up in a 2-planet room.

I’m still unclear why the level incrementer goes from 9 to 11 — it seems obvious that it has something to do with there being two planets, but I didn’t have the level incrementer tied in any way to the number of planets. And it’s more mysterious to me still that it gets stuck on level 11, and so displays level 9, 11, 11, 11, 14. If GameMaker Studio had a better debugger, I might have bothered to trace through the script and watch the variables change to understand what’s going on, but I figured out enough to fix the problem without completely understanding it (well let’s hope so).

As to why there was no player at all on level 12, I do understand that. The planet’s Create event creates a player instance, and stores its ID in an instance variable, so it can update the player’s x,y position as the planet rotates. In the two-planet world, of course, I ended up with a player instance on each world. I didn’t need or want both of them, so I figured I’d just randomly destroy one of them, rather than fix it so that there would only be one. So I used a for loop and iterated over an array that should have been as long as the number of planets (2), and picked 1 array index to keep, and destroy all others. I figured I might want to make a 3-planet room at some point, and was trying to make the code work for N-planet rooms, rather than solve the 2-planet problem and leave a 3+ planet problem still unresolved. But sometimes the random chooser picked an array index that was out of bounds for the “keeper”, and so the for loop would go through and destroy all of the player instances. This happened to happen on level 12. It happened consistently on level 12 because the RNG seed value was always the same, and the same number of calls to random() always happen between the start of the game and getting to level 12.

I fixed the code by removing the player create from the Planet object, and put it after the planets are created, using choose() to select which planet if there’s more than 1.

The code works and appears to be bug free, but from a design standpoint it’s still messy. When I get around to doing it over, I will clean things up by removing the 2-planet room, which was only ever supposed to be an experimental room, and re-writing the code so that rather than move to that room when the level incrementer hits 9, it will spawn two planets, instead. This will enable move to remove the duplicate code by getting rid of the now-obsolete experiment room entirely. In retrospect that’s what I should have done in the first place, but because I was so concerned about not screwing up my working 1-planet room, I didn’t want to risk it. But really, all I needed to do was check-in to source control and create a fork to experiment in.

As easy and fast as the progress I made Friday night was, Saturday night was an absolute nightmare of a debugging session, just to figure this thing out and get it working. It’s SO weird how it was sortof almost working. Sometimes it’s a lot better to have something completely not working and obviously wrong. Those kind of bugs are much easier to fix.

The good news, though, is that I kept my Friday momentum through Saturday until I took my long break. I implemented a lot of features and had the game 95% complete, or so I thought. Just that last little bit of debugging took about 7 hours, and now the game is basically done.

So I made excellent progress Friday, and most of Saturday, although I unwittingly introduced this nasty puzzling bug during that progress, which stalled me for the entire night. But I still got so much done so quickly that I’m basically done now.

I have until 9pm Sunday to work on it, but I think it’s pretty good right now.

Ludum Dare 38: A Small World (TARJECTORIES)

Tarjectories by csanyk for LD48-38: A Small WorldMy latest release is called TARJECTORIES, and it’s my entry for Ludum Dare 38, A Small World.

Play and Rate TARJECTORIES at Ludum Dare

The title is a mashup of “target” and “trajectory”. It’s also an easy misspelling of “trajectory”.

You control a little gun turret on a little world, shooting little projectiles at little targets. Use the planet’s spin, and your shot power and gun elevation to put shells on the target.

Destroy all targets on the planet to advance to the next level.

You will need to use your judgment and instincts to know how much power to give the shot, and what angle to fire at. Most targets can only be hit by indirect fire, relying on the trajectory of the shot as its path curves due to gravity. Here’s an early work-in-progress screen capture:

TARJECTORIES - Early work-in-progress

Controls

Adjust your turret’s gun elevation by the left/right arrow keys, or A and D keys.

Adjust gun power by using up/down arrow keys, or W and S keys.

Fire using the Space bar or Enter keys.

Scoring

  • Direct hit: If you hit a target directly with the shot, you will score a base amount of 1000 points. This is doubled for each consecutive hit you make: 2000, 4000, 8000, 16000, 32000, etc.
  • Indirect hit: If you hit the ground near a target, the explosion from your shot may destroy the target anyway. But you will lose your consecutive hit score multiplier, since when your shot hit the ground, technically that was a miss. This will score you 1000 points, and count as your first hit on your next consecutive hit multiplier.
  • Bonus timer: There is a timer in each level, and if you manage to destroy all the targets before it expires, you’ll get bonus points.
  • Perfection bonus: If you mange to hit all the targets in a level without missing (all direct hits), you will earn a perfection bonus. The base perfection bonus is 10000 points * the number of hits scored in the level, raised to an exponent equal to the number of Planets in the level. This is how you get the truly astronomical scores. If you get a perfect bonus on a multi-planet level, you deserve it.

Winning and Losing

The only way to lose in TARJECTORIES is to accidentally shoot yourself. This can happen if your shot orbits your planet and comes back around to hit you, or if your planet is rotating fast enough that it puts you in the path of your shot as it falls back to the ground. Don’t do that.

To win, you must complete every level of the game. You can play again; the game will be re-randomized on your subsequent re-plays.

Download TARJECTORIES

TARJECTORIES is currently able to run on Windows.

The source code is also available for you to download, if you wish.

TARJECTORIES was built using GameMaker Studio 1.4, Bfxr, and Audacity. It took about 22.5 hours of development time for me to built. Everything was built from scratch, by me.

Version History

1.0.0.0

Initial release

Bug reports:

  1. One user has reported a bug whereby two worlds appear on level 1. Unable to replicate. There should be no way for more than one world to be created on level 1, and even if there were, the oPlanet object has collision detection with other oPlanets, and re-positions them in the event of a collision until they are no longer in collision.
  2. FATAL ERROR in
    action number 1
    of Step Event0
    for object oGround_explosion:Push :: Execution Error – Variable Get -2.t_angle(100033, -2147483648)
    at gml_Object_oGround_explosion_StepNormalEvent_1 (line 11) – ex.t_angle = other.t_angle;
  3. Stats tracker fails to count a miss when a shot destroys itself due to timeout.
1.0.1.3 Bug fixes:

  1. Stats tracker fails to count a miss when a shot destroys itself due to timeout. FIXED.
  2. oGround_explosion error referencing non-existent other in Step Event when a collision is detected with a target. Replaced other with the id of the target instance.
1.0.2.4 Numerous tweaks, mostly to the level_timer, minor bug fixes, and polish.
1.0.3.5

“GE” edition released. Feature complete.

1.0.4.8 Fixes the graphical bug some users were reporting where on the first level it looks like there’s two worlds overlapping each other. The bug was the result of using surface and draw functions in the Create event, rather than in the Draw event where they belong. I guess it affects certain users who have certain video cards, because I was not able to replicate the problem on my machine, but a user who did experience the bug confirmed that it was fixed by this release. Final build for Compo entry.

Classic Videogame Quotes

Since their invention, almost overnight videogames have made a lasting impact on the greater culture. Here are a few of my favorite memorable quotes from video games.

It’s dangerous to go alone. Take this!

It's dangerous to go alone! Take this.

Game: The Legend of Zelda

System: Nintendo Entertainment System

Year: 1986

It’s the mid-80’s. The NES is new, and a chip shortage has made this already-hot game a hard to find must-have for the holidays — despite being released in February. Limited quantities of the special gold cartridge meant that a lot of kids had to wait a long time to get their copy of the game everyone was talking about: The Legend of Zelda. In Link’s first encounter, he finds an old man in a cave with a gift and some memorable advice.

Welcome to adventure, kid.

It’s a secret to everybody.

It's a secret to Everybody.

Game: The Legend of Zelda

System: Nintendo Entertainment System

Year: 1986

There’s something seedy about taking free rupees from a cave-dwelling Moblin. Is this a legit offer? What’s the catch? Why is this overworld enemy helping us? But yes, it’s true. Everyone knows that the secret to getting ahead in the world is to have a little money. It can get you into places, and out of jams. You can never have too much, but you can only carry $255. Don’t spend it all in one place, unless it happens to be the hidden shop that sells the Blue Ring!

Uh Oh. The truck have started to move!

Uh-oh! The trick have started to move!

Game: Metal Gear

System: Nintendo Entertainment System

Year: 1987

Most videogames for the NES were developed in Japan, and accurate translation never seemed to be a high priority. So many memorable quotes from mid-80’s videogames are remembered for their quirky, incorrect grammar and hilarious misspellings.

In Metal Gear, you sneak about a military base attempting to keep a low profile lest you be discovered and create an international incident. While looking inside a few parked trucks for supplies to aid you in your mission, one of them happens to start up with you inside! Better lie low and hope that you will not be discovered, and that wherever it takes you doesn’t bring your mission to a premature end. Fortunately for you, the blundering enemy has in fact just made it easier for you to succeed, by taking you to an area on the base where you could not get to otherwise.

Earlier in the game, you encounter this tired guard, who, if you wait out of sight long enough, will fall asleep. Oddly, before nodding off he announces, to no one in particular, “I feel asleep!!” Either the designers meant to say he fell asleep, which makes no sense because he’s already asleep, or perhaps they meant to say he feels sleepy. Either way, it’s pretty funny.

The NES port of Metal Gear was a bug-ridden mess, but since most of us didn’t have an MSX to compare against, we had no idea, but we didn’t care. The sneaking about, using stealth tactics to infiltrate the base while quietly eliminating guards, and finding an arsenal’s worth of gear to blow up a nuclear-armed super-weapon were too important to let some bad English stop us.

I feel asleep!!

Congratulation.

Congratulation.

Game: 1942

System: Nintendo Entertainment System

Year: 1986

A number of early Capcom NES games rewarded the player who successfully beat the game with this stingy accolade, “CONGRATULATION.” What, just one measly congratulation? Isn’t plural, multiple congratulations nearly always in order when complimenting someone’s happy success? After dogfighting your way through thirty-two (!) stages of bland, slow-moving shoot-em-up “action” against an unbearable monotone soundtrack, this is the thanks we get?

Literally, this is the entirety of what you get when you beat the game. Screw you, Capcom!

Fortunately, they more than made up for this with the sequel, 1943, which features improved everything, including one of the best soundracks on the NES. Capcom went on to produce some of the best titles on the NES, and found even greater glory in the 16-bit era with Street Fighter II. All is forgiven.

A winner is you!

A winner is you

Game: Pro Wrestling

System: Nintendo Entertainment System

Year: 1986

Pro Wrestling is one of those games that is pretty dumb, and yet really fun despite that, with a one of the hardest boss fights to win, the championship bout against Great Puma. But each time you manage to win a wrestling match, your reward was this message: A winner is you! All right! It really pumps up your self esteem!

You are in a maze of twisty passages, all [alike|different].

You are in a maze of twisty passages, all alike.

You are in a maze of twisting passages, all different.

Game: Colossal Cave Adventure

System: DEC PDP-10, and others

Year: 1976

There’s so much quotable in Colossal Cave Adventure, considering the entire game is entirely text, and one of the first computer games ever. But this quote from the Maze is the one that I come back to the most. To create the feeling of being lost in a maze, the game just repeats the same text in each room, until you manage to solve the maze. There’s no feedback to tell you where you are, or to give yourself a reference point to have some idea where you are. After puzzling over this conundrum, successful players eventually figure out that if they drop an item from their inventory in a room, it will help them to make that room in the maze stand out from the others, enabling them to map out the maze with pen and paper.

To this day, whenever I’m in a confusing situation where there are many options and I don’t know which is the right one, I’ll think back to this one.

I am Error

I am Error.

Game: Zelda II: The Adventure of Link

System: Nintendo Entertainment System

Year: 1987

A genuine WTF moment in gaming occurs when you meet the infamous Error. This is all he ever says to you, “I am Error.” Is that his name? Or is he just a chronic screwup? Or is the game telling you that it has an Error? This was a matter for deep contemplation in 1987.

What a horrible night to have a curse.

What a horrible night to have a curse.

Game: Castlevania II: Simon’s Quest

System: Nintendo Entertainment System

Year: 1987

Castlevania II attempted to innovate by introducing adventure and RPG elements into the action-platformer formula. There’s a level-up system, and shops where you can spend money that you spend hours grinding for… so much grinding for XP and hearts in fact that this game is usually remembered as the least-liked of the NES Castlevania titles. Luckily the music was excellent. Unlike the first Castlevania, rather than having a linear progression through a series of stages, the game featured an open map that you could go back and revisit, and likely would need to several times while trying to figure out some extremely obscurely hidden secrets. Another innovation the game features is a day-night cycle, where during the nighttime hours, the enemies were stronger, doing twice as much damage, and taking twice as many hits to be defeated. Every couple of minutes, day would turn to night, or night to day, and every time the game would freeze and display this message to you… one character at a time… for about 30 seconds. It was… memorable, let me tell you.

Winners don’t use drugs

Game: Various arcade games

Year: 1989-2000

If you went to an arcade in the 1990s, you surely saw this message on a regular basis. I don’t know whether it ever stopped anyone from trying drugs who wanted to, but we sure did know who the Director of the FBI was.

It is pitch black. You are likely to be eaten by a grue.

It is pitch black. You are likely to be eaten by a grue.

Game: Zork

System: PC

Year: 1980

The early text adventure games borrowed liberally from one another. In Colossal Cave Adventure, you could die if your torch went out, falling into a pit in the pitch black darkness. In the Zork series, there were locations where you could die without a light source, but it made no sense to have a hole that you could fall into. Enter the Grue, a loathsome fell creature that inhabited only the darkest reaches, and had never been seen by anyone who lived. But what is a Grue? No one knew. Some speculate that the name derived from the word gruesome, which is certainly a likely sounding explanation. On the other hand, the term “grue” is also found in the philosophy of Nelson Goodman, which might have been familiar to the MIT students who formed Infocom. But they’re also a monster in the Dying Earth novels by Jack Vance. So which is it?

Fight, Megaman! For everlasting peace!

Fight, Megaman! For everlasting peace!

Game: Mega Man

System: Nintendo Entertainment System

Year: 1987

After winning the original Mega Man, we are informed that Mega Man has to continue to fight (basically telling you that you could now play the game again, enjoying it for “replayability”). “Fight, Megaman!” the game extolls us, “For everlasting peace!” What? How? That oxymoronic statement always gives me a chuckle.

President Ronnie has been kidnapped by the ninjas! Are you a bad enough dude to rescue Ronnie?

President Ronnie has been captured by the ninjas

Game: Bad Dudes vs. Dragon Ninja

System: Arcade (Data East)

Year: 1988

What could be more 80’s than a President named Ronnie? In the last year of Reagan’s presidency, this 2D beat-em-up gave us the attitude of cool badness that we all needed. Are you a bad enough dude? The game play in Bad Dudes wasn’t necessarily great, consisting of mostly standing around on platforms as the level slowly scrolled by, delivering repetitive one-punch or one-kick knockouts to an endless supply of cookie cutter Ninjas, without a great amount of depth or variety to the entire affair. This was a game anyone could beat, pretty much regardless of their skill level, as long as they had enough money. But the giant-sized, 16-bit sprites and (somewhat) challenging boss fights were enough to suck us in and drain the quarters from our pockets.

Barf!

Barf!

Game: River City Ransom

System: Nintendo Entertainment System

Year: 1989

The famous last words of many dying students at River City High school, uttered as they blinked out of existence and left behind their bouncing pocket change. It’s funny that they apparently literally say “Barf!” rather than making the sounds of barfing, such as “Bleaugh!”

Finish him!!

Finish Him!

Game: Mortal Kombat

System: Arcade

Year: 1992

The voice narration gave these words a chilling malevolence. When you hear this, having won two out of three rounds in the Mortal Kombat tournament, it’s time to unleash the combo that triggers your fatality move, giving your opponent a death worthy of the game’s title. Or, if you’re the loser, it’s time to endure the indignity and shame of having your body torn asunder, in the most unpleasant way imaginable. Yet, no matter how many times they die in the MK tournament, you everyone still gets to fight again in the endurance rounds.

Game Over

Game Over

Game: Just about every one, ever.

System: All of them.

Year: Eternal

Game Over, man. Game over!

To be sure there are many more memorable videogame quotes that I’ve left out. What are your favorites?

The Ongoing Sale

Since I announced yesterday that I’d finally earned my first $100 payout through the GameMaker Marketplace, I dropped my price on all paid assets to $0.99. I had another purchase today, so to celebrate that, I decided to adjust the terms of the sale.

The payday celebration sale will continue through 4/10/17 as planned.

For each paid purchase I get during the sale, I will extend the sale by one day.

Update, I had another sale today, 4/11/17, which will extend the discounts another day.

So as of right now, the sale on all my paid assets will last until 4/12/2017.

Get csanyk GameMaker assets on GameMaker Marketplace!

Achievement unlocked: $100 in revenue on GameMaker Marketplace

On July 20, 2014, I released my first asset for GameMaker Marketplace, MMap Mini Maps.

Today, nearly three years later, I have finally reached the $100 author revenue milestone, meaning I’ll finally get paid.

In celebration, I’ve put all of my paid assets on the GameMaker Marketplace on sale for just $0.99 for one week, ending 4/10/2017. Update: I’ve decided to extend the discounts by one day per asset sold during the sale. So currently the sale will run through 4/12/17. We’ll see how long we can keep this going.

You can buy them here.

Enjoy! And share! And thanks!

YoYoGames: Major GameMaker roadmap announcement

YoYoGames posted a major, detailed update to their roadmap for GameMaker Studio 2 this morning. Seemingly not an April Fool’s joke.

The announcement contains lots of exciting, long-awaited new features and improvements, but not much detail as yet about when most of these might be forthcoming. And the usual disclaimers that these are plans, not promises.

There’s even more at the link above, but here’s what I think about these in particular: (more…)

csanyk.com © 2016
%d bloggers like this: