Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
106 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

How To Build a Game In A Week From Scratch With No Budget


Intermission – Crisis Management!

At this point I realize I'm more than 3/5ths of the way through my schedule, and that I have less then 15 hours left to finish the game.  I go through my list of Things To Do, and assuming one hour per feature, it'll take around twenty-five hours to finish it all. That's ten hours over my limit  I'm halfway through the time I'd allocated to getting the environment active, and I've not really started on it yet.  The project is officially in jeopardy.

Going overtime is really not an option I'm allowing myself. Hiring additional help or buying some more code / resources isn't an option, either. Since I'm only counting real "development" time for my 40 hours, I'm already pretty maxed out on productivity – I can't think of any way to be more efficient. Aside from spending a lot of time on the Internet looking for magical free solutions to my problems, I really have no choice here but to cut features, and see what I can do to simplify my design.

  • Doors: CUT! I REALLY want doors in this game. This is the most painful feature to cut – especially since I've already spent some time working on them already. But there is too much work to be done on them - especially considering the AI has to deal with them. I probably need 2-3 hours to get them working, and I don't have the time.
  • Inventory: SIMPLIFIED! Forget having a "back inventory" of usable items you don't currently have equipped. Anything you aren't equipped with gets converted into money immediately.
  • Traps: SIMPLIFIED! I wanted to have all kinds of nasty traps with interesting, debilitating effects. Not gonna happen.  Traps will have a simple visual when they go off, and just do damage and temporarily increase the chance of running into a random ("wandering") monster
  • Bows (Missile Weapons): CUT! It's going to be just melee and spells in this game.
  • Saving / Loading the Game: SIMPLIFIED! Only your character will be saved and loaded, not the state of the world. (Editorial Note: I didn't even do this!)
  • Particle Effects: BACK-BURNERED!  These are getting dropped to the bottom of the priority list. I really doubt I'll get to them. I wanted some cool particles for animations for spell effects… but that is unlikely to make it.
  • Spells: SIMPLIFIED! I had a concept for spells where you could "find" spells in the game via scrolls, and that there'd be over a dozen spells you could use. Well, as much as it pains me… I don't see that happening. I'm going to have only a handful of spells available now: Heal, Damage, Debilitate, Buff, and Recall. To deal with increased level, I'm going to allow the player to "beef up" the spells by increasing the number of magic points that go into the spells

  • Monster and Player Animations: CUT! I don't have the artistic talent to do a great job, anyway.

While deciding what I won't do (or what I'm dropping down in priority to highly-unlikely status), it's equally important to decide what I absolutely must do – what needs to be made top priority.

There are a lot of elements to the planned game that I consider very important – like searching for traps, finding secret doors (well, secret portals now), and unlocking chests. But the core of the game is combat. If that's not there, nothing else matters. So I decide I must focus on that, and getting combat working is top priority. I set a goal that by hour 30, monsters will be working – at least enough that the player can kill them.

With my adjusted priorities in place, I move on to continue development.

Hour 26 – The Roll of the Dice

I work out the core "dice" mechanic, something I've had in mind for about the last week --- how the random chances come into play. Since we're not limited to using real dice, we can make a random number of any range we want. Like 1-33, or 6-17.  So what I do for a "standard" roll is a weighted, random roll against the total of the attacker's score plus the defender's score. If the number is above the defender's score, the attacker wins.

For example, let's say I have a total attack rating of 15. I'm attacking a monster with a total defense rating of 10. My odds are 15:25 (25 is 15 + 10), or 3:5. So the game will generate a number between 1 and 25, and if it's above a ten, I win.

Damage uses a slightly different type of roll. I add the defender's "armor" rating together with the attack's "damage" rating. I generate a random number between 1 and this total, and then subtract the armor rating. If the total is less than one, the defender takes no damage. Otherwise, he takes the amount indicated. So if a monster with a damage rating of 10 attacks the player with an armor rating of 5, the game will roll a number between 1 and 15, and then subtract 5 for the damage.

This explanation took more time to document here than it did to write. The dice-rolling code looks like this:

from random import randint
def StandardRoll(attackerScore,defenderScore):
    if (attackerScore<1): # If the attack rating is 0, the attack always fails
        return 0
    if (defenderScore<1): # Otherwise, automatic success on defense rating of 0
        return 1
    roll = randint(1,attackerScore+defenderScore)
    if (roll>defenderScore):
        return 1
    return 0


def DamageRoll(attackAmount, defenseAmount):
    if (attackAmount<1): # 0 attack rating? No damage will be done
        return 0
    if (defenseAmount < 1): # Man, don't screw with us with negative numbers
        defenseAmount= 0

    total = randint(1,attackAmount + defenseAmount)
    total -= defenseAmount
    if (total<1):
        return 0
    return total

Filling out the hour, I decrease the window size for drawing the dungeon to get a slight framerate increase --- the section to the right will now be entirely User Interface stuff. I also make sure the player's movement is corrected for frame- rate.

