Nov 28 2009

Minute Dungeon- Design Notes

Minute Dungeon is my entry for Mochimedia’s Novemeber ‘Flash Game Friday’ contest. Flash Game Friday had been a $100 bonus awarded by Mochi on a near weekly basis to a game in their distribution feed selected by Mochi staff. There were no codified rules, and I don’t think anyone paid too much attention to it.

In early November, Mochi announced they were discontinuing the old FGF program, and replacing it with a monthly development contest which would also be called ‘Flash Game Friday’. November 6th, they announced the rules for the first running of the new monthly contest “60 seconds to fame”. The theme of this first contest was ’60-second game’– ie, the game had to be over in 60 seconds or less.

Key rules were:

  • Entries must use Mochi’s version control and Mochi’s distribution feed.
  • Entries must use Mochi’s Leaderboards, and automatically submit scores on game completion

Beyond that, there were some instructions on how to tag your game so it could be found in the distribution feed by the judges, and that’s about it. Everything else was left to the developers.

WARNING! Long and rambling discussion of my design methods ahead. I write these in large part so that I have a record of what I did, and definitely not to suggest you should emulate what I do.

 Origin

I don’t recall exactly what my process was for coming up with my idea– it couldn’t have taken too long, since my working directory for Minute Dungeon source code files was created on the 6th. I do know that I was strongly influenced by 8PRL, a theoretical roguelike by Andrew Doull that so far as I know has never been implemented.*

8PRL’s characteristics which I borrowed include:
– The object of the game is to find a crown located somewhere in a randomly generated dungeon. I thought this type of objective would work better in a time attack game as required by the contest than a game where the objective was to beat a final bad guy. I also thought random dungeon generation would be preferable to static levels.
– Having found the objective item, the player is now burdened– less effective because his limited inventory is suddenly smaller.
– Several items made the transition from 8PRL to Minute Dungeon unchanged (Staff, Wand, Potions, Goblets..)

8PRL characteristics which I intentionally discarded:
– I did my (simplistic) own monster behaviors. 8PRL implicitly assumes turn based game mechanics. I thought several of the monster mechanics specified would turn the monsters into homing missiles. :)
– I dropped water tiles, doors, and the associated items. I was not planning to implement scrolling maps in my levels, and thought the maps would become too cluttered.

Other minor differences:
– I use 6 monsters per level, instead of 8.. again due to the size of the map.
– Arrows aren’t re-useable.

So that’s the basis of the game.

Development Narrative

Throughout the development I was split between feeling I had a serious and looming deadline, as in the 48-hour Ludum Dare contest, and feeling I had all the time in the world. Of course neither line of thinking was correct. Most of the work on Minute Dungeon was done on Sundays and about 6 days on which I was not scheduled to fly. In addition I probably averaged 10 hours a week during each week the game was in development on normal workdays. Not all the time spent was fruitful.

I selected 640×480 as my target resolution more or less by default. This was historically a common game resolution because of the technical specifications of early monitors, today it’s useful in Flash because it will fit inside most people’s browser windows even if they have two or three toolbars installed.

The sidebar/view layout I had used in The Knight’s Tour and Cellular Automator, as well as some inprogress slow-burning projects which may or may not see the light of day, so that was familiar and easy. At a highlevel view, there is a game model which is a set of data structures which describe everything about the game. Each frame the primary view queries the model and displays it. Flag variables in the sidebar and the invisible keyboard handler allow the player to make changes to the model. This is a pretty straightforward MVC design implementation, and I’ve gotten somewhat fast at putting it together from scratch in AS3.

The first objective was to procedurally generate dungeon-like mazes. There are several ways to do this– I ended up settling on using a cellular automata routine. You can find good discussions of the specifics elsewhere (such as here). But basically I used rule M45 and applied it to a random grid three times, followed by a path cutting algorithm that attempted to connect as many discrete areas of open space as possible. I decided on the rule, the number of times to apply it, and developed the path-cutter by trial and error.

Following generation, I needed to validate the map– for some maps generated this way, there would be no possible way to get from an entrance on one side of the map to an exit on the other. To do this, I selected a cell on the bottom edge near the center and moved up until I encountered an open cell. I then applied a 4-way recursive flood fill … although I wasn’t actually changing any colors I was just marking the cells as open. I then checked to make sure that there was at least one cell marked as open in the left-most and right-most columns of the playing map. (The display map being two cells wider to accommodate exits on the left and right).

Doing my validation this way, some maps which were actually playable fail to validate, because the validation fill gets performed inside a group of open squares near the center bottom that happen to not be connected to anything else. Even with this limitation, it’s rare when generating 5 levels to have more than 2 or 3 validation failures. I considered this acceptable. After validation, I marked every square not marked as open as a wall, regardless of whether it had been set as a wall by the generation routine, in order to remove unreachable rooms.

The rest of world generation was fairly straightforward– place x items or monsters in random open squares, so I won’t go into it. From a display standpoint, the game isn’t very complex after this point. In the primary playing area there is a floor image, over which there is a grid of cells which are either walls or not. Then there’s a grid which is either an item or not. Then fire effect, spells, etc (Though monsters and the player are handled differently, as sprites which can move around). Each display layer has a corresponding data layer in the world model.

