diff --git a/exec/ircbots/rpgbot/items.xml b/exec/ircbots/rpgbot/items.xml
new file mode 100644
index 0000000000000000000000000000000000000000..71b91f5408164e40de6e6d06b2353d8f6a06f600
--- /dev/null
+++ b/exec/ircbots/rpgbot/items.xml
@@ -0,0 +1,38 @@
+<items>
+	<item id="0">
+		<type>food</type>
+		<title>a loaf of bread</title>
+		<keywords>loaf of bread</keywords>
+		<description>
+			It is hard, stale and disgusting.
+		</description>
+		<appearance>a moldy loaf of bread is lying here.</appearance>
+		<weight>1</weight>
+	</item>
+	<item id="1">
+		<equip id="wielded"/>
+		<title>a dull practice sword</title>
+		<keywords>dull practice sword</keywords>
+		<description>The sword is so tarnished and worn that it is barely shiny.</description>
+		<appearance>a battered-looking sword lies at your feet.</appearance>
+		<dice qty="2" sides="4"/>
+		<weight>5</weight>
+	</item>
+	<item id="2">
+		<equip id="body"/>
+		<title>a tattered cotton shirt</title>
+		<keywords>tattered cotton shirt</keywords>
+		<description>The shirt is filthy and offers little protection from the elements.</description>
+		<appearance>a crumpled pile of cloth lies here.</appearance>
+		<armor>10</armor>
+		<weight>1</weight>
+	</item>
+	<item id="3">
+		<type>container</type>
+		<title>a small bag</title>
+		<keywords>small bag</keywords>
+		<description>The bag is small and lightweight.</description>
+		<appearance>a small bag has been discarded here.</appearance>
+		<weight>1</weight>
+	</item>
+</items>
diff --git a/exec/ircbots/rpgbot/rpg_commands.js b/exec/ircbots/rpgbot/rpg_commands.js
index 979585a092d59ff6d3ca534ba044f03fd90815a7..e0f09b6ae4932287f8e73d7d498dfe00542e5b9f 100644
--- a/exec/ircbots/rpgbot/rpg_commands.js
+++ b/exec/ircbots/rpgbot/rpg_commands.js
@@ -54,7 +54,7 @@ Bot_Commands["ZONES"].help =
 Bot_Commands["ZONES"].command = function (target,onick,ouh,srv,lvl,cmd) {
 	var list=[];
 	for(var z in zones) {
-		list.push(zones[z].name);
+		list.push(zones[z].@name);
 	}
 	srv.o(target,"Zones: " + list.join(", "));
 }
