diff --git a/xtrn/dicewarz2/ai.js b/xtrn/dicewarz2/ai.js
index a43be2b0dae424cc9bf02ab4b56a123d0da02a51..d78b02c7f8e6a366ebc80aacf1be66a935eeec72 100644
--- a/xtrn/dicewarz2/ai.js
+++ b/xtrn/dicewarz2/ai.js
@@ -213,8 +213,12 @@ function main()
 			updateStatus(map);
 			nextTurn(map);
 		}
-		game_data.saveData(map);
+		game_data.save(map);
+		mswait(1000);
 	}
+	stream.sendfile(getFileName(map.game_number));
+	mswait(5000);
+	stream.close();
 }
 function attack()
 {
diff --git a/xtrn/dicewarz2/dice2.js b/xtrn/dicewarz2/dice2.js
index bf8d383c9366528c56ad92430f96f219b12db5ef..0ab2f633dccba1ef56946a26809327a8302a73d5 100644
--- a/xtrn/dicewarz2/dice2.js
+++ b/xtrn/dicewarz2/dice2.js
@@ -26,6 +26,8 @@ function splashStart()
 		console.center("\1n\1c[\1hPress any key to continue\1n\1c]");
 		while(console.inkey(K_NOECHO|K_NOSPIN)=="");
 	}
+	stream.recvfile("players.ini");
+	stream.recvfile("*.dw");
 }
 function splashExit()
 {
@@ -111,7 +113,7 @@ function viewInstructions(section)
 }
 function cycle()
 {
-	chat.receive();
+	chat.cycle();
 }
 
 //LOBBY LOOP
@@ -207,7 +209,7 @@ function lobby()
 	}
 	function initChat()
 	{
-		chat.init("dice warz",78,5,2,19);
+		chat.init("dice warz lobby",78,5,2,19);
 		chat.input_line.init(10,18,70,"\0017","\1k");
 	}
 	function initMenu()
@@ -333,7 +335,7 @@ function run(map)
 					listPlayers();
 					break;
 				case "E":
-					endturn();
+					endTurn();
 					break;
 				case "F":
 					forfeit();
@@ -417,6 +419,7 @@ function run(map)
 					break;
 				case "turn":
 					map.turn=data.turn;
+					debug("received turn notice: " + map.players[map.turn].name);
 					turnAlert();
 					listPlayers();
 					setMenuCommands();
@@ -443,7 +446,15 @@ function run(map)
 	}
 
 	//GAMEPLAY
-	function endturn()
+	function forfeit()
+	{
+		map.players[map.turn].active=false;
+		var data=new Packet("activity");
+		data.activity=("\1n\1y" + map.players[map.turn].name + " forfeits");
+		stream.send(data);
+		players.scoreLoss(map.players[map.turn].name);
+	}
+	function endTurn()
 	{
 		reinforce();
 		nextTurn(map);
@@ -457,6 +468,7 @@ function run(map)
 			return;
 		}
 		if(map.players[map.turn].AI) {
+			game_data.save(map);
 			load(true,game_dir + "ai.js",map.game_number,game_dir);
 		}
 	}
diff --git a/xtrn/dicewarz2/maps.js b/xtrn/dicewarz2/maps.js
index 77ee1c5c0634c686b69c821146956c1c69a3c43b..dcfeae2b4bf3ce536d53d4ec3229059cdb1d4403 100644
--- a/xtrn/dicewarz2/maps.js
+++ b/xtrn/dicewarz2/maps.js
@@ -6,7 +6,7 @@ load(game_dir+"rolldice.js");
 var settings=	loadSettings(game_dir+"dice.ini");
 var players=	new PlayerData(game_dir+settings.player_file);
 var game_data=	new GameData(game_dir+"*.dw");
-var stream=	new ServiceConnection("Dice Warz ][","dicewars");
+var stream=	new ServiceConnection("dicewarz2","dicewars");
 
 function Char(ch,fg,bg)
 {
@@ -134,24 +134,25 @@ function GameData(filemask)
 		this.list[map.game_number]=map;
 		if(map.game_number>this.last_game_number) this.last_game_number=map.game_number;
 		
-		menuText("Storing game data");
+		//menuText("Storing game data");
 		this.saveData(map);
 		
-		menuText("Storing player data");
+		//menuText("Storing player data");
 		for(var p=0;p<map.players.length;p++)
 		{
-			menuText(".",true);
+			//menuText(".",true);
 			var player=map.players[p];
 			this.savePlayer(map,player,p);
 		}
 		
-		menuText("Storing map data");
+		//menuText("Storing map data");
 		for(var t=0;t<map.tiles.length;t++)
 		{
-			menuText(".",true);
+			//menuText(".",true);
 			var tile=map.tiles[t];
 			this.saveTile(map,tile);
 		}
+		stream.sendfile(file_getname(getFileName(map.game_number)));
 	}
 	this.closeGameFile=function(file,map)
 	{
@@ -595,7 +596,7 @@ function Packet(type)
 				var grid=getBorders(map,array[t]);
 				var connections=trace(map,grid,count,match);
 				counted.concat(connections);
-				var group_size=countSparseArray(connections);
+				var group_size=countMembers(connections);
 				if(group_size>largest_group) largest_group=group_size;
 			}
 		}
@@ -738,7 +739,6 @@ function Packet(type)
 	//MAP DATA FUNCTIONS
 	function updateStatus(map)
 	{
-		debug("updating game status");
 		for(var p=0;p<map.players.length;p++) {
 			if(map.players[p].active) {
 				if(countTiles(map,p)==0) {
diff --git a/xtrn/dicewarz2/rolldice.js b/xtrn/dicewarz2/rolldice.js
index b02ce63418c034d8ce9997a07632dd81c00c214d..0f52ebc1c1f3e2a3fd1e214a4e6beeca540f8a86 100644
--- a/xtrn/dicewarz2/rolldice.js
+++ b/xtrn/dicewarz2/rolldice.js
@@ -45,7 +45,7 @@ function showRoll(rolls,attr,x,y)
 	return total;
 }
 function loadDice()
-{								//INITIALIZE SIX SIDED DICE OBJECTS
+{							
 	var dice=[];
 	for(d=1;d<=6;d++)
 	{
@@ -66,7 +66,7 @@ function Roll(pnum)
 	}
 }
 function Die(number)
-{								//DICE CLASS
+{								
 	this.number=number;
 	this.line1="   ";
 	this.line2="   ";