ScreenShot1

ScreenShot1

As mentioned, I felt under a time pressure, so I jumped around a little. Here is an early screnshotshowing the working dungeon generation, a blue square which is the player, the early sidebar (I stuck with the red and grey color scheme– but I’m not sure where I picked it up from. Probably I had just received some type of letter from my old high school whose colors are red and grey), and the floor. The floors were the first graphically detailed objects for the game which I did.

I’m not sure if the timer was working at that point or if it was just a stand-in. The sidebar however, I had built in order to dimension the primary playing field. (I needed to know how much space I needed for the sidebar in-order to know how much space I had for the rest of the game.) I ended up setting the sidebar at 140 pixels wide, leaving a 500×480 playingfield. At this this point I made a mistake though I didn’t realize it then– I made my tiles 20×20 pixels. This would have ramifications later.

The story being the player needed to get into the dungeon, find a crown, and get out, I needed three floors. (Putting the crown on the third level meant 5 total levels, giving the player 12 seconds per level which I thought was about right). I built the floors by merging GiMP’sdefault textures in a 500×480 screen withdifferentlevels of transparencies. Basically anything with a detailed surface texture was done this way, which was a new technique for me. I liked the results, but when saved as .png files the floors were far too large (about 400kb each). I switched over to jpg for the floors which reduced them to about 30kb each. Generally, jpg doesn’t seem to get used much in games because it’s a lossy compression format, but in this case the object was merely to have an aesthetically pleasing non-uniform surface so it seemed to work. Although this is the background for the scoreboard, rather than the floor you can see the difference below. .png on the left, .jpg on the right.

PNG Backdrop

PNG Backdrop

JPG Backdrop

JPG Backdrop

 

 

 

 

 

 

 

 

Wall Tiles and solid colored squares

Wall Tiles and solid colored squares

 

More or less at this point I wasted two solid days trying to make wall tiles. Displacement filters, blurs, you name it, if it’s a filter in flash.filters.* I tried it, but really couldn’t get a 20×20 tile to look nice and not excessively regular. After some searching I found a discussion by RPGMaker3k users on pixel art that was useful. In particular, post #35 broke open the tiling problem for me. I’m fairly proud of my wall tiles. The author of that post has interesting blogs about game development and pixel art as well.

The next two weeks were basically spent doing art and sound and then shoving them into the framework I had done originally. There’s not too much to be said about sound– I used FL studio 9’s demo to create the main track and speech effects, and sfxr to do the sound effects. Then I converted everything to 11khz mp3s using Audacity for space reasons. The one thing I didn’t do when I created the main track was create a single beat ambient loop for the menus and such… and I couldn’t recall what settings I had given the low bass drum in the soundtrack, which is why the menu drum sounds slightly different from the drums in the main soundtrack. The FL studio demo doesn’t allow you to save your projects (though it allows .wav and .mp3 export, which is how I was able to use it for my purposes).. The express version of FL studio is fairly inexpensive, and I think I’ll probably end up purchasing it. (What I’d really like though, is inexpensive software which can use VST instruments and understands musical notation. I don’t think that exists though.)

Art meanwhile, was a major stumbling block. 20×20 is a non-standard tile size. By the time I had drawn enough to want to just find an already done open-source or free-use tileset, I was fairly well wedded to 20×20, which doesn’t seem to be available in freeware chipsets. Programmatically, I could have made the switch since everything which needed a tile size to compute a value or position used global constants for tile size. But for some reason I persisted with my own drawing.

A Valiant Hero

A Valiant Hero

For drawing characters, I found the technique of using a sprite guide and other techniques suggested in Tsugumo’s ‘So You Want To Be A Pixel Artist’** to be useful. Unfortunately, while drawing the player, I subconsciously considered the sprite guide I had set up on the left side of my canvas as an edge. This meant the hero waddles a bit as he walks, because the two walk frames are horizontal mirror images of each other but they weren’t centered. (Between each walk frame he returns to the standing frame to create an ersatz 4-cycle walk animation). However, by the time I was testing the animation, I had begun to like the effect and left the waddle be.

Lineup of dangerous characters

Lineup of dangerous characters

Monsters were about the last thing I added, both on the data and on the art side. The first set of monsters, were pretty random. I didn’t have a clear idea of what I wanted the monsters to be.

The Final Enemies
The Final Enemies

Further, I originally intended to have the monsters only face one way to minimize rendering complexity. I ended up not liking the result, so I redrew the monsters to incorporate facing. Or rather, I drew 2 and recolored one to make the additional enemies. (The first guy gets repeated since on level 1 he’s moving left/right, and on level 2 he’s moving up/down…) I used bright colors because the dark greens and blues of the original monsters weren’t showing up well against the floors.

I’m almost certain that the knight enemy is a near-copy of a Final Fantasy character, but I’m not 100% sure. I actually never played any of the Final Fantasy games, so it would have come from seeing him in 8Bit Theatre— but I don’t really want to delve through 1000+ pages of webcomic to find out his name.

