Geeks With Blogs

News

Google My Blog

Catch me at: The List!


My InstallScript Utility Belt My Amazon Wishlist
My Standard Disclaimer


Archives
Chris G. Williams Beware: I mix tech and personal interests here.

As I work on my RPG project, I'll use this blog as a notebook to track my thought process and ideas.

What kind of information do I want to store about a given tile within my map?

For starters, I need to know what kind of tile it is (is it solid stone, a wall, a door, a floor, grass, a road, water, etc.) So here's a preliminary stab at a list of Tile types:

public enum TileType { Desert, DoorClosed, DoorOpen, Floor, Grass, Hill, Ice, MountainClimbable, MountainUnclimbable, Road, SecretDoor, Stone, Volcano, Wall, Water };

 

I'll also need to include information about Traps. Not all tile types can contain traps, but dungeons certainly will, so off the top of my head, I'll add the following:

public enum TrapType { Sleep, Stone, Fire, Pit, Shock, Confusion };

 

I'll worry about implementation of the traps later on. For now it's good enough to know if one exists on a given tile, and what kind it is.

For some maps, like dungeons, there will be special tags that "help" other routines work properly, so I need to distinguish certain areas, such as rooms and passages, as more than just the walls and floor that make them up. Also, Chambers are a type of Room that has special features:

public enum RegionType { Chamber, Room, Passage };

 

So at this point, I've got some basic info about the tile, but I also need to store information about any creature(s) that inhabit this space. I haven't decided yet if the game will support multiple creatures (monsters) per tile in addition to the hero. As creatures are created and destroyed in game, they will be managed by a master list, so we only need to store the ID of the creature(s) that occupy the tile. I'll go ahead and create a List to handle this, even if I only put one thing in it.

In addition to creatures, I need to store the IDs of any items (treasure or otherwise) that can be found at this tile, so I'll create a list for this as well.

This gives me a structure that looks basically like this:

public struct MapTile
{
TileType tileType;
TrapType trapType;
RegionType regionType;
List<int> itemList;
List<int> monsterID;
}

 

I'll use this structure as the type for my map array. I'll return this array when I call the CreateDungeon() routine, as shown here:

public static MapTile[,,] CreateDungeon()
{
MapTile[,,] map = new MapTile[DUNGEONWIDTH, DUNGEONHEIGHT, DUNGEONDEPTH];

// blah blah Do Stuff here...

return map;
}

As this project progresses, I'm sure more will be added (and some things removed) so I'll update these accordingly.

Posted on Tuesday, February 24, 2009 9:50 PM | Back to top


Comments on this post: RPG Project update

# re: RPG Project update
Requesting Gravatar...
Do you mind basic programming questions about this stuff? MVPs are supposed to support junior programmers, right? :)

Why is MapTile a struct rather than a class? I expect that it's a stack versus heap thing, but if they're stored in an array, I'm not sure that makes sense. So maybe it's something else. But I'm really sketchy on this stuff.

And in your RegionType, you talk about tagging areas with special designations. What are the chances that you'd want to use a broader list of tags that might combine and so install region type as a list. I'm imagining things like "hot," "passage" and "goblin-controlled" or whatever. Even if you're not interested for your game, is there a more broad reason that that's a bad approach? (For that matter, your other enums might be fun to handle that way. This tile is an ice-secret door with a shock-pit. :-)
Left by Christopher Weeks on Feb 25, 2009 10:03 AM

# re: RPG Project update
Requesting Gravatar...
Don't mind the questions at all.

Structs live on the stack. This will yield performance gains. Also, I'm not dealing with references to an instance of a struct as I would with classes. I'm working directly with the struct instance. I'm not inheriting it either, so a struct makes sense.

As for the Region tags, that's not a bad idea at all. It definitely adds to the complexity of the map generator, but could produce some fun combinations. In my case, I'd keep that list of adjectives seperate from RegionType since I have something specific in mind for that, but including an AdjectiveList like you describe makes a lot of sense. Excellent suggestion.
Left by Chris G. Williams on Feb 25, 2009 11:02 AM

