 		}
 		
 		protected function cacheValid():Boolean {
-			if (!cached)
-				return false;
-			if (U.zoom != cachedZoom)
-				return false;
-			return true;
+			return cachedLines && U.zoom == cachedZoom && link.source.Loc.equals(cachedStart) && link.destination.Loc.equals(cachedEnd);
 		}
 		protected function canBuildCache():Boolean {
-			return link.deployed && cachesThisFrame < MAX_CACHES_PER_FRAME && false; //TODO
+			return link.deployed && cachesThisFrame < MAX_CACHES_PER_FRAME; //TODO
 		}
 		
 		protected function buildCache():void {
-			//TODO
-			//same as wire, but per jags, not per pre-path
-			
-			cached = true;
+			cachedLines = new Vector.<FlxSprite>;
+			_bounds = null;
+			
+			var source:Point = link.source.Loc;
+			var dest:Point = link.destination.Loc;
+			var midpoint:Point = new Point(Math.floor((source.x + dest.x) / 2),
+										   Math.floor((source.y + dest.y) / 2));
+			var primaryHorizontal:Boolean = Math.abs(source.x - dest.x) >= Math.abs(source.y - dest.y);
+			
+			var width:int = getWidth();
+			
+			//TODO: split up very long wires
+			if (primaryHorizontal) {
+				cachedLines.push(new FlxSprite(
+					Math.min(source.x, midpoint.x) * U.GRID_DIM - width/2,
+					source.y * U.GRID_DIM - width / 2
+				).makeGraphic(Math.abs(source.x - midpoint.x) * U.GRID_DIM + width, width, 0xffffffff, true));
+				
+				cachedLines.push(new FlxSprite(
+					midpoint.x * U.GRID_DIM - width/2,
+					Math.min(source.y, dest.y) * U.GRID_DIM - width/2
+				).makeGraphic(width, Math.abs(source.y - dest.y) * U.GRID_DIM + width, 0xffffffff, true));
+				
+				cachedLines.push(new FlxSprite(
+					Math.min(midpoint.x, dest.x) * U.GRID_DIM - width/2,
+					dest.y * U.GRID_DIM - width/2
+				).makeGraphic(Math.abs(midpoint.x - dest.x) * U.GRID_DIM + width, width, 0xffffffff, true));
+			} else {
+				cachedLines.push(new FlxSprite(
+					source.x * U.GRID_DIM - width/2,
+					Math.min(source.y, midpoint.y) * U.GRID_DIM - width/2
+				).makeGraphic(width, Math.abs(source.y - midpoint.y) * U.GRID_DIM + width, 0xffffffff, true));
+				
+				cachedLines.push(new FlxSprite(
+					Math.min(source.x, dest.x) * U.GRID_DIM - width/2,
+					midpoint.y * U.GRID_DIM - width/2
+				).makeGraphic(Math.abs(source.x - dest.x) * U.GRID_DIM + width, width, 0xffffffff, true));
+				
+				cachedLines.push(new FlxSprite(
+					dest.x * U.GRID_DIM - width/2,
+					Math.min(midpoint.y, dest.y) * U.GRID_DIM - width/2
+				).makeGraphic(width, Math.abs(midpoint.y - dest.y) * U.GRID_DIM + width, 0xffffffff, true));
+			}
+			
+			
 			cachedZoom = U.zoom;
+			cachedStart = link.source.Loc.clone();
+			cachedEnd = link.destination.Loc.clone();
+		}
+		
+		protected function drawCached():void {
+			var color:uint = getColor();
+			for each (var line:FlxSprite in cachedLines) {
+				if (line.color != color)
+					line.color = color;
+				line.draw();
+			}
 		}
 		
 		protected function drawDynamic(drawFromOrigin:Boolean = false):void {

			end.x *= U.GRID_DIM;
			end.y *= U.GRID_DIM;
			
			if (!hSeg || U.zoom != segZoom)
				setSegs();
			
			var color:uint = getColor();
			if (hSeg.color != color)

		}
		
		protected function setSegs():void {
			if (hSeg && U.zoom == segZoom)
				return;
			
			if (!hSegs[zoomIndex])
				buildSegsForZoom();
			