Monster behaviors were designed to be increasing the challenge to the player without ever getting particularly intelligent or difficult– after all the player only has 12 seconds to get through the each level! So for the first two levels the enemies move but don’t shoot, then on the third they shoot in order to let the player know that they can. (After all, this is flash… you can pretty much assume players won’t read the instructions even if they’re good instructions which I haven’t yet developed the knack for). Then on the last two levels they shoot and move. I didn’t want the monsters to all shoot and move at the same time (actually I tried it, and it caused a rather stuttery look) so each monster has a move timer and delay timer which is randomly seeded. (I guess they’re counters rather than timers, because their just Integer variables which are incremented each time the monster’s maintenance method is called, rather than Timer objects sending trigger events). On each level the the number of frames that must pass to trigger a behavior is reduced, and for each monster it’s allowed to vary by +-5 from the level’sdefault trigger. I was happy with the effect.

I’ll admit I kind of phoned-in the instructions page. Based on my previous games, no one looks at it anyways.*** Beyond that, there’s not much to say about API integration or menus. The only trick to mention is that on my computer, world generation (generating 5 levels, and placing the items and monsters therein) takes some fraction of a second– not long but long enough to be noticeable if it’s done when the player clicks the start button. So instead I run the world generation routine once during the splash screen (It’s complete by the time the first drum sounds), and then I run the removal and re-generation each time the high scores get displayed. This was my attempt to hide the calculation process from the user.

Statistics (just for fun)

  • Lines of code: 5287 (not counting third-party APIs)
  • Classes: 50
  • Image files (in final swf): 63
  • MP3 files: 18

Economic Considerations

There were essentially none. By the time I had a game complete enough to seek sponsorship, I would have had only a week to find a sponsor, implement their preloader and graphics, and get ad and distribution approval from Mochi. I did put an outlink to Casual Collision in the game though.
Release

I submitted the game to Mochi for ad and distribution approval on the 25th, suggesting I only spent 2 and a half weeks on development. It sure feels longer! I had submitted the game for approval because I thought it was basically done, but I was worried that if I delayed too much longer I wouldn’t get approved before December 4th, since the 26th of November is a major US holiday that more or less stretches through the weekend. I figured I was just getting my game early into a queue which wouldn’t be processed until next week, but Mochi surprised me by approving the game within a few hours.

In retrospect, I absolutely did not need to, but once the game was approved by Mochi I pushed the game onto Kongregate and Newgrounds. I also posted a forum topic on Mochi asking for feedback. I received a number of nice comments which exceeded my expectations and I’ve been flattered by the response. :) I also got a good gameplay suggestion regarding the inventory which has already been implemented.

However, in retrospect it was probably not the best idea to release immediately before a major holiday as early on the morning of the 26th a large number of games were released, presumably to try to capitalize on the number of people not at work and presumably playing games. My game was pushed off the new games pages for Kong and NG within 12 hours of release, something that I don’t think has happened to my games before. (I actually thought for a moment that it had gotten blammed (removed for poor score) from NG when it went from being under judgement to off the recent submissions page in one jump!) Of course, as of this writing, it’s far far too early to call the game a success or failure as I haven’t really begun systematic distribution.

Takeaways

  •  I didn’t really touch on it too much, but using FL studio to do a soundtrack was new to me, and using sfxr was newish. I got to practice some using those tools.
  • I definitely picked up some new techniques relating to pixel art, whether for good or ill remains to be seen. :)
  • Merging textures also is a new technique for me, and seems to be useful.
  • I got a lot of practice at coding, and forcing myself to stick to a framework rather than hacking away to get an effect to work like I sometimes do. 😉

Regardless of how the game ends up placing in the contest or does in it’s released life, I think I got quite a bit out of building Minute Dungeon. Sometimes just finishing is enough reason to enter a contest like this. Good luck to all the other entrants!

 
*- I should note that I really want to like roguelikes, but I can’t get my head around the ascii graphics which are traditional in that genre. Even ZZT with it’s ANSI graphics is more appealing to me. I wasted months playing Dwarf Fortess, but only because of a third party graphics mod which took the ascii graphics and generated a tilemap using sprites.

**- Google it. I don’t know the authorized location or I’d post a link, but it’s copied verbatim all over the web.

***- On previous games I had setup MochiBot counters to fire when the game was loaded, a new game was started, instructions were looked at, etc.

2 Comments

  • By Andrew Doull, November 29, 2009 @ 9:16 pm

    Really enjoying it – just wish it was two minute dungeon. The time constraint makes it hard to explore the whole rule set effectively.

  • By Tony, November 30, 2009 @ 2:27 pm

    Glad you’re enjoying the game! :)

    Although there seems to be a large minority of players who like the game as a time attack, several people commented on the Mochi forums that the game might work better without the timer at all. At some point after the judging for the contest is complete I’ll rework the engine without the timer.

    Though I suppose I’ll have to change the name…
    -TF

Other Links to this Post

RSS feed for comments on this post. TrackBack URI

Leave a comment