# re: RPG Project update
Requesting Gravatar...
Chris,

I'd also take a look at these:

http://en.csharp-online.net/.NET_Type_Design_Guidelines%E2%80%94Choosing_Between_Class_and_Struct

Generally, I never make a struct. They always seem more "hassle" than they're worth for a number of reasons. That doesn't mean they're worthless - I just find myself using them on very rare occasions.

Also, about the performance comment...just because it's a struct doesn't mean it'll automatically perform better. I'm guessing that's not what you meant, but I'd be interested to see how a similar definition of MapTile would perform if it was a class by doing some performance measurements against the two.

I'd also rename the enums to not have "Type" in them. That's a sign that the enumeration is actually trying to represent a "type" in the .NET sense which I don't think is your intent.

Are you doing unit tests with this stuff? I remember we talked a long time ago about unit testing game-based code and this seems like the perfect opportunity to go down that route.
Left by Jason Bock on Feb 27, 2009 5:12 PM

# re: RPG Project update
Requesting Gravatar...
as I understand the difference, which may be wrong, making an array full of structs still only creates 1 reference in memory, while an array full of classes makes an in memory reference for each class (potentially thousands)

If I was using inheritance or interfaces or instantiation, I'd go with a class for sure, but structs seem to make sense here. (and I'm more than happy to discuss it if I'm totally missing the point) :)

re: types, that's a good point and definitely not my intent. So would plural form make sense here? Traps instead of TrapType, Tiles instead of TileType? Or should it be singular?

I haven't written enough code to test yet. ;) So far it's mostly been all declarations. Having said that, I DO want to incorporate unit tests into this, though for the life of me I'm not sure where to begin.
Left by Chris G. Williams on Feb 27, 2009 8:56 PM

# re: RPG Project update
Requesting Gravatar...
After the above exchange, I reviewed the topic and in the Wrox _Visual Basic 2005 Programmers Reference_ I read:

"If you must use a large array of object where only a few at a time will have values other than Nothing, then using a class may save the program a considerable amount of memory. If you will need most of the objects to have values other than Nothing at the same time, it may be faster to allocate all the memory at once using a structure. This will also use slightly less memory, because an array of class references requires an extra 4 bytes per entry to hold the references."

And later, which is what I was remembering in my above oblique reference to the array negating stack-based gains:

"Note that arrays are themselves reference types, so all arrays are allocated from the heap whether they contain structures or references to class objects. The memory for an array of structures is allocated all at once, however, so there is still some benefit to using structures. All the memory in an array of structures is contiguous, so the program can access its elements more quickly than it would if the memory were scattered throughout the heap."

So, and please let me know if I'm drawing the wrong conclusions, by my reading, the why you're doing it is basically perfect assuming that each array is custom to each dungeon, etc. But if you were creating several e.g. 1000x1000x1000 dungeons and usually only filling portions of them, then you'd want to switch to a class. (Except that really, you'd just want to customize the arrays.)
Left by Christopher Weeks on Mar 03, 2009 4:32 PM

# re: RPG Project update
Requesting Gravatar...
Consider making Trap a class that you can inherit from. This would give you a way to easily implement new traps without having to change core code. Also consider making Trap inherit from a base "action" class that supports the basic OnEnter() and OnExit() methods, perhaps the Tile class? This would give you a very flexable platform.

class Tile
{
OnEnter();
OnExit();
}

class TrapBase : Tile
{

}
AcidTrap : TrapBase
{
OnEnter()
{
//kaboom!
}
}

You also now have the foundation for action items like:
Teleporter : Tile
{
OnEnter()
{
//move the PC.
}
}

I have always used enums for things that don't change (often) like the TileType being Passive, Slowed, or Impassive.



Left by Keith on Mar 09, 2009 2:28 PM

Your comment:
 (will show your gravatar)


Copyright © Chris G. Williams | Powered by: GeeksWithBlogs.net