diff --git a/Nibriboard/CommandConsole.cs b/Nibriboard/CommandConsole.cs
index f615e6b..ca61324 100644
--- a/Nibriboard/CommandConsole.cs
+++ b/Nibriboard/CommandConsole.cs
@@ -61,10 +61,11 @@ namespace Nibriboard
 					await destination.WriteLineAsync("Nibriboard Server Command Console");
 					await destination.WriteLineAsync("=================================");
 					await destination.WriteLineAsync("Available commands:");
-					await destination.WriteLineAsync("    help         Show this message");
-					await destination.WriteLineAsync("    save         Save the ripplespace to disk");
-					await destination.WriteLineAsync("    plane list   List all the currently loaded planes");
+					await destination.WriteLineAsync("    help                        Show this message");
+					await destination.WriteLineAsync("    save                        Save the ripplespace to disk");
+					await destination.WriteLineAsync("    plane list                  List all the currently loaded planes");
 					await destination.WriteLineAsync("    plane create {new-plane-name} [{chunkSize}]   Create a new named plane, optionally with the specified chunk size.");
+					await destination.WriteLineAsync("    plane status {plane-name}   Show the statistics of the current plane.");
 					break;
 				case "save":
 					await destination.WriteAsync("Saving ripple space - ");
@@ -83,7 +84,7 @@ namespace Nibriboard
 						case "list":
 							await destination.WriteLineAsync("Planes:");
 							foreach(Plane plane in server.PlaneManager.Planes)
-								await destination.WriteLineAsync($"    {plane.Name} @ {plane.ChunkSize} ({plane.LoadedChunks} / ~{plane.SoftLoadedChunkLimit} chunks loaded, {plane.UnloadableChunks} inactive)");
+								await destination.WriteLineAsync($"    {plane.Name} @ {plane.ChunkSize} ({plane.LoadedChunks} / ~{plane.SoftLoadedChunkLimit} chunks loaded, {plane.UnloadableChunks} inactive, {plane.TotalChunks} total at last save)");
 							await destination.WriteLineAsync();
 							await destination.WriteLineAsync($"Total {server.PlaneManager.Planes.Count}");
 							break;
@@ -104,6 +105,29 @@ namespace Nibriboard
 
 							await destination.WriteLineAsync($"Created plane with name {newPlaneName} and chunk size {chunkSize}.");
 
+							break;
+						case "status":
+							if(commandParts.Length < 3) {
+								await destination.WriteLineAsync("Error: No plane name specified!");
+								return;
+							}
+
+							string targetPlaneName = commandParts[2].Trim();
+							Plane targetPlane = server.PlaneManager.GetByName(targetPlaneName);
+							if(targetPlane == null) {
+								await destination.WriteLineAsync($"Error: A plane with the name {targetPlaneName} doesn't exist.");
+								return;
+							}
+
+							await destination.WriteLineAsync($"Name: {targetPlane.Name}");
+							await destination.WriteLineAsync($"Chunk size: {targetPlane.ChunkSize}");
+							await destination.WriteLineAsync($"Loaded chunks: {targetPlane.LoadedChunks}");
+							await destination.WriteLineAsync($"Unloaded chunks: {targetPlane.TotalChunks - targetPlane.LoadedChunks}");
+							await destination.WriteLineAsync($"Total chunks: {targetPlane.TotalChunks}");
+							await destination.WriteLineAsync($"Primary chunk area size: {targetPlane.PrimaryChunkAreaSize}");
+							await destination.WriteLineAsync($"Min unloadeable chunks: {targetPlane.MinUnloadeableChunks}");
+							await destination.WriteLineAsync($"Soft loaded chunk limit: {targetPlane.SoftLoadedChunkLimit}");
+
 							break;
 						default:
 							await destination.WriteLineAsync($"Error: Unknown sub-action {subAction}.");
@@ -111,6 +135,33 @@ namespace Nibriboard
 					}
 					break;
 
+				/*case "chunk":
+					if(commandParts.Length < 2) {
+						await destination.WriteLineAsync("Error: No sub-action specified.");
+						break;
+					}
+
+					string chunkSubAction = commandParts[1].Trim();
+					switch(chunkSubAction)
+					{
+						case "list":
+							if(commandParts.Length < 3) {
+								await destination.WriteLineAsync("Error: No plane specified to list the chunks of!");
+								return;
+							}
+
+							Plane plane = server.PlaneManager.GetByName(commandParts[2].Trim());
+
+							foreach(Chunk chunk in plane.
+							break;
+
+						default:
+							await destination.WriteLineAsync($"Error: Unknown sub-action {chunkSubAction}.");
+							break;
+					}
+
+					break;*/
+
 				default:
 					await destination.WriteLineAsync($"Error: Unrecognised command {commandName}");
 					break;
diff --git a/Nibriboard/RippleSpace/ChunkReference.cs b/Nibriboard/RippleSpace/ChunkReference.cs
index 8044cd6..c1b2cac 100644
--- a/Nibriboard/RippleSpace/ChunkReference.cs
+++ b/Nibriboard/RippleSpace/ChunkReference.cs
@@ -20,7 +20,7 @@ namespace Nibriboard.RippleSpace
 			
 		}
 		/// <summary>
-		/// Creates a new blank <see cref="Nibriboard.RippleSpace.ChunkReference" />.
+		/// Creates a new blank <see cref="ChunkReference" />.
 		/// Don't use this yourself! This is only for Newtonsoft.Json to use when deserialising references.
 		/// </summary>
 		public ChunkReference() : base()