Hour 27 – Building A Monster

I have a lot to worry about to get monsters working. I have to change the game update system to make it turn-based. The player needs a variety of ways to interact with creatures (bribery, combat, spell-casting). The monster has to interact back. There's AI and pathfinding considerations. And graphics! DO I display the monster with the same top-down perspective?

I can't worry about all these at once – I need to start small. Just putting a monster in the room and displaying in the correct position on the screen is a good start.

  • I create a "monster" class, derived from creature.
  • I create an "ActiveAI" list for the main game loop to deal with activated monsters.
  • I work on art for a monster – which takes me the rest of the hour (and it still doesn't look very good- I should have just used a smiley-face).

Hour 28 – The Monster Appears, and the Player Has to Change His Armor

  • I get the display routines working for monsters
  • I make the monster block the player's movement.
  • The perspective on the monster is totally different from the player, but I don't care. But the player graphic looks more terrible by comparison, so I re-do the player graphics.

Hour 29 – Time to Come Out Swinging

  • I create a menu and menu-responder for the mnster.
  • Player attacks are working
  • Main loop responds to the monster dying.
  • Experience points are awarded for killing the monster.

Hour 30 – With this Sword, I Thee Slash

  • I create the first of true equippable "items" (a '+1 sword')

  • Monsters drop their items when they die.

  • Game loop update gets broken into turn-based and non-turn-based updates.

  • Massive changes to player movement / actions based on the turn-based architecture.

    Hour 31 – Entering the Final Stretch

    • Monsters get emotional – I give them three 'attitudes' towards the player, which can be adjusted by player actions.
    • Money is added to the game, in the form of silver
    • I get the "negotiate" action working, where you can bribe the monsters to leave you alone if you haven't attacked them yet.
    • Monsters attack a player if the player is right next to them (and they've not yet been bribed).
    • I fix a bug where the player decides to treat a monster like a chest, and runs up to them to begin the negotiation. This gives the monster a free attack before the negotiation happens. That kinda ruins the point, but it's funny.

    Hour 32 – Why Can't We All Just Get Along?

    • Finish negotiation logic
    • Add monster hunt / chase routines
    • Monster chooses between spellcasting attacks (stubbed out) or melee combat

    In order to save time, I cheat on monsters chasing players through a portal. I just assign a random chance of the monster going through the portal each round. This gives the player a better chance to escape, anyway.

    Hour 33 – Wandering Artwork

    • Monsters now wander around if they aren't actively attacking the player.
    • Artwork for some items and potions
    • I add potions as items – they don't work yet, but they appear

    Hour 34 – 35 – Drink Me!

    • Potions get added to the player's potion inventory
    • Potions have the appropriate effect on the player's stats. Healing Potions restore hit points, Essence potions restore mana points.
    • I add pure treasure (which gets converted immediately into silver) as an item.
    • I start working on equipment items.

    Equipment items are a little tricky. Since I don't have an "inventory" of unused equipment, you can't carry a spare sword around with you. If you pick up an item and you already have another item in the "slot", the game asks you if you want to replace the old item, or cash in the new item for treasure. For items where only a single slot is permitted (like a weapon, or armor), that's not too hard. Wands and rings are more complicated, since those can be in one of several slots.

    After almost an hour of working on this, I realize that I've got the player running through two menus (one to pick up an item, and another to choose what to replace) for items is really ugly. It's far better to have the game be "smart" about it and reflect these options in a single menu.  I end up overhauling some of what was already done, throwing away a little bit of code, to make this change to a simpler system.

    Hour 36 – HACKENSLASH!

    • I create a "Hackenslash" title panel with a sword graphic, and link this bitmap into the right UI panel display
    • Add the logic for the "monster display" panel to display the information on whatever monster last had the mouse pass over it.

    Hour 37 – We Don't Need No Stinkin' Word-Wrap!

    I create a scrolling "text box" class to display game mechanics information. This is useful both for player feedback and for debugging purposes. Without any user controls (like scroll bars), development goes extremely quickly. It actually takes more time to send it lines of text from various events in the game (picking up items, attack results, etc).

    Some of my preliminary work back in the first 20 hours is FINALLY paying off - there's a good framework in place for calculating the bonuses for skills based on equipment. All items have a 'dictionary' (a great Python construct) of bonuses and penalties to SOMETHING (the name of the roll). So when I get ready to make a roll, say, an attack roll, I just run through the equipment list and apply all adjustments with an "attack" key. I'll do something similar for spell effects.

    Next, I work on the menu for opening chests – and decide to simplify it significantly. Why not just assume the player is ALWAYS going to check it for traps, and will ALWAYS attempt to unlock it if it's locked? The extra steps in there are tedious. No sense in having trivial choices floating around.

    Hour 38 – A Little Bit of Magic

    I'm frantic now. Three hours left – I have to work on ONLY what MUST be in the final game.

    • I generate five types of spells – three that are cast on the player, two on monsters.
    • I add extra "levels" for the spells to give them slightly more variety. The levels vastly increase the power (and cost) of the spell, and are only available as the player's "magic" skill increases.
    • I make the player-menu non-static, so I can add menu options that become available only under certain circumstances.
    • I add the ability to "level up" through a set of menus that become available from the player menu when the player's experience points exceed a certain level-based threshold.

    Hour 39 – Crisis Management, Part II

    What I'm missing:

    • Searchable secret doors and items
    • Quest Items – and a place to return the quest item to win the game
    • Sound Effects
    • Music
    • A merchant from whom to purchase equipment
    • A place to rest
    • Random equipment with different bonuses and names
    • Random monsters
    • Graphics for the new equipment, monsters, and merchant.
    • Random chest traps & locks
    • Creatures casting spells
    • Wands
    • A larger dungeon with a quest item (and maybe boss monster) at the end.
    • The ability to sneak around (?) to avoid being attacked by the monsters.

    There is no way I can get these all in with a little over 100 minutes to go.  I can handle maybe three or four of these if I'm fast. What is the minimal set of items needed to make a playable game?

    I decide on the following

    • The player must be able to rest to regain health and magic points
    • Monsters and treasure should respawn while the player is resting
    • Random equipment types and abilities should be generated with the treasure, and should gradually scale up by player level
    • Random monsters should be created with abilities and numbers that scale up to the player level.

    The initial room (the one up the stairs) becomes the the "rest" room (pay no attention to the awful pun – aw, heck, it's part of the charm). There will be no monsters in this room, ever. I add a new dynamic entry into the player menu when he's in a rest area – the "rest option." Then I create a routine to "re-initialize" the dungeon while the player is resting. Right now it's a stub.

    I add the remaining equipment graphics in GiMP. I have no time to make them look any good. I simply draw them in 32 x 32, blur them in areas to hide my awful artwork, and then sparingly add some highlighting so they don't just look like a blurry mess. Now they look like a touched-up blurry mess.

    For the random equipment generator, I have the game pick one or two random abilities and slap them onto the item, with a possible range based on the player's "level" (Editorial note: Unfortunately, the player's level is never actually displayed on the screen anywhere. D'oh!). Certain items have mandatory effects – a sword has to improve either your attack or your damage rating, armor must improve your armor rating, and a shield improves your defense rating. I add these constraints… and we're now already well into hour 40.

    Hour 40 – The End Is Near

    I have no time to create actual unique monster types – so I frantically work on just changing the names and stats of the one monster I have – the goblin. I throw some silly-sounding adjectives in front of the goblin names, and I have them "level up" similarly to the player based on the player's level. I finish up the "re-initialization" routine to repopulate the dungeon while the player rests. I finish up some routines to deactivate monsters that are far away from the player, and to make them become active when the player enters the room.

    I add a couple more rooms to the dungeon, and then I'm out of time.

    Post-Development Work: Wrapping It Up With a Bow

    After talking with a friend, I'm convinced that I shouldn't work on fixing any bugs except the ones that crash the game. Since the purpose of this project is to show off what can be done in 40 hours, I leave it in that state. There are lots of non-critical bugs: stats aren't being displayed properly in the right-hand panel; I don't think goblin hit points are increasing with level; I'm not convinced monsters are properly de-activating; monsters are ignoring collision detection; treasures are appearing inside interior walls; monsters are ignoring magic attacks from long range…

    I leave them, and focus on the crash bugs. This means playing the game quite a bit. It's actually pretty fun. Not play-this-game-for-hours fun, but certainly an amusing diversion. Once the crash bugs appear to be mostly quashed, I work on the distribution.

    Py2exe is supposed to make things ridiculously easy, allowing you to package a Python program as a native Windows executable, including everything you need so that users don't need to have Python installed to run the program. It's not quite so easy as all that. First, it tells me there are missing modules, and the executable crashes in the font code. I check on the Internet, and find that the 'missing modules' are red herrings, and what I'm missing is a font file that needs to be copied over manually.

    After I do this, I get another crash in the executable. This is much harder to track down. It turns out that I need an icon for the window – something that didn't seem required in the non-compiled version. Once I have that in place, everything works. I run a few more tests – and I seem golden. WHEW! I create a zip file of the distribution (I'm not going to bother with an installer / setup program), and I'm DONE.

    My week-long project actually took two-and-a-half weeks of real-world, part-time effort. It's definitely not everything I hoped it would be, but I'm pretty proud of what I accomplished:

    http://www.rampantgames.com/hackenslash.html





    Aftermath: The Post-Mortem


  • Contents
      Introduction
      The Development Diary of Hackenslash
      The Development Diary of Hackenslash, Pt. 2
      Aftermath: The Post-Mortem

      Printable version
      Discuss this article