Showing posts with label dungeons. Show all posts
Showing posts with label dungeons. Show all posts

Wednesday, February 6, 2008

The World Model

I've been thinking a lot about my implementation of the world, and how everything will fit together. I haven't decided on it yet, so I figured I would take the chance to go through my thought process "out loud" so anyone can benefit from it. Hopefully a coherent post will come through, since none of what I'm about to say is premeditated.

Before I begin I'll discuss some terminology. For the sake of this post the world is the entire game, and internally this is a collection of maps. A map is a single screen within the game. A dungeon is any vertical series of maps, this would include a tower since it's just an inverted dungeon.

I'll start by describing my goal for the system. I decided early on that each map in the game will be randomly generated. Once a map is generated it doesn't get recreated. I want to describe my world in such a way that it can be created randomly but retain a general look. So how do I go about doing that?

Since my maps will be both outdoor and indoor this lends itself to some interesting issues, the first of which is interconnectivity. Stated more clearly, I need to be able to determine that each of my maps are connected to any adjacent maps. Any given map can have connections from the north, south, east, west, up, and down. This lends itself well to a three dimensional coordinate system. Maps connected vertically will only need to be connected from a minimum of one point, but they could be connected by more. Maps connected horizontally can be connected by any number of points, and for most outdoor maps these connections are on each point on the outside of the grid.

Each map can be described in a text file by a list of grid workers used to create it, and the parameters for those grid workers. The only other thing the maps need to know is what maps are adjacent to it. They need this information for several reasons. Firstly, they need to know what connections to create. Secondly, they need to know what the adjacent maps look like, because we want to preserve the look across boundaries. For instance, if we have a forest map that borders a desert we don't want a harsh cut from forest to desert once the character travels to the next map. We'll want to organically blend these together so it looks natural.

This can be handled in a few different ways. I can generate the entire world at once, but that would take a long time and be a lot of useless processing up front. Also, I can look at the adjacent maps and use their creation algorithms to bleed the two maps together. This is a lot more difficult than it sounds, but probably the best solution. The bleed algorithms will have to be pretty intelligent, or a wide view of the world will just end up looking like a bunch of rectangles loosely connected. I'll probably need something in addition to bleeding, like the ability to set percentages on a given map. For instance, 25% of the north and west will be desert, while the remainder will be forest. I feel this is a problem I'll be fighting with for awhile.

This system will allow me to create a relatively complex world that is still randomly generated. Each map on subsequent plays will look slightly different. I'm worried that this will be stale, and if that lends itself to be true I'll have to think of a different system. The only other thing I can think of is instead of defining individual maps I would define regions. A forest could be anywhere from 2 to 5 maps large. There is a dungeon somewhere within a 5 map radius of this point. Stuff like that. Only time will tell.

I think I've said all I can say on this topic for now (or want to). As always, any comments are welcome!

Monday, January 28, 2008

First Week: Update

Since it's been roughly a week since I've started development on Mirage, I figured it was time for a status report. Of course real life interferes with development so I haven't really gotten as much work done as I'd like. However, I am pleased with my progress so far.

The first thing I started doing was coding my Display Model. Details of that creation can be found in my previous post. I'm happy to note that this model is serving me nicely as I move forward with production. It is an excellent base that (so far) handles everything I'm throwing at it nicely.

The next thing I worked on was Tiles. Tiles are my base object in the game, and is the base for objects that are put into my display model. They are essentially any object that can be displayed within the game. On top of this base class I derived two classes, Terrain and Actor. An Actor is any tile that can move around the grid. Upon further thought I think I'm going to rename this base class to Entity, since I'm using it for things other than the player and enemies.

The Actor base class has been fully fleshed out, and from that I've got an initial Hero, Enemy, and Projectile. You can interact with the Hero through the keyboard, you can move it around the board, and shoot Projectiles around the grid. All Actors have hit detection so the Projectiles work just as you'd expect. Enemies also move around the screen randomly, but that's all they do currently. The structure is there to add AI and more complex logic to them though, so once I feel the need to give them a little more life I'll be able to move on that.

