Category: Dungeon Delver


Alright, week three of #iDevBlogADay and I haven’t been kicked off yet!

This week I’m trying something different by putting up a screen cast of me drawing one of the creatures for Dungeon Delver and droning on about my creative process, or lack there of. It’s kind of long, and I think some people will dig it and others not so much. I probably could have found ways to cut it down but if someone is really interested in seeing the whole process, now they can.

So, without further adieu, here it is:
You should really go view it in HD at Vimeo. I don’t have a pro account so Vimeo won’t allow me to embed the HD version here.

Drawing a creature for Dungeon Delver from Broken Platypus Games on Vimeo.

Let me know what you think. I’d like to do more screen casts, so feel free to give suggestions on what would make the next one better for you, either in the comments or on twitter, or by shooting me an email at mattguest@gmail.com if you’re the type that prefers to be more discreet with your criticism.

New Gameplay Video

First off, if you are at all interested in Dungeon Delver’s progress then you should really be following me on twitter (@brokenpgames) because I post little updates there a heck of a lot more than I update this website.

However, since my traffic logs show that someone out there is still waiting for an update, here is a video I took of the gameplay a few days ago showing off the latest addition to the engine – ranged combat. So far I’ve added bows, but the tile highlighting and picking will be used for other actions as well, such as spells. I’ll be adding a few other ranged weapons as well.. probably slings and throwing daggers.

Dungeon Delver Ranged Combat from Broken Platypus Games on Vimeo.

The engine is just about complete at this point. The few things left to do are state save and load, which should be fairly straightforward using NSCoder, tightening down the skill and leveling system, and adding a screen for starting a new game or continuing. After that the engine will be feature complete (for this game anyway, lots of new features planned if I make a DD2) and I’ll get to concentrate on what I really want to do – make tons of monsters, items, and story.

It’s been a long road, but I think I can see a light peeking out from around the next bend in the tunnel.

Still around, still working

I haven’t updated the site in a while, but wanted to stop in to assure my hundreds, nay – thousands, of loyal fans refreshing the brokenplatypus.com website 30 times a minute that I am in fact still working on Dungeon Delver! Things are coming along nicely, in fact. I have randomly generated dungeons linked together in a currently endless procession, populated at this time exclusively by little purple blobs and giant rats.

I have been updating my Twitter account (@brokenPGames) quite often with updates and screenshots as I’m working, so if there is actually anyone out there interested in Dungeon Delver’s progress then that is where you’ll see the freshest, most succulent morsels of information.

I’ll be working on the character stats and combat system in the next week or two, at which time I’m sure I’ll the waxing philosophic about mechanics and various methods of simulating combat.

rat

Look out, it’s a giant rat!

In all RPGs – computer, console, and pen and paper – one of my all-time favorite classes to play is the rogue. I love sneaking around, stabbing things in the back, and pulling off stealthy head shots from afar. The only complaint I’ve had is that it’s difficult to play a true stealth character in a lot of games because they don’t provide experience for avoiding conflict.

In many pen-and-paper games, the game master can provide experience for resolving a situation, whether it was through combat, negotiation, or completely circumventing it somehow. This is difficult to pull off in a computer game. It’s really easy to give out experience for killing an enemy, but what if you used stealth to avoid combat, or froze the enemy with a spell and then high tailed it out of there? Should you get experience from that?

This is a question I’m putting a lot of thought into for my game. I would like there to be real differences in how a player plays depending on their character. If you work up your stealth attributes, I don’t think you should be punished for avoiding combat. The question is when is it appropriate to award experience for this, and how do you guarantee that players can’t double dip, avoiding the enemy and gaining experience and then killing it for more.

One idea I had was to give each enemy a max experience value that gets transferred to the player bit-by-bit for different actions. Here’s a scenario:

Goblin: 100 max XP
Player turns on a stealth skill and manages to sneak past the goblin, who is within 5 squares of the player. Player gets 20xp for this, goblin now has 80 left in its pool.
Player comes back that way again and sneaks past – another 20 point transfer, goblin has 60 xp left.
Player tries to sneak past again and is noticed, combat ensues, player kills the goblin and gains the remaining 60xp.

If the player hadn’t killed the goblin, then they would have earned 40xp from it. They’re still not rewarded fully for avoiding it, but I think by tweaking the numbers it would be enough that playing a non-combative stealth character would be a viable option.