diff --git a/Nibriboard/RippleSpace/Plane.cs b/Nibriboard/RippleSpace/Plane.cs
index 8a93482..8d2e8b3 100644
--- a/Nibriboard/RippleSpace/Plane.cs
+++ b/Nibriboard/RippleSpace/Plane.cs
@@ -43,7 +43,7 @@ namespace Nibriboard.RippleSpace
 		/// loaded.
 		/// Works like a radius.
 		/// </summary>
-		public int PrimaryChunkAreaSize = 10;
+		public int PrimaryChunkAreaSize = 5;
 
 		/// <summary>
 		/// The minimum number of potentially unloadable chunks that we should have
@@ -95,6 +95,19 @@ namespace Nibriboard.RippleSpace
 				return result;
 			}
 		}
+		/// <summary>
+		/// Calculates the total number of chunks created that are on this plane - including those
+		/// that are currently unloaded.
+		/// </summary>
+		/// <description>
+		/// This is, understandably, a rather expensive operation - so use with caution!
+		/// Also, this count is only accurate to the last save.
+		/// </description>
+		public int TotalChunks {
+			get {
+				return Directory.GetFileSystemEntries(StorageDirectory, "*.chunk").Length;
+			}
+		}
 
 		/// <summary>
 		/// Initialises a new plane.
@@ -110,7 +123,7 @@ namespace Nibriboard.RippleSpace
 			// Set the soft loaded chunk limit to double the number of chunks in the
 			// primary chunks area
 			// Note that the primary chunk area is a radius around (0, 0) - not the diameter
-			SoftLoadedChunkLimit = PrimaryChunkAreaSize * PrimaryChunkAreaSize * 4;
+			SoftLoadedChunkLimit = PrimaryChunkAreaSize * PrimaryChunkAreaSize * 16;
 		}
 
 		private async Task LoadPrimaryChunks()
@@ -131,7 +144,7 @@ namespace Nibriboard.RippleSpace
 				}
 			}
 
-			await FetchChunks(primaryChunkRefs);
+			await FetchChunks(primaryChunkRefs, false);
 		}
 
 		/// <summary>
@@ -139,16 +152,24 @@ namespace Nibriboard.RippleSpace
 		/// </summary>
 		/// <param name="chunkRefs">The chunk references to fetch the attached chunks for.</param>
 		/// <returns>The chunks attached to the specified chunk references.</returns>
-		public async Task<List<Chunk>> FetchChunks(List<ChunkReference> chunkRefs)
+		public async Task<List<Chunk>> FetchChunks(IEnumerable<ChunkReference> chunkRefs, bool autoCreate)
 		{
-			// todo Paralellise loading with https://www.nuget.org/packages/AsyncEnumerator
+			// Todo Paralellise loading with https://www.nuget.org/packages/AsyncEnumerator
 			List<Chunk> chunks = new List<Chunk>();
-			foreach(ChunkReference chunkRef in chunkRefs)
-				chunks.Add(await FetchChunk(chunkRef));
+			foreach(ChunkReference chunkRef in chunkRefs) {
+				Chunk nextChunk = await FetchChunk(chunkRef, true);
+				if(nextChunk != null) // Might be null if we're not allowed to create new chunks
+					chunks.Add(nextChunk);
+			}
 			return chunks;
 		}
+		public async Task<List<Chunk>> FetchChunks(IEnumerable<ChunkReference> chunkRefs)
+		{
+			return await FetchChunks(chunkRefs, true);
+		}
 
-		public async Task<Chunk> FetchChunk(ChunkReference chunkLocation)
+
+		public async Task<Chunk> FetchChunk(ChunkReference chunkLocation, bool autoCreate)
 		{
 			// If the chunk is in the loaded chunk-space, then return it immediately
 			if(loadedChunkspace.ContainsKey(chunkLocation))
@@ -162,13 +183,22 @@ namespace Nibriboard.RippleSpace
 			Chunk loadedChunk;
 			if(File.Exists(chunkFilePath)) // If the chunk exists on disk, load it
 				loadedChunk = await Chunk.FromFile(this, chunkFilePath);
-			else // Ooooh! It's a _new_, never-before-seen one! Create a brand new chunk :D
+			else
+			{
+				// Ooooh! It's a _new_, never-before-seen one! Create a brand new chunk :D
+				// ....but only if we've been told it's ok to create new chunks.
+				if(!autoCreate) return null;
 				loadedChunk = new Chunk(this, ChunkSize, chunkLocation);
+			}
 			loadedChunk.OnChunkUpdate += HandleChunkUpdate;
 			loadedChunkspace.Add(chunkLocation, loadedChunk);
 
 			return loadedChunk;
 		}
+		public async Task<Chunk> FetchChunk(ChunkReference chunkLocation)
+		{
+			return await FetchChunk(chunkLocation, true);
+		}
 
 		/// <summary>
 		/// Works out whether a chunk currently exists.
diff --git a/Nibriboard/RippleSpace/RippleSpaceManager.cs b/Nibriboard/RippleSpace/RippleSpaceManager.cs
index 648ce54..d327437 100644
--- a/Nibriboard/RippleSpace/RippleSpaceManager.cs
+++ b/Nibriboard/RippleSpace/RippleSpaceManager.cs
@@ -116,6 +116,15 @@ namespace Nibriboard.RippleSpace
 			return newPlane;
 		}
 
+		public Plane GetByName(string targetPlaneName)
+		{
+			foreach(Plane plane in Planes) {
+				if(plane.Name == targetPlaneName)
+					return plane;
+			}
+			return null;
+		}
+
 		public async Task StartMaintenanceMonkey()
 		{
 			Log.WriteLine("[RippleSpace/Maintenance] Automated maintenance monkey created.");