@@ -83,8 +83,8 @@ Bot_Commands["LOGIN"].command = function (target,onick,ouh,srv,lvl,cmd) {
 
 Bot_Commands["LOGOUT"] = new Bot_Command(0,false,false);
 Bot_Commands["LOGOUT"].command = function (target,onick,ouh,srv,lvl,cmd) {
-	var player=players[onick.toUpperCase()];
-	if(!player) {
+	var player=players.player.(@name == onick);
+	if(!player.length() > 0) {
 		srv.o(target,"You have not created a character.");
 		return;
 	}
@@ -99,6 +99,200 @@ Bot_Commands["LOGOUT"].command = function (target,onick,ouh,srv,lvl,cmd) {
 /*	Game commands */
 var RPG_Commands=[];
 
+RPG_Commands["NEW"] = function (srv,target,zone,room,cmd,player) {
+	if(player.@editing != 1) {
+		srv.o(target,"Editor is OFF. Type 'Editor ON' to enable editing.");
+		return;
+	}
+
+	cmd.shift();
+	var editor_cmd=cmd.shift();
+	
+	switch(editor_cmd.toUpperCase()) {
+	case "ZONE":
+		var zone_level=cmd.shift();
+		var zone_title=cmd.join(" ");
+
+		if(!zone_title || !zone_level) {
+			srv.o(target,"usage: NEW ZONE <level> <title>");
+			return;
+		}
+		var zone_id=get_new_zone_id();
+		zones[zone_id]=
+			<zone name={zone_title} id={zone_id} level={zone_level}>
+				<room id="0">
+					<title>{settings.title}</title>
+					<description>{settings.description}</description>
+				</room>
+			</zone>;
+		srv.o(target,"Zone '" + zone_title + "' created.");
+		player.@room=0;
+		player.@zone=zone_id;
+		display_room(srv,player,zone_id,0);
+		break;
+	case "ITEM":
+		srv.o(target,"TODO: Allow dynamic item creation");
+		break;
+	case "MOB":
+		srv.o(target,"TODO: Allow dynamic mob creation");
+		break;
+	case "DOOR":
+		srv.o(target,"TODO: Allow dynamic door creation");
+		break;
+	}
+}
+
+RPG_Commands["EDITOR"] = function (srv,target,zone,room,cmd,player) {
+	cmd.shift();
+	var editor_cmd=cmd.shift();
+	
+	switch(editor_cmd.toUpperCase()) {
+	case "ON":
+		if(player.@editing != 1) {
+			player.@editing = 1;
+			srv.o(target,"Zone editor ON");
+		}
+		return;
+	case "OFF":
+		if(player.@editing == 1) {
+			player.@editing = 0;
+			srv.o(target,"Zone editor OFF");
+		}
+		return;
+	}
+	
+	if(player.@editing != 1) {
+		srv.o(target,"Editor is OFF. Type 'Editor ON' to enable editing.");
+		return;
+	}
+
+	switch(editor_cmd.toUpperCase()) {
+	case "SAVE":
+		mkdir(z_dir + zone.@name.toLowerCase());
+		var z_file=new File(z_dir+zone.@name.toLowerCase()+"/map.xml");
+		if(!z_file.open("w+")) return;
+		z_file.write(zone);
+		srv.o(target,"Zone saved");
+		break;
+	case "RESTORE":
+		var zone_dir=z_dir+zone.@name.toLowerCase();
+		var zone=load_zone(zone_dir);
+		if(!zone) {
+			srv.o(target,"Error loading zone");
+			break;
+		}
+		zones[zone.@id]=zone;
+		srv.o(target,"Reverted current zone to saved data");
+		break;
+	}
+	
+	return;
+}
+
+RPG_Commands["SET"] = function (srv,target,zone,room,cmd,player) {
+	if(player.@editing == 0) {
+		srv.o(target,"You aren't currently editing.");
+		return;
+	}
+	
+	cmd.shift();
+	var set=cmd.shift();
+	if(!set) {
+		srv.o(target,"Set what?");
+		return;
+	}
+
+	switch(set.toUpperCase()) {
+	case "NEW":
+		switch(cmd.shift().toUpperCase()) {
+		case "TITLE":
+			settings.title=cmd.join(" ");
+			srv.o(target,"New room title set to: " + settings.title);
+			break;
+		case "DESCRIPTION":
+			settings.description=cmd.join(" ");
+			srv.o(target,"New room description set to: " + settings.description);
+			break;
+		default:
+			srv.o(target,"usage: set new <property> <value>");
+			break;
+		}
+		break;
+	case "CURRENT":
+		switch(cmd.shift().toUpperCase()) {
+		case "TITLE":
+			room.title=cmd.join(" ");
+			srv.o(target,"Current room title set to: " + room.title);
+			break;
+		case "DESCRIPTION":
+			room.description=cmd.join(" ");
+			srv.o(target,"Current room description set to: " + room.description);
+			break;
+		default:
+			srv.o(target,"usage: set current <property> <value>");
+			break;
+		}
+		break;
+	case "AUTOLINK":
+		if(settings.autolink) {
+			settings.autolink=false;
+			srv.o(target,"Auto-link disabled.");
+		} else {
+			settings.autolink=true;
+			srv.o(target,"Auto-link enabled.");
+		}
+		break;
+	case "LINK":
+		var dir=cmd.shift().toLowerCase()
+		switch(dir) {
+		case "north":
+		case "south":
+		case "east":
+		case "west":
+		case "up":
+		case "down":
+			var room_id=cmd.shift();
+
+			if(!room_id) {
+				target_id=room.exit.(@name == dir).@target;
+				target_room=zone.room.(@id == target_id);
+
+				/* clear link if no target specified */
+				room.exit.(@name == dir).(@target="");
+				srv.o(target,"Room exit deleted");
+
+				/* clear corresponding link in original target room */
+				if(settings.autolink) target_room.exit.(@name == reverse_dir(dir)).(@target="");
+			} else {
+				var target_room=zone.room.(@id == room_id);
+				var exit=room.exit.(@name == dir);
+				
+				/* set exit target for current room */
+				if(exit.@target.toString()=="") {
+					room.exit += <exit name={dir} target={room_id}/>;
+					srv.o(target,"Room exit added");
+
+				/* change exit target for current room */
+				} else {
+					exit.@target=room_id;
+					srv.o(target,"Room target changed");
+				}
+				
+				/* change corresponding exit for target room */
+				if(settings.autolink) target_room.exit.(@name == reverse_dir(dir)).(@target = room.@id);
+			}
+			break;
+		default:
+			srv.o(target,"usage: set <direction> <target>");
+			break;
+		}
+		break;
+	deftault:
+		srv.o(target,"Set what?");
+		break;
+	}
+}
+
 RPG_Commands["FLEE"] = function (srv,target,zone,room,cmd,player) {
 	var chance=random(100);
 	if(chance<25) {
@@ -170,24 +364,30 @@ RPG_Commands["STATUS"] = function (srv,target,zone,room,cmd,player) {
 RPG_Commands["MOVE"] = function (srv,target,zone,room,cmd,player) {
 	var exit=room.exit.(@name == cmd[1].toLowerCase());
 	if(exit.@target.toString()=="") {
-		srv.o(target,"You cannot go that way.");
-		return false;
+		if(player.@editing == 1) {
+			create_new_room(srv,target,zone,room,player,cmd[1].toLowerCase());
+			return true;
+		} else {
+			srv.o(target,"You cannot go that way.");
+			return false;
+		}
 	}
 	
 	if(exit.door) {
 		var door=zone.door.(@id == exit.door);
-		if(door.open == false) {
+		if(door.open == false && player.@editing != 1) {
 			srv.o(target,"The " + door.@name + " is closed.");
 			return false;
 		}
 	}
+	
 	if(zones[exit.@zone]) player.@zone=<zone>{exit.@zone}</zone>;
 	player.@room=<room>{exit.@target}</room>;
 
 	zone=zones[player.@zone];
 	room=zone.room.(@id == player.@room);
 
-	srv.o(target,"You " + player.travel + " " + exit.@name + " to " + room.title + ". " + get_exit_string(zone,room));
+	srv.o(target,"You " + player.travel + " " + exit.@name + " to " + room.title + ". " + get_exit_string(zone,room,player));
 }
 
 RPG_Commands["UNLOCK"] = function (srv,target,zone,room,cmd,player) {
diff --git a/exec/ircbots/rpgbot/rpg_functions.js b/exec/ircbots/rpgbot/rpg_functions.js
index ec6b1ba832d0f9db9222f0e34d6fb0048e49d100..5189ed673b443dee9ddd92e1676aa795c2b54626 100644
--- a/exec/ircbots/rpgbot/rpg_functions.js
+++ b/exec/ircbots/rpgbot/rpg_functions.js
@@ -1,6 +1,7 @@
 function Server_command(srv,cmdline,onick,ouh) {
 	var cmd=IRC_parsecommand(cmdline);
 	var player=players.player.(@name == onick);
+	
 	switch (cmd[0]) {
 		case "PART":
 		case "QUIT":
@@ -116,36 +117,41 @@ function handle_command(srv,cmd,player,target) {
 /*	game activity functions */
 
 function display_room(srv,player,z,r) {
-	log("displaying zone: " + z + " room: " + r);
-
 	var zone=zones[z];
 	var room=zone.room.(@id == r);
 	
-	show_room_title(srv,player.@channel,zone,room);
-	show_room_description(srv,player.@channel,zone,room);
-	show_room_exits(srv,player.@channel,zone,room);
-	show_room_items(srv,player.@channel,zone,room);
-	show_room_mobs(srv,player.@channel,zone,room);
+	if(player.@editing == 1) {
+		srv.o(player.@channel,"Editing '" + zone.@name + "' [Z: " + z + " R: " + r + "]");
+	}
+	show_room_title(srv,player.@channel,zone,room,player);
+	show_room_description(srv,player.@channel,zone,room,player);
+	show_room_exits(srv,player.@channel,zone,room,player);
+	show_room_items(srv,player.@channel,zone,room,player);
+	show_room_mobs(srv,player.@channel,zone,room,player);
 	show_room_players(srv,player,zone,room);
 }
 
-function show_room_description(srv,target,zone,room) {
-	srv.o(target,strip_ctrl(room.description));
+function show_room_description(srv,target,zone,room,player) {
+	if(player.@editing == 1) srv.o(target,"[DESC] " + strip_ctrl(room.description));
+	else srv.o(target,strip_ctrl(room.description));
 }
 
-function show_room_title(srv,target,zone,room) {
-	srv.o(target,room.title);
+function show_room_title(srv,target,zone,room,player) {
+	if(player.@editing == 1) srv.o(target,"[TITLE] " + room.title);
+	else srv.o(target,room.title);
 }
 
-function show_room_items(srv,target,zone,room) {
+function show_room_items(srv,target,zone,room,player) {
 	for each(var i in room.item) {
-		srv.o(target,i.appearance);
+		if(player.@editing == 1) srv.o(target,"[ITEM: " + i.@id + "] " + i.appearance);
+		else srv.o(target,i.appearance);
 	}
 }
 
-function show_room_mobs(srv,target,zone,room) {
+function show_room_mobs(srv,target,zone,room,player) {
 	for each(var m in room.mob) {
-		srv.o(target,m.appearance);
+		if(player.@editing == 1) srv.o(target,"[MOB: " + m.@id + "] " + m.appearance);
+		else srv.o(target,m.appearance);
 	}
 }
 
@@ -159,20 +165,22 @@ function show_room_players(srv,player,zone,room) {
 	}
 }
 
-function show_room_exits(srv,target,zone,room) {
-	srv.o(target,get_exit_string(zone,room));
+function show_room_exits(srv,target,zone,room,player) {
+	srv.o(target,get_exit_string(zone,room,player));
 }
 
-function get_exit_string(zone,room) {
+function get_exit_string(zone,room,player) {
 	var exit_str="";
-	for(var e in room.exit) {
+	var exits=room.exit.(@target != "");
+	for(var e in exits) {
 		var prefix="";
-		if(room.exit[e].door) {
-			var door=zone.door.(@id == room.exit[e].door);
+		if(exits[e].door) {
+			var door=zone.door.(@id == exits[e].door);
 			if(door.locked==true) prefix="@";
 			else if(door.open==false) prefix="#";
 		}
-		exit_str+=", "+prefix+room.exit[e].@name;
+		exit_str+=", "+prefix+exits[e].@name.substr(0,1);
+		if(player.@editing == 1) exit_str+="[ID:"+exits[e].@target+"]";
 	}
 	return ("exits: " + exit_str.substr(2));
 }
@@ -372,7 +380,7 @@ function load_zone(dir) {
 
 		log("loading zone file: " + z_file.name);
 		if(!z_file.open("r+")) return false;
-		var zone=new XML(z_file.readAll().join()); 
+		var zone=new XML(z_file.read()); 
 		z_file.close();
 		
 		zone.directory=<directory>{dir}</directory>;
@@ -397,14 +405,14 @@ function load_zone(dir) {
 
 function load_items(file) {
 	if(!file.open("r+")) return false;
-	var items=new XML(file.readAll().join());
+	var items=new XML(file.read());
 	file.close();
 	return items;
 }
 
 function load_mobs(file) {
 	if(!file.open("r+")) return false;
-	var mobs=new XML(file.readAll().join());
+	var mobs=new XML(file.read());
 	file.close();
 	return mobs;
 }
@@ -416,9 +424,14 @@ function load_players() {
 		var p_file=new File(p_list[f]);
 		if(!p_file.open("r+")) return false;
 		log("loading player data: " + p_file.name);
-		var player=new XML(p_file.readAll().join());
+		var player=new XML(p_file.read());
 		p_file.close();
 		player.@active=0;
+		player.@editing=0;
+		if(!zones[player.@zone]) {
+			player.@zone=0;
+			player.@room=1;
+		}
 		players.appendChild(player);
 	}
 }
@@ -435,13 +448,199 @@ function load_zones() {
 function load_classes() {
 	if(!c_file.open("r+")) return false;
 	writeln("loading class data: " + c_file.name);
-	classes=new XML(c_file.readAll().join());
+	classes=new XML(c_file.read());
 	c_file.close();
 }
 
 function load_races() {
 	if(!r_file.open("r+")) return false;
 	writeln("loading race data: " + r_file.name);
-	races=new XML(r_file.readAll().join());
+	races=new XML(r_file.read());
 	r_file.close();
-}
\ No newline at end of file
+}
+
+/* game edit functions */
+function find_link(zone,room,start_coords,finish_coords,checked) {
+	
+
+	/* cumulative array for tracking scanned rooms (by room.@id) */
+	checked=checked || [];
+	if(checked[room.@id]) return -1;
+	checked[room.@id] = true;
+	
+	
+	if(!start_coords) start_coords=new Coords(0,0,0);
+	else {
+		/* if the passed starting coordinates match our query, return the current room id */
+		if(start_coords.x == finish_coords.x &&
+			start_coords.y == finish_coords.y &&
+			start_coords.z == finish_coords.z) {
+			return room.@id;
+		}
+	}
+	/* store all room exits in an array */
+	var dirs=[];
+	for(var e=0;e<room.exit.length();e++) {
+		if(room.exit[e].@target == "" || zones[room.exit[e].@zone]) continue;
+		
+		var dir=room.exit[e].@name;
+		var target_id=room.exit[e].@target;
+		var new_coords=get_exit_coords(start_coords,dir);
+		var target=zone.room.(@id == target_id);
+		
+		/* do recursive scan on all rooms */
+		var result=find_link(zone,target,new_coords,finish_coords,checked);
+		if(result >= 0) return result;
+	}
+	return -1;
+}
+
+function get_exit_coords(coords,dir) {
+	var new_coords=new Coords(coords.x,coords.y,coords.z);
+	switch(dir.toString()) {
+	case "north":
+		new_coords.y++;
+		break;
+	case "south":
+		new_coords.y--;
+		break;
+	case "east":
+		new_coords.x++;
+		break;
+	case "west":
+		new_coords.x--;
+		break;
+	case "up":
+		new_coords.z++;
+		break;
+	case "down":
+		new_coords.z--;
+		break;
+	default:
+		log("unknown dir: " + dir);
+		break;
+	}
+	return new_coords;
+}
+
+function create_player(name,player_race,player_class) {
+	var player=
+		<player name={name} active="0" zone="0" room="0">
+			<experience>0</experience>
+			<hitpoints>{base_hitpoints}</hitpoints>
+			<movement>{base_movement}</movement>
+			<mana>{base_mana}</mana>
+			<gold>0</gold>
+			<strength>{base_stats}</strength>
+			<dexterity>{base_stats}</dexterity>
+			<wisdom>{base_stats}</wisdom>
+			<intelligence>{base_stats}</intelligence>
+			<constitution>{base_stats}</constitution>
+			<level>1</level>
+			<travel>walk</travel>
+			<player_class>{player_class}</player_class>
+			<player_race>{player_race}</player_race>
+			<inventory>
+				{global_items.item.(@id == "1").copy()}
+				{global_items.item.(@id == "2").copy()}
+				{global_items.item.(@id == "3").copy()}
+				{global_items.item.(@id == "4").copy()}
+			</inventory>
+			<equipment>
+				<slot id="head" qty="1"/>
+				<slot id="neck" qty="1"/>
+				<slot id="about body" qty="1"/>
+				<slot id="body" qty="1"/>
+				<slot id="waist" qty="1"/>
+				<slot id="wrist" qty="2"/>
+				<slot id="hands" qty="1"/>
+				<slot id="finger" qty="2"/>
+				<slot id="wielded" qty="1"/>
+				<slot id="legs" qty="1"/>
+				<slot id="feet" qty="1"/>
+			</equipment>
+		</player>;
+	return player;
+}
+
+function create_new_room(srv,target,zone,room,player,dir) {
+	var new_id=get_new_room_id(zone);
+	var old_id=room.@id;
+	/* add this room to previous room's exit list */
+	room.exit +=<exit name={dir} target={new_id}/>;
+	
+	/* add new room data to zone */
+	zone.room += 
+		<room id={new_id}>
+			<title>{settings.title}</title>
+			<description>{settings.description}</description>
+		</room>;
+		
+	/* get direction we came from and add that exit to new room */
+	dir=reverse_dir(dir);
+	var new_room=zone.room.(@id == new_id);
+	new_room.exit += <exit name={dir} target={old_id}/>;
+	
+	if(settings.autolink) {
+		var dirs=get_dir_coords(dir);
+		for(var d in dirs) {
+			if(!dirs[d]) continue;
+			var result=find_link(zone,new_room,undefined,dirs[d],undefined);
+			if(result >= 0) {
+				/* add link to found exit */
+				new_room.exit += <exit name={d} target={result}/>;
+				/* add corresponding exit for target room */
+				var target_room=zone.room.(@id == result);
+				target_room.exit += <exit name={reverse_dir(d)} target = {new_id}/>;
+			}
+		}
+	} 
+	
+	/* move player to new room */
+	player.@room=new_id;
+	srv.o(target,"room " + new_id + " created");
+	display_room(srv,player,zone.@id,new_id);
+}
+
+function get_dir_coords(exclude) {
+	var dirs={
+		north:new Coords(0,1,0),
+		south:new Coords(0,-1,0),
+		east:new Coords(1,0,0),
+		west:new Coords(-1,0,0),
+		up:new Coords(0,0,1),
+		down:new Coords(0,0,-1),
+	}
+	delete dirs[exclude];
+	return dirs;
+}
+
+function reverse_dir(dir) {
+	if(dir=="north") dir="south";
+	else if(dir=="south") dir="north";
+	else if(dir=="east") dir="west";
+	else if(dir=="west") dir="east";
+	else if(dir=="up") dir="down";
+	else if(dir=="down") dir="up";
+	return dir;
+}
+
+function get_new_room_id(zone) {
+	var id = 0;
+	var r = zone.room.(@id == id);
+	while(r != undefined) {	
+		id++;
+		r=zone.room.(@id == id);
+	}
+	return id;
+}
+
+function get_new_zone_id() {
+	var id = 0;
+	var z = zones[id];
+	while(z != undefined) {	
+		id++;
+		z=zones[id];
+	}
+	return id;
+}
diff --git a/exec/ircbots/rpgbot/rpgbot.js b/exec/ircbots/rpgbot/rpgbot.js
index 961e157695c089c01874bfe22a7116b092f86082..d2086793d421840698cc7af6b9b136d85e35d098 100644
--- a/exec/ircbots/rpgbot/rpgbot.js
+++ b/exec/ircbots/rpgbot/rpgbot.js
@@ -2,7 +2,9 @@ var p_dir=this.dir+"players/";
 var z_dir=this.dir+"zones/";
 var c_file=new File(this.dir+"classes.xml");
 var r_file=new File(this.dir+"races.xml");
+var gi_file=new File(this.dir+"items.xml");
 
+var settings=new Settings();
 var players=[];
 var zones=[];
 var classes=[];
@@ -10,6 +12,7 @@ var races=[];
 var global_items=[];
 var player_attacks=[];
 var mob_attacks=[];
+var global_items=load_items(gi_file);
 
 var activity_timeout=300;	// seconds
 var tick_time=4;	// seconds
@@ -29,7 +32,7 @@ function save() {
 		var p_file=new File(p_dir + player.@name + ".xml");
 		if(!p_file.open("w+")) continue;
 		debug("saving RPG player: " + player.@name);
-		p_file.writeln(player.normalize());
+		p_file.write(player);
 		p_file.close();
 	}
 }
@@ -103,47 +106,19 @@ function update_game_status(srv) {
 	return active;
 }
 
-function create_player(name,player_race,player_class) {
-	var player=
-		<player name={name} active="0" zone="0" room="0">
-			<experience>0</experience>
-			<hitpoints>{base_hitpoints}</hitpoints>
-			<movement>{base_movement}</movement>
-			<mana>{base_mana}</mana>
-			<gold>0</gold>
-			<strength>{base_stats}</strength>
-			<dexterity>{base_stats}</dexterity>
-			<wisdom>{base_stats}</wisdom>
-			<intelligence>{base_stats}</intelligence>
-			<constitution>{base_stats}</constitution>
-			<level>1</level>
-			<travel>walk</travel>
-			<player_class>{player_class}</player_class>
-			<player_race>{player_race}</player_race>
-			<inventory>
-				{items.item.(@id == "1").copy()}
-				{items.item.(@id == "2").copy()}
-				{items.item.(@id == "3").copy()}
-				{items.item.(@id == "4").copy()}
-			</inventory>
-			<equipment>
-				<slot id="head" qty="1"/>
-				<slot id="neck" qty="1"/>
-				<slot id="about body" qty="1"/>
-				<slot id="body" qty="1"/>
-				<slot id="waist" qty="1"/>
-				<slot id="wrist" qty="2"/>
-				<slot id="hands" qty="1"/>
-				<slot id="finger" qty="2"/>
-				<slot id="wielded" qty="1"/>
-				<slot id="legs" qty="1"/>
-				<slot id="feet" qty="1"/>
-			</equipment>
-		</player>;
-	return player;
-}
-
 /*	game objects */
+function Coords(x,y,z)
+{
+	this.x=x;
+	this.y=y;
+	this.z=z;
+}
+function Settings()
+{
+	this.autolink=true;
+	this.title="New Room";
+	this.description="A new room.";
+}
 function Attack(attacker,defender)
 {
 	this.attacker=attacker;
@@ -158,8 +133,10 @@ function Move(item,result)
 /*	Init */
 load_classes();
 load_races();
-load_players();
 /* 	TODO: make zones load on demand, 
 	as loading them all at the start could become a problem 
 	when the world gets bigger */
 load_zones(); 
+load_players();
+
+