diff --git a/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java b/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java
index b5240df..ae9ea89 100644
--- a/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java	
+++ b/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java	
@@ -150,6 +150,8 @@ public class GameEngine {
     public synchronized boolean build (Map map, String buildingArg) {
         BuildingFactory bfactory = new BuildingFactory();
         Building type = bfactory.getBuilding(buildingArg);
+        if (type == null)
+            return false;
         return map.build(new Tile(), type);
     }
 
diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java
index 558018e..5b63458 100644
--- a/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java	
+++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java	
@@ -9,35 +9,50 @@ import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.Map;
 
 public class Client implements Runnable {
     private GameDisplay view = new GameDisplay();
 
     private DatagramSocket clientSocket;
-    private boolean running = true;
+    private volatile boolean running = true;
     private Thread receiveThread;
-    private final HashMap<Long, Message.Sent> sentMessages = new HashMap<>();
+    private final Map<Long, Message.Sent> sentMessages = Collections.synchronizedMap(new HashMap<>());
     private int lastMessageID = 0;
     private final InetAddress serverAddress;
 
+    private long ourClientID = 0;
+
     public Client(String address) throws IOException {
         serverAddress = InetAddress.getByName(address);
         clientSocket = new DatagramSocket();
         receiveThread = new Thread(this);
         receiveThread.start();
 
-        sendMessage(new Message.Sent(PacketTable.CONNECT, 0, ++lastMessageID));
+        sendMessage(new Message.Sent(PacketTable.CONNECT, ourClientID, ++lastMessageID));
 
         while (running) {
             String prompt;
             if ((prompt = view.nextInput()) != null) {
                 if (prompt.trim().isEmpty())
                     continue;
-                if (prompt.charAt(0) == '6')
+                if (prompt.charAt(0) == '6') {
+                    running = false;
                     break;
+                }
+                view.printGameMenu();
+                String[] args = prompt.split(" ");
+                char c = prompt.charAt(0);
+                if (c > '0' && c < '4') {
+                    if (args.length < 2) {
+                        System.err.println("Args must include type!");
+                        continue;
+                    }
+                }
                 byte messageType;
-                switch (prompt.charAt(0)) {
+                switch (c) {
                     case '1':
                         messageType = PacketTable.BUILD;
                         break;
@@ -47,15 +62,16 @@ public class Client implements Runnable {
                     case '3':
                         messageType = PacketTable.UPGRADE;
                         break;
+                    case '5':
+                        messageType = PacketTable.PRINT_MAP_DATA;
+                        break;
                     default:
                         System.err.println("> Invalid command input!");
                         return;
                 }
-                Message.Sent buildMessage = new Message.Sent(messageType,0,++lastMessageID);
-                buildMessage.getData().write(prompt.substring(1).getBytes());
+                Message.Sent buildMessage = new Message.Sent(messageType,ourClientID,++lastMessageID);
+                buildMessage.getWriter().writeUTF(prompt.substring(1));
                 sendMessage(buildMessage);
-
-                view.printGameMenu();
             }
             ArrayList<Long> removes = new ArrayList<>();
             for (HashMap.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
@@ -89,6 +105,8 @@ public class Client implements Runnable {
 
                 switch (packetID) {
                     case PacketTable.ACK:
+                        if (ourClientID == 0)
+                            ourClientID = clientID;
                         Message.Sent message = sentMessages.get(messageID);
                         if (message == null)
                             throw new RuntimeException("Server acknowledged a message we never sent! (" + messageID + ")");
@@ -99,11 +117,16 @@ public class Client implements Runnable {
                         for (HashMap.Entry<Long, Message.Sent> ms : sentMessages.entrySet())
                             System.out.println("MessageID: " + ms.getKey());
                         break;
+                    case PacketTable.MESSAGE:
+                        System.out.println(stream.readUTF());
+                        break;
                     case PacketTable.DISCONNECT:
                         running = false;
                         break;
                 }
-
+                if (packetID != PacketTable.ACK && packetID != PacketTable.DISCONNECT){
+                    sendMessage(new Message.Sent(PacketTable.ACK, ourClientID, messageID));
+                }
             } catch (Exception e){
                 e.printStackTrace();
             }
diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java
index eab7859..ca3d279 100644
--- a/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java	
+++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java	
@@ -23,6 +23,6 @@ public class PacketTable {
     // messageHeader, upgrade
     public static final byte UPGRADE = 0x7;
     // messageHeader, serial packets with map info
-    public static final byte USER_MAP_DATA = 0x8;
+    public static final byte PRINT_MAP_DATA = 0x8;
 
 }
diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java
index 52cb271..ed18178 100644
--- a/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java	
+++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java	
@@ -9,10 +9,7 @@ import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
 import java.rmi.ServerException;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.PriorityQueue;
-import java.util.Queue;
+import java.util.*;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -55,7 +52,7 @@ public class Server implements Runnable {
                 long clientID = stream.readLong();
                 long messageID = stream.readLong();
 
-                System.out.println("Receiving message with ID " + messageID + " to client: " + clientID + " of type " + packetID);
+                System.out.println("Receiving message with ID " + messageID + " from client: " + clientID + " of type " + packetID);
 
                 ConnectedClient client = clients.get(clientID);
 
@@ -67,7 +64,7 @@ public class Server implements Runnable {
                     continue;
                 }
                 if (client == null)
-                    throw new ServerException("Client disconnected with invalid client id! (" + clientID + ")");
+                    throw new ServerException("Client sent message invalid client id! (" + clientID + ")");
                 if (packetID == PacketTable.DISCONNECT) {
                     client.halt();
                     clients.remove(clientID);
@@ -95,7 +92,7 @@ public class Server implements Runnable {
         private final Queue<Message.Received> pendingRequests = new PriorityQueue<>();
         private final ReentrantLock requestLock = new ReentrantLock();
         private final AtomicBoolean allowUpdate;
-        private final HashMap<Long, Message.Sent> sentMessages = new HashMap<>();
+        private final java.util.Map<Long, Message.Sent> sentMessages = Collections.synchronizedMap(new HashMap<>());
         private final DatagramSocket serverSocket;
         private final long clientID;
         private volatile boolean running = true;
@@ -148,16 +145,20 @@ public class Server implements Runnable {
                         System.out.println(request.getReader().readUTF());
                         break;
                     case PacketTable.BUILD:
-                        usingEngine.build(clientMap,new String(request.getData(), StandardCharsets.UTF_8));
+                        if (usingEngine.build(clientMap, request.getReader().readUTF())){
+                            System.out.println("Client " + clientID + " has built something!");
+                        } else {
+                            System.out.println("Client " + clientID + " failed to build!");
+                        }
                         break;
                     case PacketTable.TRAIN:
-                        usingEngine.train(clientMap,new String(request.getData(), StandardCharsets.UTF_8));
+                        usingEngine.train(clientMap, request.getReader().readUTF());
                         break;
                     case PacketTable.UPGRADE:
-                        usingEngine.upgradeBuilding(clientMap, ByteBuffer.wrap(request.getData()).getInt());
+                        usingEngine.upgradeBuilding(clientMap, Integer.parseInt(request.getReader().readUTF()));
                         break;
-
                 }
+                sendMessage(new Message.Sent(PacketTable.ACK, clientID, request.getMessageID()));
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }