In my previous post on the GameAPI (original RFC here), I talked about map making and the concept of a room: a single location, regardless of size, that could contain other, smaller, locations. A house, being one large "room", could contain three smaller rooms, for a total of 4. Re-read my earlier post, as its discussion of the user-interface to these rooms will become a key consideration in the following discussion.
Progress on the GameAPI has been slow but steady, and I've only two or three remaining TODO items for the character creation framework before I'll consider it "done enough for now". Next up is room definition and map making, to which the earliest question is simply put: coordinate-based or unique names? I've decided on coordinate-based, and the following is a meandering set of reasons why.
A coordinate-based system would place each room in a simple three-dimensional space, such as 15,14,0. 15 and 14 are the x,y coordinates, and z, here 0, would refer to the vertical plane. If 0 is "ground floor" of the inn, then 1 would be the second floor, and -1 would be its basement. Coordinates would be unique to a namespace, specifically, the include file they've been defined in. If rooms/inn.inc defines 15,14,0, it has nothing to do with the 15,14,0 in rooms/forest.inc. Likewise, the measure of the vertical plane is unique to the namespace: for the inn it may refer to floors, but for the "overworld", it may refer to inner-earth, "outside", and space.
A name-based system doesn't use coordinates at all: locations are inferred from connections the rooms define, and each room has a unique name like "bar" or "1F_bathroom". Two inspirations for the framework I'm trying to achieve, Inform and LPC (from LPMUDs), both use name-based definitions.
Here's an example from Inform:
Object before_cottage "In front of a cottage"
with description "You stand outside a cottage ... "
e_to forest;
Another from LPC (Dead Souls mudlib):
static void create() {
room::create();
SetShort("Servants' Quarters");
SetExits( ([
"east" : "/domains/town/room/mansion_uhall3"
]) );
SetObviousExits("e");
}
And a possibility from the GameAPI:
$rooms['bedroom'] = array(
'description_short' => t('Morbus\' bedroom'),
'description_long' => t('This den of smut is ...'),
'e_to' => 'love_nest',
);
The advantage of this approach is that you never have to worry about esoteric numbers like 15,14,0: if you want something to be up, you just use "u_to" and up it is - you don't think of "well, up is the z coord, so this room is 1 to the ground floor's 0". A possible disadvantage is you lose all sense of direction when you attempt to tell someone about it: "I'm three rooms to the north of the convenience store, left at the great rock, and then under the shoe" is a bit more difficult to say, retain, and recite clearly than "I'm at field: 13,14,2". Asking for directions when you're lost is the rough equivalent of this approach when compared to a coordinate system.
The other main disadvantage to named-based definitions is largely due to their heritage: both Inform and LPC are intended for plain text-based gaming only, where a visual map is usually non-existent (or else client-software-created or fan-made). Per my previous post on the GameAPI, I would like a visual and dynamically-created (though optional) map, and the name-based approach makes it slightly more prohibitive to code.
In a coordinate-based system, we need merely to find where the player is located (15,14,0) and then branch out mathematically to our map boundaries: a 3x3 two dimensional map can be created by just loading up the range of connecting coordiates (14,13,0 14,14,0 14,15,0, etc., for a total of 9 rooms). That makes the map-generation code a bit easier (though, granted, not by much), but it also reduces the map-makers coding time, as they no longer have to explictly code the connections of a particular room if it's unnecessary: northeast of 15,14,0 is 16,13,0, southeast is 14,15,0, and so forth. If someone can't go west, then the mapmaker can simply not define that coordinate or, in the case of an adjoining room with no door, deny access to it with code (though, this denial of access needs to have a bit more thought put into it - I feel more comfortable forcing written connections than forcing written denials). The problem, of course, is cognition and visualizing the grid the map is apart of. Visual tools to create maps, though not on my mindmap, would certainly ease any such difficulties.
A possible example of coordinate-based GameAPI definition:
$rooms['15,14,0'] = array(
'description_short' => t('Morbus\' bedroom'),
'description_long' => t('This den of smut is ...'),
);
$rooms['16,14,0'] = array(
'description_short' => t('Morbus\' love nest'),
'description_long' => t('Eggs! Eggs all over the walls! ...'),
);
Difficulties in a coordinate-based approach, besides the previously mentioned cognition, include new additions in the middle of the map. If you've got a 50 room map and you want to add a new room smackdab in the middle, doing so in a text editor is cumbersome - you'd have to either delete a room, or manually edit all the existing coordinates. This also causes problems for other maps that have connected to yours: if inn.inc connects to tower.inc at 15,13,0, but that's now a brick wall due to edits. For now, I'm considering that a "rare event", and one best solved by better editing tools.
Even though a coordinate-based system can infer connections, such that 16,14,0 is east of 15,14,0, a mapmaker would still have the ability to force a definition. Perhaps moving east of this room translates into "stepping outside the town and into a forest" or "being transported from ground level at one planet to a floating city on another planet". Since those are different namespaces ("town" vs. "forest"), there's no way code can infer that without additional help. I've not fully hammered out this aspect of connections, but the same problem exists with a name-based approach.
Thoughts, comments, flamewars? No code has been written yet. Stop me if I'm an idiot.
Comments
Going strong
Well it seems to me you've put a lot of thought and consideration in this issue, and defined the pros and cons of both options. I agree with your conclusion that coordinates make the most sense, especially when you allow the mapmaker to force a definition. The problem of adding a new room smackdab in the middle of a map can allways be resolved by a module for instance (you can bet someone will quickly make a mapmaking module for the GameAPI).
I wrote an article/summary on my blog about the GameApi btw: Create Content > RPG. I'll keep track of the development and give regular status update.
Excellent, thanks for the
Excellent, thanks for the post!
At the moment, I'm thinking that "forced definitions" will be a setting that the mapmaker will set himself. If I'm making a forest, I don't want to have to set all the cardinals myself, so I'd set "force_definitions" off. If I'm making a dungeon or a house, then I would want forced definitions (so that I can control where walls are, etc.).
http://www.disobey.com/
http://www.gamegrene.com/
Developer of Drupal's GameAPI
http://www.disobey.com/
good work!
this is so i remember read the post in the future. important stuff here!
Advomatic (Web Design for Progressive Advocacy, Grassroots Movements, and Really Cool Causes)
Games Group
New group at http://groups.drupal.org/games-and-game-apis for those watching...
Aaron Winborn
Spindowners (A web text-based sci-fi rpg in development...)
Advomatic (Web Design for Progressive Advocacy, Grassroots Movements, and Really Cool Causes)