I’m still not sure how to reliably detect a non-kill defeat though. I could see a rogue character scoring a hit on a creature to stun it and then running out of the room, locking the door behind him to trap the creature. It seems like that should deserve some XP, because it’s a more true to character action than standing there pounding on the enemy like a warrior, but how best to detect those scenarios and award them? The answer is that I’m not sure yet.

Another idea would be to implement offensive skills that would be more appropriate to a rogue character. If a rogue builds a trap on a square and then lures a creature into it then they get experience for the kill. Running away or avoiding a creature wouldn’t gain xp, but passively defeating it still counts. And then there’s always the old ranged attacks standby.

Getting off of the rogue class specifically, I’m also undecided on the type of skill system I want to put into the game. I’d like to keep it casual and avoid having the player distributing skill points or picking powers, but feel that the ability to mold different types of characters through play should be integral to the game.

One idea I have is to split skills into several categories, like “Rogue” “Warrior” and “Mage”. The player starts with an equal skill in all three categories and as they do things in the game experience points accumulate in the different pools accordingly. Attacking something with a sword puts the XP into warrior, using stealth or picking locks gives you rogue points, and casting spells or using scrolls increases mage. When the total XP from all groups combined hits a threshold then you gain a level and your general stats go up, but modified by the distribution of points. So, a player that has done a lot of head on combat will gain more hit points per level than a stealth character, and a magic user will gain more mana than a warrior. When the points in a particular category reaches a threshold then new skills may become available. So, a character with a lot of warrior points might be able to conduct a spin attack that hits all squares around him at once, while a stealth character might get a tumble action that allows them to slide several squares in one round. These skills could be a bit randomized to add to the Roguelike feel of the game. Each time you play a new game different sets of skills could be given to your character in each category to keep it interesting.

As you can see I’ve got a lot to ponder here. If you have any comments or ideas, please step forth and speak your piece.

Interface begining to take shape

I’ve had the control scheme for Dungeon Delver set up like several other roguelikes in the app store, using the top of the screen to move up, bottom to move down, left – left, right – right. I found after a lot of playing that this really becomes unfomfortable after a while. I think it’s important that the game can be played with one hand, and this control scheme starts to wear on your hand pretty quickly. So I’ve decided to go with a d-pad. It will be trivial to keep both schemes, so I may end up making it an option.

Another thing I keep repeating to myself is that this is going to be a fairly casual Roguelike. I don’t want anyone to have to pour over a manual to figure it out, or memorize obscure commands. I understand that this is half the fun in a real Roguelike, but that’s not what I’m aiming for with this game. With that in mind, I am also adding interface buttons for all of the major actions a player can take. I’ve added a button to open and close doors already, and there will be others to use your queued attacks, rest, etc. Actions like drinking or eating something will be in the inventory screen, like any modern rpg.

Here’s another video showing my first go at the d-pad. I’ve added the door button already, so you can see that in action as well. It may be hard to tell from this video, but in your hand this is extremely natural and easy to use.

Dungeon Delver – New Control Schme from Broken Platypus Games on Vimeo.

I also added a smooth transition for the player when he moves from tile to tile.

I wonder what’s around that corner?

I have added a line of sight algorithm to Dungeon Delver. It’s pretty simple, and there are a few places where it can get a little wonky, but I after playing with it for a while, I think it definitely falls into the “good enough” category.

The algorithm is very simple:

  • For each tile being drawn on the screen attempt to draw a line using Bresenham’s line algorithm from the tile to the tile occupied by the player. If you hit any blocking tile, like a wall or closed door, then the tile can’t be seen.

This algorithm is pretty brute force and could be made more elegant and optimized quite a bit, but since we have a fixed (and rather small) screen to work with on the iPhone, I’m not too concerned. It runs extremely fast in practice.

I had already built in for each tile to support a lighting value that can set the shade of a tile using cocos2d’s setColor function. This value is used to set tiles that have never been seen to black, and tiles that have been seen but are not currently visible to 50% lightness, making them darker than visible tiles. Once I get objects and creatures into the maps, they will only be drawn if they are on currently visible tiles.

I also added tile groups, which link tiles to a single entity, like a hallway or a room. When the player steps into a room, all of the tiles associated with that room automatically become visible. In practice I liked this better than just letting the algorithm do its thing as it cut down on some of the artifact problems of using Bresenham’s algorithm, which is really fast but can be a little flaky and imprecise at times. I’m not necessarily going for precision here, just what fells right and revealing an entire room when you enter it feels right to me at the moment.