After laying the ground work I started to work on some initial dungeon creation. I've just been playing around, but I've had the chance to implement two algorithms. The first I implemented was a cavern algorithm, that with the right parameters could also be used for other environmental features (lakes). The other algorithm implemented is just for a basic dungeon. It's nothing special and just adds about 16 rooms to the dungeon, but it's something to start with for now. I'm still working out the structure in my head on how dungeon generation is going to work. This is especially important at this stage, because I want anything even remotely content related to be in flat files outside of the code. I'm trying to think of the best way of doing this, so if anyone has any ideas I would love to hear them!

So that's essentially what I've worked on. It's mostly just the base stuff to build the game upon, and I'll start to develop some of the more specific stuff soon. My next focus is some early dungeon and map generation. This will include saving of the created maps, and html output as well. Once I've got that going I want to add some logic to my actual Terrain tiles, since currently the only difference is the look and all Actors can walk through "walls." I'm trying to think of a way to represent this logic so that it makes the most sense to me as well.

So that's where I'm at. It's been a ramble, so I hope you could follow along. I'd love to hear peoples thoughts on my progress. Any input would be much appreciated.

Tuesday, January 22, 2008

The GridWorker!

This post is going to be more software development related rather than roguelike related, but it is still applicable in many cases. I'm going to talk about the importance of, and my obsession with, naming classes appropriately. Since this is my own project, not one I'm getting payed to do, I spend more time on these design issues than normal. You'll see this in my over analysis below.

I've been holding off on dungeon creation so far (except for a few small tests) for one reason, and one reason only. Because I couldn't decide on a name for any classes related to the task. I have a particularly interesting quirk. I can never decide on a name for a class, and in most cases it takes me longer to name a class than to actually write it. Even once written I end up renaming the class multiple times until I feel it suits it completely. Even though I admit this is weird, I do also think this is necessary (to a certain extent).

We all know that you're supposed to name a class logically. In this case I could've just named my class DungeonCreator and I would've been done with it. This seemed too specialized though, after all if this was my base class it wouldn't feel right if down the line I was deriving from this to fill the grid with terrain as well. Having thought about it more I decided I should make a generic base class that DungeonCreator could derive from.

The first thing that popped into my head was GridBuilder. It makes sense, but it didn't sit well with me. Mostly because the class wouldn't actually be building the grid, that would be done sometime during the initialization of the game. I hit up the thesaurus and after many failed and overly complex names I decided on GridFiller. It seemed as if I'd finally found the right name and I could begin developing. Third time's a charm right? Wrong! The class wouldn't be filling the grid, just part of it. This is an extremely minor quibble, but it demonstrates how crazy I am about naming my classes.

I'll cut to the chase to save you from further boredom. I finally decided upon GridWorker as the name for my class (I'm sure you could've figured this out by now). It only has a constructor, a pointer to the grid object, and a virtual function entitled DoWork that can be derived from to do the actual work on the grid itself. So what was the benefit of all this naming and renaming you might ask? Well I now have a class that is completely abstract, and that doesn't shoehorn its derived classes into a specialized role. It reduces overall complexity of the code, and you can instantly know what a derived class is doing just by looking at the name of its base class.

The most obvious use of a GridWorker is to derive from it to create dungeons. I can also use it to place items and enemies upon a map. I could make a class that outputs a grid to html, or the state of a grid to a save file. Virtually (no pun intended) anything in the game that might want to look at or do something to the grid could derive from GridWorker. I can create a task that will get processed while the game runs that contains a list of GridWorker objects. It would then be trivial to iterate through the list and call their DoWork function, performing several different unrelated tasks, but still using the same structure.

This post was a window into my development style. I take a lot of time to create the base classes of the game in order to reduce complexity down the road. I'm a firm believer that the more time spent designing earlier on in the project will save much time in the end. The above example illustrates how just the naming of a class can simplify and streamline the entire structure of a program. In particular, roguelikes can benefit from this methodology because of the number of extremely similar objects that can have vastly different behavior.