diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..44052d7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.aider*
diff --git a/events.js b/events.js
index f2baf13..943f5a7 100644
--- a/events.js
+++ b/events.js
@@ -38,17 +38,22 @@ function setupPanZoom() {
   
   canvas.addEventListener('wheel', (e) => {
     e.preventDefault();
-    let zoomSpeed = 0.001;
+    // Adjust zoom speed based on current scale for smoother zooming
+    let zoomSpeed = 0.001 * (scale < 1 ? 0.5 : 1);
     let delta = e.deltaY * zoomSpeed;
     let oldScale = scale;
     scale -= delta;
+    
+    // Limit scale range
     if(scale < 0.1) scale = 0.1;
     if(scale > 5) scale = 5;
 
-    let mouseX = e.clientX - (canvas.width/2 + offsetX);
-    let mouseY = e.clientY - (canvas.height/2 + offsetY);
-    offsetX -= mouseX * (scale - oldScale);
-    offsetY -= mouseY * (scale - oldScale);
+    // Zoom toward mouse position
+    const rect = canvas.getBoundingClientRect();
+    let mouseX = e.clientX - rect.left - (canvas.width/2 + offsetX);
+    let mouseY = e.clientY - rect.top - (canvas.height/2 + offsetY);
+    offsetX -= mouseX * (scale / oldScale - 1);
+    offsetY -= mouseY * (scale / oldScale - 1);
   }, {passive: false});
 }
 
diff --git a/render.js b/render.js
index 2fae340..292ec4a 100644
--- a/render.js
+++ b/render.js
@@ -82,11 +82,28 @@ function drawTerrain() {
   const endX = Math.ceil(startX + visibleWidth);
   const endY = Math.ceil(startY + visibleHeight);
   
-  // Draw terrain cells
-  const cellSize = 10; // Size of each terrain cell
+  // Draw terrain cells - use a larger cell size when zoomed out for performance
+  const baseSize = 10; // Base size of each terrain cell
+  const adaptiveSize = Math.max(baseSize, Math.floor(baseSize / scale) * baseSize);
   
-  for (let x = startX; x <= endX; x += cellSize) {
-    for (let y = startY; y <= endY; y += cellSize) {
+  // Align to grid to prevent shaking
+  const alignedStartX = Math.floor(startX / adaptiveSize) * adaptiveSize;
+  const alignedStartY = Math.floor(startY / adaptiveSize) * adaptiveSize;
+  
+  // Limit the number of cells drawn for performance
+  const maxCells = 10000;
+  const cellsWidth = Math.ceil((endX - alignedStartX) / adaptiveSize);
+  const cellsHeight = Math.ceil((endY - alignedStartY) / adaptiveSize);
+  
+  // If too many cells would be drawn, increase cell size
+  let cellSize = adaptiveSize;
+  if (cellsWidth * cellsHeight > maxCells) {
+    const scaleFactor = Math.sqrt((cellsWidth * cellsHeight) / maxCells);
+    cellSize = Math.ceil(adaptiveSize * scaleFactor);
+  }
+  
+  for (let x = alignedStartX; x <= endX; x += cellSize) {
+    for (let y = alignedStartY; y <= endY; y += cellSize) {
       // Get terrain type at this position
       const terrainType = getTerrainType(x, y);
       
@@ -125,19 +142,34 @@ function drawGrid() {
 
   ctx.strokeStyle = "#ccc";
   ctx.lineWidth = 1/scale;
-  let range = 2000;
-  for(let x = -range; x <= range; x += 100) {
+  
+  // Calculate visible area
+  const visibleWidth = canvas.width / scale;
+  const visibleHeight = canvas.height / scale;
+  const startX = Math.floor((-offsetX / scale) - (visibleWidth / 2));
+  const startY = Math.floor((-offsetY / scale) - (visibleHeight / 2));
+  const endX = Math.ceil(startX + visibleWidth);
+  const endY = Math.ceil(startY + visibleHeight);
+  
+  // Align grid to prevent shaking
+  const gridSize = 100;
+  const alignedStartX = Math.floor(startX / gridSize) * gridSize;
+  const alignedStartY = Math.floor(startY / gridSize) * gridSize;
+  
+  // Only draw visible grid lines
+  for(let x = alignedStartX; x <= endX; x += gridSize) {
     ctx.beginPath();
-    ctx.moveTo(x, -range);
-    ctx.lineTo(x, range);
+    ctx.moveTo(x, startY);
+    ctx.lineTo(x, endY);
     ctx.stroke();
   }
-  for(let y = -range; y <= range; y += 100) {
+  for(let y = alignedStartY; y <= endY; y += gridSize) {
     ctx.beginPath();
-    ctx.moveTo(-range, y);
-    ctx.lineTo(range, y);
+    ctx.moveTo(startX, y);
+    ctx.lineTo(endX, y);
     ctx.stroke();
   }
+  
   ctx.restore();
 }
 
diff --git a/terrain.js b/terrain.js
index 26de505..3ddee13 100644
--- a/terrain.js
+++ b/terrain.js
@@ -182,6 +182,7 @@ function isWater(x, y) {
 // Get terrain type at a position
 function getTerrainType(x, y) {
   // Convert world coordinates to terrain grid coordinates
+  // Use consistent rounding to prevent shaking
   const gridX = Math.floor((x + 2000) / 10);
   const gridY = Math.floor((y + 2000) / 10);