Anyway, enough blabbering. Here’s a video of it in action.. also note the smooth map scrolling, which I think adds some polish while maintaining a traditional tile-by-tile movement feel:

Dungeon Delver LOS test from Broken Platypus Games on Vimeo.

And here’s the source to the main function that makes it happen for anyone who’s interested:

/////////////////////////////////////////////////////////
// LINE OF SIGHT
/////////////////////////////////////////////////////////

-(BOOL) playerCanSeeTile:(CGPoint)pos {
  Tile *t = [map getTileAtX:pos.x y:pos.y];
  if(t.type == EMPTY_TILE) return FALSE;

  Tile *playerTile = [map getTileAtX:player.tilePos.x y:player.tilePos.y];
  if(playerTile.type == FLOOR_TILE)
  {
    if(t.type != HALL_TILE && playerTile.blockId == t.blockId) return TRUE;
  }

  float x1 = pos.x;
  float y1 = pos.y;
  float x0 = player.tilePos.x;
  float y0 = player.tilePos.y;

  BOOL steep = abs(y1 - y0) > abs(x1 - x0);
  if(steep) {
    int t = x0;
    x0 = y0; y0 = t;
    t = y1;
    y1 = x1; x1 = t;
  }

  if(x0 > x1) {
    int t = x0;
    x0 = x1; x1 = t;
    t = y1;
    y1 = y0; y0 = t;
  }

  int deltax = x1 - x0;
  int deltay = abs(y1 - y0);
  int error = deltax / 2;
  int ystep;
  int y = y0;
  if(y0 < y1) ystep = 1; else ystep = -1;

  // Top Tiles contain doors and other obstacles that sit above the floor.
  Tile *topT;

  // check the tiles using bresenham's algorithm
  for (int x=x0; x
  {
    if(steep) {
      if(!(y==pos.x && x==pos.y) && !(y==player.tilePos.x && x==player.tilePos.y))
      {
        t = [map getTileAtX:y y:x];
        if(t.type != FLOOR_TILE && t.type != HALL_TILE) return FALSE;
        topT = [map getTopTileAtX:y y:x];
        if(topT.type == DOOR_TILE && !topT.door_open) return FALSE;
      }
    } else {
      if(!(x==pos.x && y==pos.y) && !(x==player.tilePos.x && y==player.tilePos.y))
      {
        t = [map getTileAtX:x y:y];
        if(t.type != FLOOR_TILE && t.type != HALL_TILE) return FALSE;
        topT = [map getTopTileAtX:x y:y];
        if(topT.type == DOOR_TILE && !topT.door_open) return FALSE;
      }
    }

    error = error - deltay;
    if(error < 0) {
      y = y + ystep;
      error = error + deltax;
    }
  }

  return TRUE;
}

Dungeon generation ala pathfinding

There are a lot of algorithms out there to create random dungeons for a Roguelike, ranging from really primitive brute force algorithms, like shown in my last post, to really involved procedures, like the one detailed here at RogueBasin.

All of these algorithms have their pluses and minuses, but none really hit on what I was looking for Either the maps were lack luster or just too random and uncontrolled. I needed something a little more flexible – something that I could put hand-crafted rooms and areas into while creating a randomly generated but still believable looking dungeon.

So after some thought it just kind of struck me while I was thinking about my use of the A* algorithm in a network routing project I worked on a few years ago. It dawned on me that using a pathfinding algorithm to connect the rooms on my map would probably generate some really nice and very flexible maps. I gave it a shot and the results are quite pleasing. Before I explain how it works, here are some results, generated with different settings and costs on different types of tiles:

Here’s how it works:

  • I create a bunch of random rooms of different sizes and scatter them around the map, marking the room tiles as floors and the borders as wall, which is important for later. These rooms could be of all shapes and sizes, or could even be sub maps with their own rooms and hallways. In this demo I have two types – rectangular rooms and rounded rooms, which just have their corners shaved off for variety.
  • After all the rooms have been created, I pick one at random to be the ‘hub’ and use an A* algorithm to draw hallways from it to every other room on the map. This ensures that by the end all of the rooms have been connected and there will be no islands.
  • The A* algorithm takes the cost of going through a tile into consideration. This makes the algorithm very tweakable. For instance, when I draw the halls from the hub room to all the others, I set other hallways as the cheapest tile to move through, empty space as the second cheapest, and wall tiles as the most expensive. This ensures that the algorithm will use existing pathways if it can and only break through the walls to create a new path when it absolutely makes sense.
  • After the halls have been drawn I change the rules, setting hallway tiles as expensive, and draw a few more halls between random rooms, which creates new halls that will attempt to go around other halls instead of using them, for more variety. Halls.

Some of the benefits of this approach include:

  • Not all rooms need to be random. You could insert hand-crafted rooms or areas and connect them to random rooms without having to modify the hall drawing algorithm at all.
  • Right now the halls are drawn from the center of one room to the center of another, but there’s no reason why you couldn’t create doorways on the rooms beforehand and connect doorways to doorways instead, ensuring that rooms are never segmented by a hall.
  • By changing the weights of certain tiles, you can make the algorithm act pretty much any way you like. For instance, if you had a room that you wanted to be sure had only one doorway, you could set its tiles to be very expensive, ensuring that the algorithm would bypass it.

And the faults:

  • It can get pretty slow, especially with larger maps. The A* algorithm is really slow when there are no tiles on the map that can stop the process in its tracks because it literally evaluates every tile on the map many times. I sped it up some by limiting the rectangle it evaluates to the smallest rect containing the two rooms its connecting, but this limits the types of hallways that will be drawn. For the size and complexity of maps I’m creating for Dungeon Delver, the algorithm takes 6-10 seconds to generate a map on the iPhone 3Gs. But, I haven’t really optimized it either, so I’m sure I’ll be able to get it to run much faster when I give it a good once-over.

I’m sure this idea has been done by someone somewhere before, but I couldn’t find it documented anywhere, so I’m posting it here. Feel free to take this code and do whatever you like with it.

Download mapTests.zip

A word of warning – I’m very new to objective-c and have done no cocoa programming before this little test app, so don’t expect too much from the structure of the app itself.. the real meat is in AStarGenerator.m.

Map Generation – Brute force

I’ve gotten a basic map generator working. I plan on doing several based on different styles and algorithms, and this first is a pretty simple brute force approach. It makes viable maps most of the time, with a cut off room here or there when too many rooms have been squeezed into too small a map. There are never any islands though, so the worst that happens is when two rooms overlap and there is a chunk of room cut off from the rest. This can actually be fixed pretty easily, and so shall be soon.

Basically, the way this algorithm works is:

  • Create X number of rooms and place them around the map. While placing a room, make sure that it doesn’t intersect with any already positioned. If it does then move it randomly and try again. About 2% of the time, let them intersect for a little extra variety. This might sound like it could get really bogged down, but during the test generation of a ton of maps it has proven to be very fast.
  • Once all of the rooms are placed, start connecting them with hallways. This part takes a room and loops through all the others, looking for the closest room that hasn’t already been used as an end point for another room. This ensures that every room will have a connection.
  • Hallways are drawn from the center of one room to the center of another using bresenham’s algorithm. This can create some pretty interesting maps because if several rooms lay between room A and room B, then they get extra connections at random angles in the process.

As I said, this algorithm is pretty simple and is about as brute force as it gets. It’s completely unintelligent and sometimes the maps look really cool, othertimes not so much.

Generally, the rooms are well scattered and the hallways between rooms are a bit chaotic. It’s also possible to get very long hallways that cut diagonally through a large portion of the map. I think these will actually be interesting from the confines of the tiny visible area on the iPhone, but can look pretty strange from a bird’s eye view. You can see some sample maps below.

I imagine dungeons like these would have been dug over many years sort of ad-hoc, without any real plan for expansion. Perhaps by a clan of goblins. If Nib-Ju-Guk needs more space because their giant acid spitting spider, Nimbu, is getting ready to have a whole littler of precious acid spitting spider babies, then Nib-Ju-Guk starts digging. I think this could lead to something like the maps below, created with different map sizes, room sizes and room counts:

As soon as I figure out what license I want to use and comment the code a little, I will make it available for download. As I’ll explain in an upcoming post, for various reasons I plan to make many of the components to this game open source.

It shall be named Dungeon Delver

Came up with a tentative title for the game: Dungeon Delver. I wanted something sort of generic, but still descriptive. I think it fits the bill.

menubg

Also did a quick title screen. This will probably change over time, but will do for now.

Powered by WordPress | Theme: Motion by 85ideas.