# Organic Island Design for Pirate Maps

Quick reference for drawing islands that look like real landmasses, not circles with noise.

## Principle
Every island tells a story through its shape. The coastline should reflect what's *on* the island.

| Island | Shape Language | Interior Details |
|---|---|---|
| Port / Capital | Natural harbor (bay indentation), hills behind | Harbor bay, hill triangles, inner shelf |
| Archipelago cluster | Multiple small irregular blobs clustered | Each blob slightly different size |
| Mountainous / Spire | Craggy, jagged peaks, sharp cliffs | 2-3 triangular peaks, glowing spire tip |
| Maze / Swamp | Tangled, many inlets/bays, no clean coast | Seaweed texture lines, multiple coves |
| Dark / Corrupted | Smooth but wrong, faint distortion lines | Inner dark shelf, wrongness lines |
| Shattered reef | Main island + scattered fragments around it | Fragments as small irregular polygons |
| Atoll / Banks | Scattered ellipses, one large, several small | No interior — flat coral sand |
| Storm-battered | Elongated, broken cliff on windward side | Broken cliff polygon |
| Temple | Small roundish with vertical structures | Standing stones, pillars, fire pit |
| Gallows / Grim | Small, minimal, one dark structure | Post + crossbar |
| Forest | Dark ground, vertical tree lines | White-barked trees, shimmer leaves |
| Flotilla (rotting ships) | Overlapping ship-like shapes | Multiple hull curves |
| Cave / Underground | One dark ellipse (mouth) | Nothing else — mystery |
| Underwater | Dark fill with upward spires | Coral lines, bubbles |
| Flying / Cloud | Light fill, cloud layers below | Castle silhouette on top |
| Mobile (turtle) | Shell pattern with movement arrows | Grid-like shell segments |
| Monster lair | Dark with radiating tentacle lines | Glowing eyes |
| False light | Small, glowing center | Lighthouse tower |

## SVG Path Recipe

```svg
<!-- Harbor bay: indent the coastline -->
<path d="M 2650,920 
         C 2700,900 2780,910 2830,950 
         C 2870,980 2890,1030 2870,1080 
         C 2850,1130 2800,1160 2740,1170 
         C 2680,1180 2610,1160 2570,1110 
         C 2530,1060 2530,1000 2570,960 
         C 2590,940 2620,930 2650,920 Z" />
<!-- Bay is created by the inward curve at 2570,1110 → 2530,1060 -->

<!-- Mountain peaks: stacked triangles -->
<polygon points="920,670 980,780 860,780" fill="#6a5a3a" opacity="0.5"/>
<polygon points="980,690 1030,790 930,790" fill="#5a4a2a" opacity="0.45"/>

<!-- Standing stones: small rects in a ring -->
<g fill="#8a7a5a" stroke="#2a1d14" stroke-width="1">
  <rect x="1445" y="615" width="6" height="18" rx="1"/>
  <rect x="1468" y="612" width="7" height="20" rx="1"/>
  <rect x="1475" y="635" width="5" height="16" rx="1"/>
</g>

<!-- Bone trees: thin lines with small branches -->
<g stroke="#d0c0a0" stroke-width="2" fill="none">
  <line x1="300" y1="1760" x2="295" y2="1795"/>
  <line x1="295" y1="1775" x2="285" y2="1775"/>
  <line x1="295" y1="1785" x2="310" y2="1785"/>
</g>

<!-- Tentacles: curved paths radiating outward -->
<g fill="none" stroke="#7a2530" stroke-width="2.5" opacity="0.6">
  <path d="M 3610,1550 Q 3585,1520 3570,1535"/>
  <path d="M 3685,1545 Q 3715,1515 3730,1530"/>
  <path d="M 3615,1600 Q 3590,1630 3575,1615"/>
  <path d="M 3680,1605 Q 3710,1635 3725,1620"/>
</g>
```

## Hand-Drawn Filter Application

Apply these SVG filters to make shapes look hand-drawn:

```xml
<!-- Rough paper distortion -->
<filter id="roughPaper" x="-20%" y="-20%" width="140%" height="140%">
  <feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="5" result="noise"/>
  <feDisplacementMap in="SourceGraphic" in2="noise" scale="3" xChannelSelector="R" yChannelSelector="G"/>
</filter>

<!-- Ink bleed for coastlines -->
<filter id="inkBleed" x="-10%" y="-10%" width="120%" height="120%">
  <feGaussianBlur stdDeviation="1.2" result="blur"/>
  <feTurbulence type="fractalNoise" baseFrequency="0.1" numOctaves="3" result="noise"/>
  <feDisplacementMap in="blur" in2="noise" scale="4" xChannelSelector="R" yChannelSelector="G"/>
</filter>

<!-- Heavy rough for borders -->
<filter id="heavyRough" x="-20%" y="-20%" width="140%" height="140%">
  <feTurbulence type="fractalNoise" baseFrequency="0.08" numOctaves="4" result="noise"/>
  <feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G"/>
</filter>
```

Apply `filter="url(#roughPaper)"` to island groups, `filter="url(#inkBleed)"` to individual island strokes, and `filter="url(#heavyRough)"` to borders and cartouches.

## Coastal Glow

Use `radialGradient` with eased opacity falloff:

```xml
<radialGradient id="coastGlow" cx="50%" cy="50%" r="50%">
  <stop offset="0%" stop-color="#709595" stop-opacity="0.35"/>
  <stop offset="50%" stop-color="#4a6b6b" stop-opacity="0.1"/>
  <stop offset="100%" stop-color="#2a4050" stop-opacity="0"/>
</radialGradient>
```

One ellipse per island, sized 1.5-2x the island's bounding box.

## Rendering with Playwright

```python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page(viewport={"width": 3840, "height": 2160})
    page.goto("file:///path/to/map.html")
    page.wait_for_timeout(6000)  # Heavy filters need extra time
    page.screenshot(path="map.png", timeout=60000)
    browser.close()
```
