diff --git a/Nibriboard/ClientFiles/ClientManager.js b/Nibriboard/ClientFiles/ClientManager.js
index dfaad57..e57955c 100644
--- a/Nibriboard/ClientFiles/ClientManager.js
+++ b/Nibriboard/ClientFiles/ClientManager.js
@@ -10,6 +10,9 @@ class ClientManager extends EventEmitter
 	{
 		super();
 		
+		this.otherClientCursorSize = 25;
+		this.otherClientCursorWidth = 2;
+		
 		this.otherClients = new Map();
 		
 		// Handle other clients' state updates
@@ -26,25 +29,10 @@ class ClientManager extends EventEmitter
 	{
 		context.save();
 		
-		for (let [otherClientId, otherClient] of this.otherClients)
+		for(let [otherClientId, otherClient] of this.otherClients)
 		{
 			// TODO: Filter rendering by working out if this client is actually inside our viewport or not here
-			context.save();
-			context.translate(otherClient.CursorPosition.x, otherClient.CursorPosition.y);
-			
-			context.beginPath();
-			// Horizontal line
-			context.moveTo(-this.otherCursorRadius, 0);
-			context.lineTo(this.otherCursorRadius, 0);
-			// Vertical line
-			context.moveTo(0, -this.otherCursorRadius);
-			context.lineTo(0, this.otherCursorRadius);
-			
-			context.strokeStyle = otherClient.Colour;
-			context.lineWidth = this.otherCursorWidth
-			context.stroke();
-			
-			context.restore();
+			otherClient.render(canvas, context, this);
 		}
 		
 		context.restore();
@@ -94,8 +82,11 @@ class ClientManager extends EventEmitter
 		let fromClient = this.get(message.OtherClientId);
 		
 		fromClient.addLine({
+			/** @type {string} */
 			LineId: message.LineId,
+			/** @type {string} */
 			Colour: message.LineColour,
+			/** @type {number} */
 			Width: message.LineWidth
 		});
 	}
@@ -106,7 +97,9 @@ class ClientManager extends EventEmitter
 	 */
 	handleOtherLinePart(message) {
 		let fromClient = this.get(message.OtherClientId);
-		fromClient.appendLine(message.LineId, message.Points);
+		let vectorPoints = message.Points.map((point) => new Vector(point.X, point.Y));
+		
+		fromClient.appendLine(message.LineId, vectorPoints);
 	}
 	
 	/**
diff --git a/Nibriboard/ClientFiles/OtherClient.js b/Nibriboard/ClientFiles/OtherClient.js
index d5717fb..82395a3 100644
--- a/Nibriboard/ClientFiles/OtherClient.js
+++ b/Nibriboard/ClientFiles/OtherClient.js
@@ -38,6 +38,55 @@ class OtherClient
 		this.Viewport.height = data.Viewport.Height;
 	}
 	
+	/**
+	 * Renders this client and all it's lines in progress to the screen.
+	 * @param  {HTMLCanvasElement} canvas  The canvas to render to.
+	 * @param  {CanvasRenderingContext2D} context The context to use to draw to the canvas.
+	 * @param  {ClientManager} manager The manager to draw rendering settings from.
+	 */
+	render(canvas, context, manager)
+	{
+		// Render ourselves
+		context.save();
+		
+		context.translate(this.CursorPosition.x, this.CursorPosition.y);
+		context.beginPath();
+		context.moveTo(-manager.otherClientCursorSize, 0);
+		context.lineTo(manager.otherClientCursorSize, 0);
+		context.moveTo(0, -manager.otherClientCursorSize);
+		context.lineTo(0, manager.otherClientCursorSize);
+		
+		context.strokeStyle = this.Colour;
+		context.lineWidth = manager.otherCursorWidth;
+		context.stroke();
+		
+		context.restore();
+		
+		// Render the lines we're currently drawing
+		for (let lineId in this.currentLines)
+		{
+			let lineData = this.currentLines[lineId];
+			let linePoints = lineData.Points;
+			
+			// Don't draw empty lines
+			if(linePoints.length == 0)
+				continue;
+			
+			context.save();
+			
+			context.beginPath();
+			context.moveTo(linePoints[0].x, linePoints[0].y);
+			for(let point of linePoints)
+				context.lineTo(point.x, point.y);
+			
+			context.strokeStyle = lineData.Colour;
+			context.lineWidth = lineData.Width;
+			context.stroke();
+			
+			context.restore();
+		}
+	}
+	
 	/**
 	 * Fetches a line that is currently being drawn by this client with the specified id
 	 * @param  {[type]} lineId [description]
@@ -50,6 +99,37 @@ class OtherClient
 		
 		return this.currentLines[lineId];
 	}
+	
+	addLine(lineData) {
+		if(typeof this.currentLines[lineData.LineId] != "undefined")
+			throw new Error(`Error: The line with the id ${lineData.LineId} already exists.`);
+		
+		this.currentLines[lineData.LineId] = lineData;
+	}
+	
+	/**
+	 * Adds a list of vectors to the line with the specified id.
+	 * @param  {string} lineId The id of the line in progress to add to.
+	 * @param  {Vector} points The list of points to add.
+	 */
+	appendLine(lineId, points)
+	{
+		if(typeof this.currentLines[lineId] == "undefined")
+			throw new Error(`The line with the id ${lineId} does not exist, so it can't be appended to.`);
+		
+		this.currentLines[lineId].Points.push(...points);
+	}
+	
+	/**
+	 * Finishes the line in progress with the specified id.
+	 * @param  {string} lineId The line id to finish.
+	 */
+	finishLine(lineId) {
+		if(typeof this.currentLines[lineId] == "undefined")
+			throw new Error(`The line with the id ${lineId} does not exist, so it can't be finalised.`);
+		
+		delete this.currentLines[lineId];
+	}
 }
 
 /**
