diff --git a/wiki/Architecture.md b/wiki/Architecture.md new file mode 100644 index 00000000..2a932d12 --- /dev/null +++ b/wiki/Architecture.md @@ -0,0 +1,461 @@ +# System Architecture + +This document describes the high-level architecture of the Fantasy Map Generator, including its design patterns, component organization, and key technical decisions. + +## Overview + +The Fantasy Map Generator is a client-side web application built with vanilla JavaScript. It uses a modular architecture where each major feature is encapsulated in its own module, communicating through shared global state objects. + +## Architecture Diagram + +``` +┌─────────────────────────────────────────────────────────────┐ +│ index.html │ +│ (Main Entry Point) │ +└────────────────────────┬────────────────────────────────────┘ + │ + ┌────────────────┼────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌──────────────┐ ┌──────────────┐ ┌──────────────┐ +│ main.js │ │ versioning.js│ │ index.css │ +│ (Core Logic) │ │(Version Mgmt)│ │ (Styles) │ +└──────┬───────┘ └──────────────┘ └──────────────┘ + │ + │ Loads & Coordinates + │ + ▼ +┌─────────────────────────────────────────────────────────┐ +│ modules/ │ +│ ┌────────────────┬────────────────┬─────────────────┐ │ +│ │ Generators │ Renderers │ UI │ │ +│ │ │ │ │ │ +│ │ • heightmap │ • coa-renderer │ • editors/ (41) │ │ +│ │ • rivers │ • relief-icons │ • dialogs │ │ +│ │ • cultures │ • ocean-layers │ • tools │ │ +│ │ • burgs/states │ │ │ │ +│ │ • religions │ │ │ │ +│ │ • routes │ │ │ │ +│ │ • military │ │ │ │ +│ │ • markers │ │ │ │ +│ │ • names │ │ │ │ +│ │ • coa │ │ │ │ +│ │ • biomes │ │ │ │ +│ └────────────────┴────────────────┴─────────────────┘ │ +│ ┌────────────────┬────────────────┐ │ +│ │ I/O │ Dynamic │ │ +│ │ • save/load │ • editors │ │ +│ │ • export │ • utilities │ │ +│ └────────────────┴────────────────┘ │ +└─────────────────────────────────────────────────────────┘ + │ + │ Uses + ▼ +┌─────────────────────────────────────────────────────────┐ +│ libs/ │ +│ • d3.min.js (Data visualization & SVG) │ +│ • delaunator.min.js (Delaunay triangulation) │ +│ • jquery.min.js (DOM manipulation) │ +│ • jquery-ui.min.js (UI widgets) │ +└─────────────────────────────────────────────────────────┘ + │ + │ Manipulates + ▼ +┌─────────────────────────────────────────────────────────┐ +│ Global State │ +│ • grid (Voronoi diagram + terrain data) │ +│ • pack (Civilizations + derived data) │ +│ • seed (Random seed) │ +│ • options (Generation parameters) │ +│ • notes (User annotations) │ +│ • mapHistory (Undo/redo state) │ +└─────────────────────────────────────────────────────────┘ + │ + │ Renders to + ▼ +┌─────────────────────────────────────────────────────────┐ +│ SVG Canvas │ +│ 30+ layered groups for different map elements │ +│ (oceans, terrain, rivers, borders, labels, etc.) │ +└─────────────────────────────────────────────────────────┘ +``` + +## Core Components + +### 1. Entry Point (index.html + main.js) + +**index.html** serves as the application shell, containing: +- SVG canvas with ~30 layered groups (see SVG Layer Structure below) +- UI controls and dialogs +- Script includes for libraries and modules + +**main.js** (67KB+) is the application core, containing: +- Initialization and bootstrapping logic +- Main generation workflow (`generate()` function) +- Global state management +- Event handlers and UI coordination +- Utility functions used throughout the app + +### 2. Module Organization + +All modules follow the **Revealing Module Pattern**: + +```javascript +window.ModuleName = (function() { + // Private variables and functions + const privateData = {}; + + function privateFunction() { + // Implementation + } + + // Public API + function publicFunction() { + // Implementation + } + + return { + publicFunction + }; +})(); +``` + +This provides: +- **Encapsulation** - Private implementation details +- **Namespace management** - Clean global scope +- **Explicit interfaces** - Clear public APIs + +### 3. Module Categories + +#### Generators (`modules/`) + +These modules create map data procedurally: + +- **heightmap-generator.js** - Terrain elevation using templates or images +- **river-generator.js** - Water flow simulation and river networks +- **cultures-generator.js** - Culture placement and expansion +- **burgs-and-states.js** - Capitals, towns, and political boundaries +- **religions-generator.js** - Religion creation and spread +- **routes-generator.js** - Road and trade route networks +- **military-generator.js** - Military units and regiments +- **markers-generator.js** - Map markers and POIs +- **names-generator.js** - Procedural name generation using Markov chains +- **coa-generator.js** - Coat of arms generation +- **biomes.js** - Biome assignment based on climate +- **lakes.js** - Lake creation and management + +#### Renderers (`modules/renderers/`) + +These modules handle visualization: + +- **coa-renderer.js** - Renders coats of arms to SVG +- **relief-icons.js** - Terrain icon rendering +- **ocean-layers.js** - Ocean visualization + +#### UI Modules (`modules/ui/`) + +41+ specialized editors, including: +- Heightmap editor, coastline editor, rivers editor +- Biomes editor, relief editor, temperature/precipitation graphs +- Burg editor, states editor, cultures editor, religions editor +- Provinces editor, routes editor, military overview +- Markers editor, notes editor, zones editor +- Style editors, options editor, tools + +Each editor is a separate file that creates a dialog interface for editing specific map aspects. + +#### I/O Modules (`modules/io/`) + +Handle data persistence and export: +- Save/load functionality (.map format) +- Export to various formats (JSON, SVG, PNG, etc.) +- Cloud storage integration + +#### Dynamic Modules (`modules/dynamic/`) + +Runtime utilities and helpers loaded dynamically as needed. + +### 4. SVG Layer Structure + +The map is rendered to an SVG canvas with ~30 named groups, organized by z-index: + +```xml + +``` + +Each layer can be toggled on/off independently. Elements are drawn to specific layers based on their type, allowing for proper z-ordering and selective rendering. + +## Design Patterns + +### 1. Global State Pattern + +The application uses several global objects to store state: + +```javascript +// Main data structures +let grid = {}; // Voronoi diagram + terrain +let pack = {}; // Civilizations + derived data +let seed = ""; // Random seed for reproducibility +let options = {}; // Generation parameters + +// Additional state +let notes = []; // User annotations +let mapHistory = []; // Undo/redo states +let customization = 0; // Customization level +``` + +**Benefits:** +- Simple communication between modules +- Easy serialization for save/load +- No complex state management library needed + +**Drawbacks:** +- Global namespace pollution +- Implicit dependencies between modules +- Harder to reason about data flow + +### 2. Typed Arrays for Performance + +To handle large datasets efficiently, the application uses JavaScript Typed Arrays: + +```javascript +pack.cells = { + i: new Uint32Array(cells), // Cell indices + h: new Uint8Array(cells), // Height (0-255) + s: new Uint16Array(cells), // State ID + culture: new Uint16Array(cells), // Culture ID + // ... etc +} +``` + +**Benefits:** +- 50-90% memory reduction vs regular arrays +- Faster iteration and access +- Enforced data types prevent bugs + +### 3. Seeded Random Generation + +Uses **aleaPRNG** for reproducible randomness: + +```javascript +Math.random = aleaPRNG(seed); +``` + +Any map can be regenerated identically using the same seed, enabling: +- Sharing maps by seed string +- Debugging reproducibility +- Procedural generation consistency + +### 4. Event-Driven UI Updates + +UI editors trigger updates through event listeners: + +```javascript +$('#someInput').on('change', function() { + updateMapElement(); + drawLayers(); +}); +``` + +Changes immediately reflect on the map, providing real-time feedback. + +### 5. D3.js Data Binding + +Uses D3.js for declarative data-to-DOM binding: + +```javascript +const cells = d3.select('#biomes').selectAll('polygon') + .data(pack.cells.i.filter(i => pack.cells.h[i] >= 20)) + .enter().append('polygon') + .attr('points', d => getCellPolygonPoints(d)) + .attr('fill', d => biomesData.color[pack.cells.biome[d]]); +``` + +This pattern allows efficient updates when data changes. + +## Data Flow + +### Generation Pipeline + +``` +User Input (seed, options) + ↓ +Generate Grid (Voronoi) + ↓ +Heightmap Generation + ↓ +Feature Detection (land/water) + ↓ +Climate Calculation (temp/prec) + ↓ +Repack Grid → Pack + ↓ +Rivers & Lakes + ↓ +Biome Assignment + ↓ +Culture Generation + ↓ +State Generation + ↓ +Settlement Generation + ↓ +Route Generation + ↓ +Rendering to SVG + ↓ +User Interaction (editing) +``` + +### Edit-Render Cycle + +``` +User Edits Data + ↓ +Update Global State (grid/pack) + ↓ +Trigger Render Function + ↓ +D3.js Updates SVG Elements + ↓ +Browser Renders Changes +``` + +## Performance Considerations + +### 1. Cell Count + +Default: **~10,000 cells** in the grid +- More cells = higher detail + slower generation +- Fewer cells = lower detail + faster generation +- Configurable in options + +### 2. Rendering Optimization + +- **Selective Layer Drawing** - Only redraw changed layers +- **D3 Data Binding** - Efficient DOM updates +- **Typed Arrays** - Memory-efficient storage +- **Debounced Updates** - Prevent excessive redraws during editing + +### 3. Lazy Loading + +Some modules are loaded on-demand: +- 3D view components +- Export utilities +- Advanced editors + +## Technology Stack + +### Core Technologies + +- **JavaScript (ES6+)** - Core language +- **SVG** - Vector graphics rendering +- **HTML5 Canvas** - Some bitmap operations +- **CSS3** - Styling and layout + +### Key Libraries + +| Library | Version | Purpose | +|---------|---------|---------| +| **D3.js** | v7+ | Data visualization, SVG manipulation | +| **Delaunator** | Latest | Fast Delaunay triangulation | +| **jQuery** | 3.x | DOM manipulation, AJAX | +| **jQuery UI** | 1.x | Dialogs, sliders, sortable | + +### Algorithms & Techniques + +- **Voronoi Diagrams** - Spatial partitioning for cells +- **Delaunay Triangulation** - Dual graph for Voronoi +- **Markov Chains** - Procedural name generation +- **Heightmap Templates** - Terrain generation patterns +- **Flux-based River Simulation** - Realistic water flow +- **Expansion Algorithms** - Culture and state growth +- **Dijkstra's Algorithm** - Route pathfinding + +## Browser Compatibility + +**Recommended:** Modern evergreen browsers +- Chrome/Edge (Chromium) - Best performance +- Firefox - Good performance +- Safari - Good performance + +**Required Features:** +- ES6 JavaScript support +- SVG 1.1 +- Canvas API +- Local Storage API +- File API for save/load + +## Deployment + +The application is: +- **Static** - No server-side processing required +- **Client-side** - Runs entirely in the browser +- **Portable** - Can run from local filesystem or any web server +- **GitHub Pages** - Official deployment at azgaar.github.io + +## Future Architecture Considerations + +The codebase is acknowledged to be "messy and requires re-design" (per README). Potential improvements: + +1. **Module Bundling** - Use webpack/rollup for better dependency management +2. **State Management** - Consider Redux/MobX for clearer data flow +3. **TypeScript** - Type safety and better IDE support +4. **Component Framework** - Vue/React for more maintainable UI +5. **Web Workers** - Offload heavy generation to background threads +6. **WASM** - Performance-critical sections in Rust/C++ + +However, the current architecture works well for its purpose and maintains accessibility for contributors familiar with vanilla JavaScript. diff --git a/wiki/Data-Model.md b/wiki/Data-Model.md new file mode 100644 index 00000000..39e7dea5 --- /dev/null +++ b/wiki/Data-Model.md @@ -0,0 +1,630 @@ +# Data Model + +This document describes the data structures used by the Fantasy Map Generator. Understanding these structures is essential for contributing to the project or building extensions. + +## Overview + +The generator maintains two primary data structures: + +1. **`grid`** - The initial Voronoi diagram with terrain and climate data +2. **`pack`** - A packed/filtered version with civilizations and derived features + +Both are global objects accessible throughout the application. All map data can be serialized to/from these structures for save/load functionality. + +## Grid Object + +The `grid` object represents the initial Voronoi diagram created from ~10,000 jittered points. It contains the raw terrain and climate data. + +### Structure + +```javascript +grid = { + // Core Voronoi data + points: [[x1, y1], [x2, y2], ...], // Array of [x, y] coordinates + cells: { + i: Uint32Array, // Cell indices [0, 1, 2, ...] + v: Array, // Vertices indices for each cell + c: Array, // Adjacent cell indices + b: Uint8Array, // Border cell (1) or not (0) + f: Uint16Array, // Feature ID (island/ocean/lake) + t: Int8Array, // Cell type: -1=ocean, -2=lake, 1=land + h: Uint8Array, // Height (0-100, where 20 is sea level) + temp: Int8Array, // Temperature (-128 to 127) + prec: Uint8Array, // Precipitation (0-255) + area: Float32Array, // Cell area in square pixels + }, + + // Vertices + vertices: { + p: [[x, y], ...], // Vertex coordinates + v: Array, // Voronoi vertices + c: Array // Adjacent cells to each vertex + }, + + // Seeds (feature centers) + seeds: { + i: Uint16Array, // Seed cell indices + } +} +``` + +### Key Properties + +#### cells.i (Index) +- Unique identifier for each cell +- Values: `0` to `n-1` where `n` is cell count +- Used to reference cells throughout the application + +#### cells.h (Height) +- Elevation value for the cell +- Range: `0-100` (typically) +- Convention: `0-20` = water, `20+` = land +- Higher values = higher elevation + +#### cells.temp (Temperature) +- Temperature in relative units +- Range: `-128` to `127` (signed 8-bit) +- Calculated based on latitude and other factors +- Affects biome assignment + +#### cells.prec (Precipitation) +- Rainfall/moisture level +- Range: `0-255` (unsigned 8-bit) +- Affects river generation and biomes +- Higher near coasts and prevailing winds + +#### cells.f (Feature ID) +- Identifies which landmass/ocean/lake the cell belongs to +- Each contiguous land area gets a unique ID +- Used for island detection and feature management + +#### cells.t (Type) +- Quick type classification +- Values: `-2` = lake, `-1` = ocean, `0` = coast, `1` = land +- Used for filtering and quick checks + +### Grid Methods + +The grid doesn't expose many methods directly. Most operations are performed by utility functions in `main.js`: + +```javascript +// Generate initial grid +generateGrid(); + +// Get neighboring cells +const neighbors = grid.cells.c[cellId]; + +// Check if cell is land +const isLand = grid.cells.h[cellId] >= 20; +``` + +## Pack Object + +The `pack` object is derived from `grid` after initial generation. It contains only land cells and adds civilization data. + +### Structure + +```javascript +pack = { + // Cell data (filtered from grid, only land cells) + cells: { + i: Uint32Array, // Cell indices + p: Array, // [x, y] coordinates + v: Array, // Vertex indices + c: Array, // Adjacent cells + area: Float32Array, // Cell area + + // Terrain data (from grid) + h: Uint8Array, // Height + temp: Int8Array, // Temperature + prec: Uint8Array, // Precipitation + + // Water features + r: Uint16Array, // River ID (0 = no river) + fl: Uint16Array, // Water flux (amount of water flowing) + conf: Uint8Array, // River confluence count + + // Biomes & terrain + biome: Uint8Array, // Biome type ID + + // Civilization + s: Uint16Array, // State ID (0 = neutral) + culture: Uint16Array, // Culture ID + religion: Uint16Array, // Religion ID (0 = no religion) + province: Uint16Array, // Province ID + burg: Uint16Array, // Burg ID (0 = no settlement) + + // Infrastructure + road: Uint16Array, // Road power (0 = no road) + crossroad: Uint16Array, // Crossroad value + + // Derived properties + pop: Float32Array, // Population density + harbor: Uint8Array, // Harbor/port status + }, + + // Vertices + vertices: { + p: Array, // [x, y] coordinates + c: Array, // Adjacent cells + v: Array // Voronoi data + }, + + // Burgs (settlements) + burgs: [ + { + i: Number, // Unique ID + cell: Number, // Cell index where burg is located + x: Number, // X coordinate + y: Number, // Y coordinate + name: String, // Settlement name + feature: Number, // Feature (island) ID + + // Political + state: Number, // State ID + capital: Boolean, // Is state capital + + // Cultural + culture: Number, // Culture ID + + // Population + population: Number, // Total population + type: String, // Settlement type (city, town, etc.) + + // Other + port: Number, // Port/harbor value + citadel: Boolean, // Has citadel/castle + } + ], + + // States (political entities) + states: [ + { + i: Number, // Unique ID (0 = neutral) + name: String, // State name + color: String, // CSS color code + capital: Number, // Capital burg ID + + // Cultural + culture: Number, // Dominant culture ID + religion: Number, // State religion ID + + // Political + type: String, // Government type (Kingdom, Empire, etc.) + expansionism: Number, // Expansion aggressiveness (0-1) + form: String, // "Monarchy", "Republic", etc. + + // Geographic + area: Number, // Total area in cells + cells: Number, // Number of cells + + // Population + rural: Number, // Rural population + urban: Number, // Urban population + + // Military + military: Array, // Military units + + // Diplomacy + diplomacy: Array, // Relations with other states + + // Other + pole: [x, y], // Pole of inaccessibility (label position) + alert: Number, // Alert level + alive: Number, // Is state alive (1) or removed (0) + } + ], + + // Cultures + cultures: [ + { + i: Number, // Unique ID + name: String, // Culture name + base: Number, // Base name generation set + type: String, // Culture type (Generic, River, etc.) + + // Geographic + center: Number, // Origin cell + color: String, // CSS color code + + // Area & population + area: Number, // Total area + cells: Number, // Number of cells + rural: Number, // Rural population + urban: Number, // Urban population + + // Cultural traits + expansionism: Number, // Expansion rate + shield: String, // Shield shape for CoA + code: String, // Two-letter code + } + ], + + // Religions + religions: [ + { + i: Number, // Unique ID (0 = no religion) + name: String, // Religion name + color: String, // CSS color code + type: String, // Religion type (Folk, Organized, etc.) + form: String, // Form (Cult, Church, etc.) + + // Origins + culture: Number, // Origin culture ID + center: Number, // Origin cell + + // Geographic + area: Number, // Total area + cells: Number, // Number of cells + rural: Number, // Rural population + urban: Number, // Urban population + + // Deities & beliefs + deity: String, // Deity name (if applicable) + expansion: String, // Expansion strategy + expansionism: Number, // Expansion rate + code: String, // Two-letter code + } + ], + + // Rivers + rivers: [ + { + i: Number, // Unique ID + source: Number, // Source cell + mouth: Number, // Mouth cell + cells: Array, // Array of cell indices along river + length: Number, // River length + width: Number, // River width + name: String, // River name + type: String, // River type + parent: Number, // Parent river (for tributaries) + } + ], + + // Features (landmasses, oceans, lakes) + features: [ + { + i: Number, // Unique ID + land: Boolean, // Is land (true) or water (false) + border: Boolean, // Touches map border + type: String, // "island", "ocean", "lake" + cells: Number, // Number of cells + firstCell: Number, // First cell of feature + group: String, // Group name (for islands) + area: Number, // Total area + height: Number, // Average height + } + ], + + // Provinces + provinces: [ + { + i: Number, // Unique ID + state: Number, // State ID + name: String, // Province name + formName: String, // Form name (e.g., "Duchy of X") + color: String, // CSS color code + + // Capital + burg: Number, // Capital burg ID + center: Number, // Center cell + + // Geography + area: Number, // Total area + cells: Number, // Number of cells + + // Population + rural: Number, // Rural population + urban: Number, // Urban population + + // Other + pole: [x, y], // Label position + } + ], + + // Markers (map annotations) + markers: [ + { + i: Number, // Unique ID + type: String, // Marker type (volcano, monument, etc.) + x: Number, // X coordinate + y: Number, // Y coordinate + cell: Number, // Cell index + icon: String, // Icon identifier + size: Number, // Icon size + note: String, // Associated note text + } + ] +} +``` + +## Biomes Data + +The `biomesData` object defines biome properties: + +```javascript +biomesData = { + i: [id0, id1, ...], // Biome IDs + name: [...], // Human-readable names + color: [...], // Display colors + habitability: [...], // How suitable for settlements (0-100) + iconsDensity: [...], // Density of relief icons + icons: [...], // Icon sets to use + cost: [...], // Movement cost multiplier + biomesMartix: [...] // Temperature/precipitation mapping +} +``` + +### Standard Biomes + +| ID | Name | Description | +|----|------|-------------| +| 1 | Marine | Ocean biome | +| 2 | Hot desert | Arid, hot regions | +| 3 | Cold desert | Arid, cold regions | +| 4 | Savanna | Grasslands with scattered trees | +| 5 | Grassland | Temperate grasslands | +| 6 | Tropical seasonal forest | Wet/dry tropical forest | +| 7 | Temperate deciduous forest | Moderate climate forests | +| 8 | Tropical rainforest | Dense, wet jungle | +| 9 | Temperate rainforest | Wet coastal forests | +| 10 | Taiga | Boreal forest | +| 11 | Tundra | Treeless cold regions | +| 12 | Glacier | Ice and snow | +| 13 | Wetland | Marshes and swamps | + +## Notes Data + +User annotations stored separately: + +```javascript +notes = [ + { + id: String, // Unique identifier + name: String, // Note title + legend: String, // Legend text + } +] +``` + +## Map History + +Undo/redo system stores state snapshots: + +```javascript +mapHistory = [ + { + json: String, // Serialized map state + options: Object, // Generation options at time + version: String // Generator version + } +] +``` + +## Data Relationships + +### Cell → Civilization Hierarchy + +``` +Cell (pack.cells.i[cellId]) + ├─ Burg (pack.cells.burg[cellId] → pack.burgs[burgId]) + ├─ State (pack.cells.s[cellId] → pack.states[stateId]) + ├─ Culture (pack.cells.culture[cellId] → pack.cultures[cultureId]) + ├─ Religion (pack.cells.religion[cellId] → pack.religions[religionId]) + └─ Province (pack.cells.province[cellId] → pack.provinces[provinceId]) +``` + +### State Hierarchy + +``` +State (pack.states[stateId]) + ├─ Capital Burg (pack.states[stateId].capital → pack.burgs[burgId]) + ├─ Culture (pack.states[stateId].culture → pack.cultures[cultureId]) + ├─ Religion (pack.states[stateId].religion → pack.religions[religionId]) + ├─ Provinces (pack.provinces.filter(p => p.state === stateId)) + └─ Burgs (pack.burgs.filter(b => b.state === stateId)) +``` + +### River Network + +``` +River (pack.rivers[riverId]) + ├─ Source Cell (pack.rivers[riverId].source) + ├─ Mouth Cell (pack.rivers[riverId].mouth) + ├─ Path Cells (pack.rivers[riverId].cells[]) + └─ Parent River (pack.rivers[riverId].parent for tributaries) +``` + +## Data Access Patterns + +### Finding data for a cell + +```javascript +// Given a cell index +const cellId = 1234; + +// Get basic terrain +const height = pack.cells.h[cellId]; +const temperature = pack.cells.temp[cellId]; +const biome = pack.cells.biome[cellId]; + +// Get civilization +const stateId = pack.cells.s[cellId]; +const cultureId = pack.cells.culture[cellId]; +const burgId = pack.cells.burg[cellId]; + +// Get full objects +const state = pack.states[stateId]; +const culture = pack.cultures[cultureId]; +const burg = pack.burgs[burgId]; +``` + +### Finding all cells for an entity + +```javascript +// All cells belonging to a state +const stateCells = pack.cells.i.filter(i => pack.cells.s[i] === stateId); + +// All cells with a specific biome +const biomeCells = pack.cells.i.filter(i => pack.cells.biome[i] === biomeId); + +// All cells with rivers +const riverCells = pack.cells.i.filter(i => pack.cells.r[i] > 0); +``` + +### Iterating efficiently + +```javascript +// Using typed arrays directly (fastest) +for (let i = 0; i < pack.cells.i.length; i++) { + const cellId = pack.cells.i[i]; + const height = pack.cells.h[i]; + // Process cell... +} + +// Using filter + map (more readable) +const mountainCells = pack.cells.i + .filter(i => pack.cells.h[i] > 70) + .map(i => ({ + id: i, + x: pack.cells.p[i][0], + y: pack.cells.p[i][1] + })); +``` + +## Serialization + +### Save Format + +Maps are saved as JSON with the following structure: + +```javascript +{ + info: { + version: String, // Generator version + description: String, // Map description + exportedAt: String, // Timestamp + mapName: String, // Map name + width: Number, // Map width + height: Number, // Map height + seed: String // Random seed + }, + settings: {}, // Generation options + mapCoordinates: {}, // Coordinate system + grid: {}, // Grid data + pack: {}, // Pack data + biomesData: {}, // Biome definitions + notes: [], // User notes + nameBases: [] // Name generation data +} +``` + +### Load Process + +When loading a map: +1. Parse JSON +2. Restore typed arrays from regular arrays +3. Run version migration if needed (via `versioning.js`) +4. Restore global state +5. Regenerate derived data if necessary +6. Render to SVG + +## Performance Considerations + +### Memory Usage + +Typed arrays provide significant memory savings: +- `Uint8Array`: 1 byte per element (0-255) +- `Uint16Array`: 2 bytes per element (0-65,535) +- `Int8Array`: 1 byte per element (-128-127) +- `Float32Array`: 4 bytes per element + +For 10,000 cells: +- Regular array: ~80 KB per property +- Uint8Array: ~10 KB per property +- **80-90% memory reduction** + +### Access Speed + +Typed arrays provide: +- Faster iteration (predictable memory layout) +- Better cache utilization +- Optimized by JavaScript engines + +### Trade-offs + +**Pros:** +- Excellent memory efficiency +- Fast array operations +- Type safety for numeric data + +**Cons:** +- Less flexible than objects +- Parallel arrays can be confusing +- Requires index synchronization + +## Extending the Data Model + +When adding new data: + +1. **Choose the right location** + - Cell-level: Add to `pack.cells.*` + - Entity-level: Add new array like `pack.newEntities[]` + +2. **Use appropriate types** + - IDs: Uint16Array or Uint32Array + - Small numbers: Uint8Array or Int8Array + - Decimals: Float32Array + - Strings/objects: Regular arrays + +3. **Update serialization** + - Add to save format + - Add to load process + - Handle versioning in `versioning.js` + +4. **Consider relationships** + - How does it relate to existing data? + - What indices/lookups are needed? + - How will it be queried? + +### Example: Adding a new cell property + +```javascript +// 1. Add to pack.cells +pack.cells.myProperty = new Uint8Array(pack.cells.i.length); + +// 2. Initialize during generation +function generateMyProperty() { + for (let i = 0; i < pack.cells.i.length; i++) { + pack.cells.myProperty[i] = calculateValue(i); + } +} + +// 3. Update save/load +function saveMap() { + const data = { + // ... existing data + myProperty: Array.from(pack.cells.myProperty) + }; +} + +function loadMap(data) { + // ... load other data + pack.cells.myProperty = new Uint8Array(data.myProperty); +} + +// 4. Use in rendering/editing +function renderMyProperty() { + d3.select('#myLayer').selectAll('path') + .data(pack.cells.i) + .attr('fill', i => getColor(pack.cells.myProperty[i])); +} +``` + +## Reference Documentation + +For more details on specific aspects: +- [Architecture](Architecture.md) - System design and patterns +- [Generation Process](Generation-Process.md) - How data is created +- [Modules Reference](Modules-Reference.md) - Module APIs diff --git a/wiki/Features-and-UI.md b/wiki/Features-and-UI.md new file mode 100644 index 00000000..bf9bb2ba --- /dev/null +++ b/wiki/Features-and-UI.md @@ -0,0 +1,911 @@ +# Features and User Interface + +This document describes all features available in the Fantasy Map Generator and how to use the user interface. + +## Table of Contents + +1. [Main Interface](#main-interface) +2. [Generation Features](#generation-features) +3. [Editing Features](#editing-features) +4. [Visualization Features](#visualization-features) +5. [Export and Save Features](#export-and-save-features) +6. [Advanced Features](#advanced-features) + +--- + +## Main Interface + +### Map Canvas + +The central SVG canvas displays your generated map with multiple layers: + +**Layer Controls:** +- Toggle layers on/off using toolbar buttons +- Adjust layer opacity +- Reorder layers (z-index) + +**Interaction:** +- **Pan**: Click and drag +- **Zoom**: Mouse wheel or pinch gesture +- **Select**: Click on elements to select +- **Info**: Hover for tooltips + +### Toolbar + +Located at the top of the screen, provides quick access to: + +**File Operations:** +- New map +- Open map +- Save map +- Export + +**Tools:** +- Edit mode toggle +- Layer visibility +- Zoom controls +- Fullscreen + +**Options:** +- Generation options +- Style settings +- Editor access + +### Tools Panel + +Expandable side panel with: +- Quick generation options +- Layer toggles +- Minimap +- Statistics + +--- + +## Generation Features + +### Initial Map Generation + +**Access:** File → Generate New Map + +**Options:** + +#### Seed Settings +- **Seed**: Text string for reproducible generation + - Leave blank for random + - Share seeds to recreate maps +- **Random Button**: Generate random seed + +#### Template Selection +- **Heightmap Template**: Choose terrain type + - Pangea - Single large continent + - Continents - Multiple landmasses + - Archipelago - Many islands + - Atoll - Ring-shaped coral island + - Mediterranean - Central sea + - Peninsula - Land projection + - Isthmus - Narrow land bridge + - Volcano - Volcanic island + - High/Low Island - Island types + - Custom - Upload your own heightmap image + +#### World Settings +- **Cell Count**: Map detail level (1,000 - 100,000) + - Lower = faster, less detailed + - Higher = slower, more detailed + - Default: ~10,000 +- **Map Size**: Width and height in pixels +- **Latitude**: North/south positioning (affects climate) + +#### Culture Settings +- **Culture Count**: Number of cultures (1-20) +- **Name Bases**: Select language/naming styles + +#### State Settings +- **State Count**: Number of political entities +- **Expansionism**: How aggressively states expand +- **Neutral Lands**: Percentage of unclaimed territory + +#### Population Settings +- **Urban Density**: Frequency of cities/towns +- **Rural Density**: Population distribution +- **Urban Growth**: City size multiplier + +**Generate Button**: Start map generation with selected options + +--- + +### Quick Regeneration + +**Access:** Tools → Regenerate + +Quickly regenerate specific map aspects: + +- **Regenerate Cultures**: New culture distribution +- **Regenerate States**: New political boundaries +- **Regenerate Religions**: New religious landscape +- **Regenerate Burgs**: New settlement locations +- **Regenerate Rivers**: New river networks +- **Regenerate Routes**: New road networks + +Useful for refining maps without starting over. + +--- + +## Editing Features + +The generator includes 41+ specialized editors for fine-tuning every aspect of your map. + +### Terrain Editing + +#### Heightmap Editor + +**Access:** Layers → Heightmap → Edit Heightmap + +**Features:** +- **Brush Tool**: Paint elevation + - Adjustable size and strength + - Raise or lower terrain +- **Smooth Tool**: Soften elevation changes +- **Flatten Tool**: Create plateaus +- **Add/Remove Land**: Change coastlines +- **Templates**: Apply heightmap patterns to regions +- **Import Image**: Load custom heightmap + +**Usage:** +1. Select tool (brush, smooth, etc.) +2. Adjust size and strength +3. Click and drag on map +4. Changes update in real-time + +#### Biomes Editor + +**Access:** Layers → Biomes → Edit Biomes + +**Features:** +- Change biome type for cells/regions +- View biome distribution +- Adjust climate parameters +- Customize biome colors and properties + +**Biome Types:** +- Marine, Hot Desert, Cold Desert +- Savanna, Grassland +- Tropical Forest, Temperate Forest, Rainforest +- Taiga, Tundra, Glacier +- Wetland + +#### Relief Editor + +**Access:** Layers → Relief → Edit Relief + +**Features:** +- Add/remove terrain icons (mountains, hills, forests) +- Adjust icon density +- Change icon styles +- Customize hill shading + +--- + +### Water Features Editing + +#### Rivers Editor + +**Access:** Layers → Rivers → Edit Rivers + +**Features:** +- **Add River**: Click to create river source +- **Remove River**: Delete rivers +- **Regenerate River**: Recalculate specific river path +- **Edit Path**: Modify river course +- **Name Rivers**: Assign custom names +- **Adjust Width**: Change river width + +**River Properties:** +- Name +- Source and mouth +- Length +- Width +- Type (river, stream, creek) +- Parent (for tributaries) + +#### Lakes Editor + +**Access:** Layers → Lakes → Edit Lakes + +**Features:** +- Create new lakes +- Remove lakes +- Resize lakes +- Name lakes +- Adjust lake elevation + +#### Coastline Editor + +**Access:** Tools → Edit Coastline + +**Features:** +- Reshape coastlines +- Add/remove coastal details +- Create bays and peninsulas +- Smooth jagged coasts + +--- + +### Civilization Editing + +#### Cultures Editor + +**Access:** Layers → Cultures → Edit Cultures + +**Features:** +- **Add Culture**: Create new culture +- **Remove Culture**: Delete culture +- **Expand/Contract**: Adjust territory +- **Properties**: + - Name + - Color + - Name base (language) + - Type (Generic, River, Lake, etc.) + - Expansionism rate + - Shield shape + +**Culture List:** +- View all cultures +- See population and area +- Filter by properties + +#### States Editor + +**Access:** Layers → States → Edit States + +**Features:** +- **Add State**: Create new state +- **Remove State**: Delete state +- **Merge States**: Combine multiple states +- **Split State**: Divide into multiple states +- **Change Capital**: Assign new capital city +- **Adjust Borders**: Reshape boundaries + +**State Properties:** +- Name +- Color +- Capital burg +- Government type (Kingdom, Empire, Republic, etc.) +- Government form (Monarchy, Theocracy, etc.) +- Culture +- Religion +- Expansionism +- Military units +- Diplomacy (relations with other states) + +**Diplomacy:** +- Set relations (Ally, Friendly, Neutral, Unfriendly, Enemy) +- View diplomatic map + +#### Burgs Editor (Settlements) + +**Access:** Layers → Burgs → Edit Burgs + +**Features:** +- **Add Burg**: Place new settlement +- **Remove Burg**: Delete settlement +- **Move Burg**: Relocate settlement +- **Properties**: + - Name + - Type (City, Town, Village) + - Population + - State + - Culture + - Capital status + - Port/harbor + - Citadel/fortress + +**Settlement Types:** +- **Capital**: State capital (largest) +- **City**: Major urban center (10,000+) +- **Town**: Smaller settlement (1,000-10,000) +- **Village**: Small settlement (<1,000) + +**Population:** +- Manually set population +- Auto-calculate based on surroundings +- View urban vs. rural population + +#### Religions Editor + +**Access:** Layers → Religions → Edit Religions + +**Features:** +- **Add Religion**: Create new religion +- **Remove Religion**: Delete religion +- **Expand/Contract**: Adjust territory +- **Properties**: + - Name + - Color + - Type (Folk, Organized, Cult, Heresy) + - Form (Cult, Church, Temple, etc.) + - Origin culture + - Deity name (if applicable) + - Expansion strategy + +#### Provinces Editor + +**Access:** Layers → Provinces → Edit Provinces + +**Features:** +- Add/remove provinces +- Adjust provincial boundaries +- Assign provincial capitals +- Name provinces +- View province statistics + +**Province Properties:** +- Name +- Form name (Duchy, County, Prefecture, etc.) +- State +- Capital burg +- Area +- Population + +--- + +### Infrastructure Editing + +#### Routes Editor + +**Access:** Layers → Routes → Edit Routes + +**Features:** +- **Add Route**: Create road/trail/sea route +- **Remove Route**: Delete route +- **Regenerate Routes**: Recalculate optimal paths +- **Edit Path**: Modify route course + +**Route Types:** +- **Roads**: Major land routes (black lines) +- **Trails**: Minor paths (dashed lines) +- **Sea Routes**: Maritime trade routes (blue lines) + +**Properties:** +- Connected burgs +- Length +- Width/importance +- Path points + +#### Military Overview + +**Access:** Tools → Military + +**Features:** +- View all military units +- Add/remove units +- Assign units to burgs +- Calculate military strength + +**Unit Properties:** +- Name +- Type (Infantry, Cavalry, Archers, Artillery, Fleet) +- Strength (number of soldiers) +- State +- Location (burg) + +--- + +### Annotations and Markers + +#### Markers Editor + +**Access:** Layers → Markers → Edit Markers + +**Features:** +- **Add Marker**: Place custom markers +- **Remove Marker**: Delete markers +- **Properties**: + - Type (volcano, ruins, mine, bridge, etc.) + - Icon + - Size + - Associated note + +**Marker Types:** +- Volcanoes 🌋 +- Ruins 🏛️ +- Battlefields ⚔️ +- Mines ⛏️ +- Bridges 🌉 +- Monuments 🗿 +- Shrines ⛩️ +- Castles 🏰 +- Capitals ⭐ + +#### Notes Editor + +**Access:** Tools → Notes + +**Features:** +- **Add Note**: Create text annotation +- **Edit Note**: Modify note text +- **Pin to Location**: Associate with marker/location +- **Categories**: Organize notes by type + +**Note Properties:** +- Title +- Description (rich text) +- Legend text +- Associated markers + +#### Zones Editor + +**Access:** Layers → Zones + +**Features:** +- Define custom zones/regions +- Outline areas for campaigns +- Mark territories +- Add zone labels + +--- + +## Visualization Features + +### Style Editor + +**Access:** Style → Edit Style + +**Features:** + +#### Color Schemes +- **Terrain**: Heightmap coloring +- **States**: Political boundaries +- **Cultures**: Cultural regions +- **Religions**: Religious distribution +- **Biomes**: Vegetation zones + +#### Presets +- Default +- Antique +- Monochrome +- Watercolor +- And more... + +#### Customization +- Background color +- Ocean color +- Land gradient +- Border styles +- Label fonts and sizes + +### Label Settings + +**Access:** Style → Labels + +**Features:** +- **Show/Hide Labels**: Toggle label types + - State names + - Burg names + - Province names + - River names + - Region names +- **Font Settings**: + - Font family + - Font size + - Font style (bold, italic) + - Text color + - Stroke color and width +- **Label Positioning**: Auto or manual placement + +### Layer Visibility + +**Access:** Toolbar layer buttons + +**Toggleable Layers:** +- Terrain (heightmap) +- Biomes +- States +- Cultures +- Religions +- Provinces +- Borders +- Rivers +- Lakes +- Coastline +- Routes (roads, trails, sea routes) +- Burgs (settlements) +- Icons (relief icons) +- Markers +- Labels +- Temperature (overlay) +- Precipitation (overlay) +- Population (density overlay) +- Grid +- Coordinates +- Scale bar +- Compass +- Legend + +--- + +### Temperature and Precipitation + +**Access:** Layers → Temperature / Precipitation + +**Features:** +- View temperature distribution +- View precipitation patterns +- Adjust climate parameters +- See climate effects on biomes + +**Display:** +- Heat map overlay +- Gradient visualization +- Isolines + +--- + +### 3D View + +**Access:** Tools → 3D View + +**Features:** +- 3D terrain visualization +- Rotate and zoom +- Adjust elevation exaggeration +- Change lighting angle +- Export 3D view + +**Controls:** +- Mouse drag to rotate +- Scroll to zoom +- Sliders for parameters + +--- + +### Emblems and Heraldry + +**Access:** Click on state/burg/province + +**Features:** +- View coat of arms +- Regenerate heraldry +- Customize elements: + - Shield shape + - Divisions + - Charges (symbols) + - Tinctures (colors) + +**Heraldic Elements:** +- 200+ charges (lions, eagles, crowns, etc.) +- Multiple shield shapes +- Standard heraldic rules +- Export as SVG/PNG + +--- + +## Export and Save Features + +### Save Map + +**Access:** File → Save Map + +**Formats:** +- **.map** - Native format (includes all data) +- Compressed JSON +- Can be loaded later + +**Features:** +- Auto-save to browser storage +- Manual save to file +- Save to cloud (Dropbox integration) + +--- + +### Load Map + +**Access:** File → Load Map + +**Sources:** +- Local file +- URL +- Dropbox +- Browser storage (auto-saved) + +**Compatibility:** +- Automatic version migration +- Handles old map formats +- Validates data integrity + +--- + +### Export Options + +**Access:** File → Export + +#### Export SVG + +- Vector format +- Scalable without quality loss +- Edit in Inkscape, Illustrator, etc. +- Options: + - All layers or selected layers + - Embedded fonts + - Optimized output + +#### Export PNG + +- Raster format +- High resolution available +- Options: + - Resolution (DPI) + - Size (width × height) + - Quality + - Transparent background + +#### Export JSON + +- Raw data export +- All map data in JSON format +- Use for custom processing +- Import into other tools + +#### Export Other Formats + +- **PDF**: Print-ready format +- **CSV**: Data tables (burgs, states, etc.) +- **GeoJSON**: Geographic data format + +--- + +### Print Map + +**Access:** File → Print + +**Features:** +- Print-optimized layout +- Paper size selection +- Scale adjustment +- Layer selection +- Preview before printing + +--- + +## Advanced Features + +### Submaps + +**Access:** Tools → Create Submap + +**Purpose:** Generate detailed map of a specific region + +**Features:** +- Select region on main map +- Generate high-detail submap +- Inherit terrain and features +- Independent editing + +**Use Cases:** +- Zooming into a kingdom +- Detailed city surroundings +- Regional campaigns + +--- + +### Focus Mode + +**Access:** Tools → Focus + +**Features:** +- **Focus on Cell**: Zoom to specific cell +- **Focus on Burg**: Center on settlement +- **Focus on Coordinates**: Go to X, Y position + +--- + +### Elevation Profile + +**Access:** Tools → Elevation Profile + +**Features:** +- Draw line on map +- View elevation graph along line +- Measure distance +- Identify peaks and valleys + +--- + +### Battle Screen + +**Access:** Tools → Battle Screen + +**Features:** +- Tactical battle map view +- Hexagonal grid overlay +- Unit placement +- Terrain effects + +--- + +### Customization + +#### Custom Name Bases + +**Access:** Tools → Name Bases + +**Features:** +- Add custom language/naming +- Provide example names +- Generator learns patterns +- Apply to cultures + +#### Custom Biomes + +**Access:** Biomes → Customize + +**Features:** +- Define new biome types +- Set climate parameters +- Assign colors and icons +- Adjust habitability + +--- + +### Versioning + +**Access:** Automatic + +**Features:** +- Maps store version info +- Auto-upgrade on load +- Maintains compatibility +- Migration scripts for old maps + +Handled by `versioning.js`. + +--- + +### Undo/Redo + +**Access:** Edit menu or Ctrl+Z / Ctrl+Y + +**Features:** +- Undo recent changes +- Redo undone changes +- History tracking +- Multiple undo levels + +--- + +### Keyboard Shortcuts + +**Common Shortcuts:** +- **Ctrl+Z**: Undo +- **Ctrl+Y**: Redo +- **Ctrl+S**: Save map +- **Ctrl+O**: Open map +- **F11**: Fullscreen +- **Space**: Pan mode +- **+/-**: Zoom in/out +- **Esc**: Cancel current operation + +--- + +### Map Statistics + +**Access:** Tools → Statistics + +**Features:** +- Total land area +- Total population +- Number of states +- Number of burgs +- Culture distribution +- Religion distribution +- Biome distribution +- And more... + +**Export:** Export statistics as CSV/JSON + +--- + +### Randomization Tools + +**Access:** Tools → Randomize + +**Features:** +- Randomize names (burgs, states, etc.) +- Randomize colors +- Randomize coats of arms +- Randomize any specific aspect + +Useful for quickly generating variations. + +--- + +## Tips and Tricks + +### Performance Optimization + +1. **Lower cell count** for faster generation +2. **Disable unused layers** for better rendering +3. **Use simple styles** for complex maps +4. **Close editors** when not in use + +### Best Practices + +1. **Save frequently** to avoid data loss +2. **Use seeds** for reproducibility +3. **Start with templates** then customize +4. **Layer edits** progressively (terrain → cultures → states) +5. **Backup important maps** + +### Common Workflows + +#### Creating a Campaign Map + +1. Generate base map with template +2. Adjust terrain with heightmap editor +3. Refine rivers and lakes +4. Edit culture and state boundaries +5. Add important cities/locations +6. Place markers for quest locations +7. Add notes for lore +8. Style and export + +#### Creating a World Map + +1. Use "Continents" template +2. Generate with medium cell count +3. Focus on large-scale features +4. Simplify details (fewer burgs) +5. Adjust states for empires/kingdoms +6. Export at high resolution + +#### Creating a Regional Map + +1. Use "Peninsula" or custom template +2. High cell count for detail +3. Add many burgs +4. Detailed provinces +5. Add markers for every point of interest +6. Extensive notes and lore + +--- + +## Troubleshooting + +### Common Issues + +**Map Won't Generate:** +- Check browser console for errors +- Try lower cell count +- Use different template +- Clear browser cache + +**Performance Issues:** +- Reduce cell count +- Disable complex layers +- Close other browser tabs +- Use modern browser + +**Export Not Working:** +- Check browser permissions +- Try different format +- Reduce export size +- Update browser + +**Data Loss:** +- Check auto-save in browser storage +- Look for backup files +- Enable cloud save + +For more help: +- [GitHub Issues](https://github.com/Azgaar/Fantasy-Map-Generator/issues) +- [Discord Community](https://discordapp.com/invite/X7E84HU) +- [Reddit Community](https://www.reddit.com/r/FantasyMapGenerator) + +--- + +## Further Reading + +- [Generation Process](Generation-Process.md) - How maps are created +- [Data Model](Data-Model.md) - Understanding the data +- [Modules Reference](Modules-Reference.md) - Technical details +- [Architecture](Architecture.md) - System design diff --git a/wiki/Generation-Process.md b/wiki/Generation-Process.md new file mode 100644 index 00000000..90c9fad6 --- /dev/null +++ b/wiki/Generation-Process.md @@ -0,0 +1,805 @@ +# Map Generation Process + +This document explains how the Fantasy Map Generator creates maps, describing each step of the generation pipeline in detail. + +## Overview + +Map generation is a multi-stage process where each stage builds upon the previous one. The entire process is orchestrated by the `generate()` function in `main.js`. + +## Generation Pipeline + +``` +┌─────────────────────────────────────────────────────────┐ +│ 1. Initialization │ +│ • Set random seed │ +│ • Apply map size and options │ +│ • Initialize data structures │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 2. Grid Generation │ +│ • Create jittered point grid │ +│ • Generate Voronoi diagram via Delaunay triangulation │ +│ • ~10,000 cells by default │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 3. Heightmap Generation │ +│ • Generate terrain elevation (0-100) │ +│ • Use templates or custom heightmaps │ +│ • Sea level typically at 20 │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 4. Feature Detection │ +│ • Identify land vs water │ +│ • Detect islands, continents, oceans │ +│ • Mark coastal cells │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 5. Climate Calculation │ +│ • Calculate temperature (latitude-based) │ +│ • Generate precipitation patterns │ +│ • Wind and moisture simulation │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 6. Repack Grid │ +│ • Filter land cells from grid │ +│ • Create pack structure │ +│ • Add additional cell properties │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 7. Water Features │ +│ • Draw coastlines │ +│ • Generate rivers (flux calculation + flow) │ +│ • Create lakes in depressions │ +│ • Define lake groups │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 8. Biome Assignment │ +│ • Map temperature + precipitation to biomes │ +│ • 13 biome types (desert, forest, tundra, etc.) │ +│ • Store in pack.cells.biome │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 9. Cell Ranking │ +│ • Calculate cell suitability for settlement │ +│ • Based on terrain, biome, rivers, coasts │ +│ • Used for placement of towns/cities │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 10. Culture Generation │ +│ • Place culture centers │ +│ • Expand cultures across suitable cells │ +│ • Assign name generation bases │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 11. Burgs and States │ +│ • Place capital cities │ +│ • Generate states around capitals │ +│ • Add secondary towns │ +│ • Define state boundaries │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 12. Religion Generation │ +│ • Create religions from cultures │ +│ • Spread religions across territories │ +│ • Assign state religions │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 13. Provinces │ +│ • Divide states into provinces │ +│ • Assign provincial capitals │ +│ • Define provincial boundaries │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 14. Route Generation │ +│ • Create road networks between burgs │ +│ • Generate sea routes │ +│ • Add trails to secondary locations │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 15. Military Generation │ +│ • Create military units for states │ +│ • Assign regiments to burgs │ +│ • Calculate military strength │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 16. Marker Generation │ +│ • Place special markers (volcanoes, ruins, etc.) │ +│ • Add points of interest │ +└────────────────────┬────────────────────────────────────┘ + │ +┌────────────────────▼────────────────────────────────────┐ +│ 17. Rendering │ +│ • Draw all map layers to SVG │ +│ • Render states, borders, labels │ +│ • Apply styling │ +│ • Add UI elements (scale, compass, legend) │ +└─────────────────────────────────────────────────────────┘ +``` + +## Detailed Stage Descriptions + +### 1. Initialization + +**File:** `main.js` +**Function:** `generate()` + +```javascript +async function generate(options) { + seed = generateSeed(); + Math.random = aleaPRNG(seed); // Set seeded RNG + applyGraphSize(); // Set SVG dimensions + randomizeOptions(); // Initialize generation parameters +} +``` + +**Purpose:** +- Establishes random seed for reproducibility +- Sets map dimensions (width, height) +- Initializes generation options (templates, settings) + +**Seed:** +- Can be user-specified or randomly generated +- Ensures identical maps can be regenerated +- Format: Short string (e.g., "abc123") + +### 2. Grid Generation + +**File:** `main.js` +**Function:** `generateGrid()` + +```javascript +function generateGrid() { + const points = generateJitteredPoints(cellsDesired); + const delaunay = Delaunator.from(points); + const voronoi = new Voronoi(delaunay, points); + grid = voronoi.toGrid(); +} +``` + +**Purpose:** +- Creates the spatial data structure for the map +- Divides map into cells using Voronoi diagram + +**Process:** +1. Generate ~10,000 points in a jittered grid pattern +2. Create Delaunay triangulation from points +3. Compute dual Voronoi diagram +4. Store in `grid` object + +**Why Voronoi?** +- Natural-looking irregular cells +- Efficient neighbor lookups +- Well-suited for procedural generation + +### 3. Heightmap Generation + +**File:** `modules/heightmap-generator.js` +**Module:** `HeightmapGenerator` + +```javascript +await HeightmapGenerator.generate(); +``` + +**Templates Available:** +- **Pangea** - Single large continent +- **Archipelago** - Many islands +- **Atoll** - Ring-shaped island +- **Continents** - Multiple landmasses +- **High Island** - Volcanic island +- **Low Island** - Flat coral island +- **And more...** + +**Process:** +1. Select template or use custom heightmap +2. Apply template algorithm to assign elevations +3. Smooth and add noise for realism +4. Normalize values to 0-100 range +5. Store in `grid.cells.h` + +**Height Conventions:** +- `0-19`: Water (ocean/lakes) +- `20`: Sea level +- `20-30`: Coastal lowlands +- `30-50`: Plains +- `50-70`: Hills +- `70+`: Mountains + +### 4. Feature Detection + +**File:** `main.js` +**Function:** `markFeatures()` + +```javascript +function markFeatures() { + detectIslands(); + markOceans(); + markLakes(); + markCoastalCells(); +} +``` + +**Purpose:** +- Identifies distinct geographic features +- Labels landmasses and water bodies +- Detects borders and coastlines + +**Feature Types:** +- **Islands/Continents**: Contiguous land areas +- **Oceans**: Large water bodies touching borders +- **Lakes**: Enclosed water bodies on land + +Each feature gets a unique ID stored in `grid.cells.f`. + +### 5. Climate Calculation + +**File:** `main.js` +**Functions:** `calculateTemperatures()`, `generatePrecipitation()` + +**Temperature:** +```javascript +// Based on latitude +const latitude = y / mapHeight; // 0 = north, 1 = south +const temp = temperatureCurve(latitude, elevation); +grid.cells.temp[i] = temp; +``` + +Factors affecting temperature: +- **Latitude** - Colder at poles, warmer at equator +- **Elevation** - Decreases with height +- **Ocean proximity** - Moderating effect + +**Precipitation:** +```javascript +// Moisture from oceans, modified by prevailing winds +const prec = calculateMoisture(cell, windDirection); +grid.cells.prec[i] = prec; +``` + +Factors affecting precipitation: +- **Ocean proximity** - Higher near coasts +- **Wind direction** - Prevailing winds bring moisture +- **Elevation** - Rain shadow effects +- **Temperature** - Warmer air holds more moisture + +### 6. Repack Grid + +**File:** `main.js` +**Function:** `reGraph()` + +```javascript +function reGraph() { + pack.cells = filterLandCells(grid.cells); + pack.vertices = grid.vertices; + // Add additional properties... +} +``` + +**Purpose:** +- Creates optimized structure for land-only operations +- Removes ocean cells to save memory +- Adds civilization-related properties + +**New Properties Added:** +- `s` - State ID +- `culture` - Culture ID +- `religion` - Religion ID +- `burg` - Settlement ID +- `province` - Province ID +- `road` - Road network +- `pop` - Population density + +### 7. Water Features + +#### Coastline Drawing + +**File:** `main.js` +**Function:** `drawCoastline()` + +Renders coastlines to SVG for visualization. + +#### River Generation + +**File:** `modules/river-generator.js` +**Module:** `Rivers.generate()` + +```javascript +Rivers.generate() { + calculateFlux(); // Water accumulation + createRiverPaths(); // Route rivers downhill + applyDowncutting(); // Erosion simulation + detectConfluence(); // Identify river junctions +} +``` + +**Flux Calculation:** +- Each cell receives water from precipitation +- Water flows to lowest adjacent cell +- Accumulates creating river strength + +**River Pathing:** +- Start from high-flux cells +- Follow elevation gradient downward +- Terminate at ocean or lake +- Tributaries merge into larger rivers + +**Downcutting:** +- Rivers erode terrain over time +- Lowers elevation along river paths +- Creates valleys and canyons + +#### Lake Creation + +**File:** `modules/lakes.js` +**Module:** `Lakes.defineGroup()` + +- Identifies water cells not connected to ocean +- Groups adjacent lake cells +- Names lakes +- Calculates lake areas + +### 8. Biome Assignment + +**File:** `modules/biomes.js` +**Module:** `Biomes.define()` + +```javascript +Biomes.define() { + for (const cell of pack.cells.i) { + const temp = pack.cells.temp[cell]; + const prec = pack.cells.prec[cell]; + const biome = biomeMatrix[temp][prec]; + pack.cells.biome[cell] = biome; + } +} +``` + +**Biome Matrix:** +Maps temperature + precipitation to biome types: + +``` + Precipitation → + Low Medium High + ┌──────────┬──────────┬──────────┐ +T Hot │ Desert │ Savanna │ Tropical │ +e ├──────────┼──────────┼──────────┤ +m Warm │Grassland │ Forest │Rainforest│ +p ├──────────┼──────────┼──────────┤ +↓ Cold │ Tundra │ Taiga │ Wetland │ + └──────────┴──────────┴──────────┘ +``` + +**13 Biome Types:** +1. Marine (ocean) +2. Hot desert +3. Cold desert +4. Savanna +5. Grassland +6. Tropical seasonal forest +7. Temperate deciduous forest +8. Tropical rainforest +9. Temperate rainforest +10. Taiga +11. Tundra +12. Glacier +13. Wetland + +### 9. Cell Ranking + +**File:** `main.js` +**Function:** `rankCells()` + +```javascript +function rankCells() { + for (const cell of pack.cells.i) { + let score = 0; + score += biomeHabitability[pack.cells.biome[cell]]; + score += riverBonus[pack.cells.r[cell]]; + score += coastalBonus[isCoastal(cell)]; + score -= elevationPenalty[pack.cells.h[cell]]; + pack.cells.s[cell] = score; + } +} +``` + +**Factors:** +- **Biome habitability** - Forests good, deserts bad +- **River proximity** - Rivers provide water and trade +- **Coastal location** - Access to fishing and trade +- **Elevation** - Lowlands preferred over mountains + +**Used For:** +- Selecting locations for towns and cities +- Expanding cultures and states +- Calculating population density + +### 10. Culture Generation + +**File:** `modules/cultures-generator.js` +**Module:** `Cultures.generate()` and `Cultures.expand()` + +**Generation Process:** + +```javascript +Cultures.generate() { + const count = rn(5, 10); // 5-10 cultures + for (let i = 0; i < count; i++) { + const center = selectHighRankCell(); + const culture = createCulture(center); + pack.cultures.push(culture); + } +} + +Cultures.expand() { + // Expand from centers using expansion algorithm + for (const culture of pack.cultures) { + expandFromCenter(culture, culture.expansionism); + } +} +``` + +**Placement:** +- Cultures start at high-rank cells +- Multiple cultures per map (5-10 typical) + +**Expansion:** +- Spreads outward from origin +- Prefers habitable terrain +- Stops at natural barriers (oceans, mountains) +- Fills until meeting other cultures + +**Properties:** +- Name (procedurally generated) +- Color (for map display) +- Name base (for generating place names) +- Type (Generic, River, Lake, Naval, etc.) +- Shield shape (for coat of arms) + +### 11. Burgs and States + +**File:** `modules/burgs-and-states.js` +**Module:** `BurgsAndStates.generate()` + +**Capital Placement:** + +```javascript +BurgsAndStates.generate() { + // 1. Place capitals + for (const culture of pack.cultures) { + const capital = placeCapital(culture); + pack.burgs.push(capital); + } + + // 2. Create states from capitals + for (const capital of capitals) { + const state = createState(capital); + expandState(state); + pack.states.push(state); + } + + // 3. Add secondary towns + addSecondaryBurgs(); +} +``` + +**Burg Types:** +- **Capital** - State capital (largest city) +- **City** - Major urban center +- **Town** - Smaller settlement + +**Burg Properties:** +- Name (from culture's name base) +- Population (based on rank + surroundings) +- Type (city, town, etc.) +- Port status (if coastal) +- Citadel (defensive structures) + +**State Creation:** +- Each capital becomes center of a state +- State expands to fill territory +- Boundaries form where states meet +- Neutral areas remain unclaimed + +**State Properties:** +- Name (from capital + government form) +- Color (randomly assigned) +- Type (Kingdom, Empire, Republic, etc.) +- Culture (dominant culture) +- Religion (state religion) +- Expansionism (aggressiveness) + +### 12. Religion Generation + +**File:** `modules/religions-generator.js` +**Module:** `Religions.generate()` + +```javascript +Religions.generate() { + const count = rn(5, 10); + for (let i = 0; i < count; i++) { + const culture = selectRandomCulture(); + const religion = createReligion(culture); + pack.religions.push(religion); + expandReligion(religion); + } + assignStateReligions(); +} +``` + +**Religion Types:** +- Folk religions (localized) +- Organized religions (widespread) +- Cults (small followings) + +**Expansion:** +- Spreads from origin culture +- Can cross state borders +- Expansion rate varies by type +- Some states adopt as official religion + +### 13. Province Generation + +**File:** `modules/burgs-and-states.js` +**Module:** `BurgsAndStates.generateProvinces()` + +```javascript +BurgsAndStates.generateProvinces() { + for (const state of pack.states) { + const provinceCount = calculateProvinceCount(state.area); + divideIntoProvinces(state, provinceCount); + } +} +``` + +**Process:** +- Larger states divided into provinces +- Each province has a capital burg +- Province boundaries respect state borders +- Names generated from capitals + titles + +### 14. Route Generation + +**File:** `modules/routes-generator.js` +**Module:** `Routes.generate()` + +```javascript +Routes.generate() { + generateRoads(); // Land routes between burgs + generateTrails(); // Secondary paths + generateSeaRoutes(); // Maritime trade routes +} +``` + +**Road Generation:** +- Connects burgs within states +- Pathfinding considers terrain +- Major roads between large cities +- Secondary roads to smaller towns + +**Sea Routes:** +- Connects coastal burgs +- Maritime trade routes +- Follows coastlines or crosses seas + +**Route Properties:** +- Width/importance +- Points along route +- Connected burgs + +### 15. Military Generation + +**File:** `modules/military-generator.js` +**Module:** `Military.generate()` + +```javascript +Military.generate() { + for (const state of pack.states) { + const unitCount = calculateUnits(state.population); + for (let i = 0; i < unitCount; i++) { + const unit = createMilitaryUnit(state); + state.military.push(unit); + } + } +} +``` + +**Military Units:** +- Based on state population +- Assigned to burgs +- Types: infantry, cavalry, archers, etc. +- Used for calculating state strength + +### 16. Marker Generation + +**File:** `modules/markers-generator.js` +**Module:** `Markers.generate()` + +```javascript +Markers.generate() { + placeVolcanoes(); + placeRuins(); + placeBattlefields(); + // ... other marker types +} +``` + +**Marker Types:** +- Volcanoes (on mountains) +- Ruins (ancient sites) +- Battlefields (historical locations) +- Monuments +- Mines +- Bridges +- And more... + +**Placement:** +- Based on terrain suitability +- Random with constraints +- Can be manually added by users + +### 17. Rendering + +**File:** `main.js` +**Multiple Functions:** `drawStates()`, `drawRivers()`, `drawLabels()`, etc. + +```javascript +function renderMap() { + drawOcean(); + drawTerrain(); + drawBiomes(); + drawRivers(); + drawLakes(); + drawStates(); + drawBorders(); + drawRoutes(); + drawBurgs(); + drawLabels(); + drawIcons(); + drawScaleBar(); + drawCompass(); +} +``` + +**Rendering Process:** +- Uses D3.js for SVG manipulation +- Layers drawn in order (back to front) +- Styling applied from templates +- Interactive elements attached + +**Performance:** +- Selective layer updates +- Efficient D3 data binding +- Minimal redraws during editing + +## Generation Options + +Users can customize generation through various options: + +### Heightmap Options +- **Template** - Select terrain type +- **Custom Image** - Upload heightmap +- **Seed** - Reproducible generation + +### World Options +- **Cell Count** - Map detail level +- **Map Size** - Width and height +- **Randomize** - Randomize all settings + +### Culture Options +- **Culture Count** - Number of cultures +- **Name Bases** - Language/naming styles + +### State Options +- **State Count** - Number of states +- **Expansionism** - Aggression levels + +### Population Options +- **Urban Density** - City frequency +- **Rural Density** - Population spread + +## Procedural Name Generation + +**File:** `modules/names-generator.js` +**Algorithm:** Markov Chains + +```javascript +Names.generate(base, type) { + const chain = nameBases[base]; + const name = markovGenerate(chain, type); + return name; +} +``` + +**Name Bases:** +Each culture has a name base (e.g., "English", "Arabic", "Chinese") used to generate: +- Burg names (e.g., "Oakshire", "Riverton") +- Province names +- Character names +- Geographic feature names + +**Markov Chains:** +- Learns patterns from example names +- Generates new names matching the style +- Produces authentic-sounding results + +## Randomization & Seeds + +**Seed Format:** +- Short alphanumeric string +- Example: "abc123" + +**Determinism:** +- Same seed = identical map +- Allows sharing maps by seed +- Useful for debugging + +**Randomization:** +Uses custom PRNG (Alea) for: +- Cross-platform consistency +- Save/load reliability +- Reproducible generation + +## Performance Optimization + +### Generation Speed + +**Fast Operations:** +- Grid generation (~100ms) +- Heightmap (~200ms) +- Climate (~50ms) + +**Slow Operations:** +- River generation (~500ms+) +- Culture expansion (~300ms) +- State generation (~400ms) + +**Total Time:** ~2-5 seconds for full map + +### Optimization Techniques + +1. **Typed Arrays** - Memory-efficient storage +2. **Minimal Reflows** - Batch DOM updates +3. **Incremental Rendering** - Progressive display +4. **Spatial Indexing** - Fast neighbor lookups +5. **Caching** - Reuse calculated values + +## Troubleshooting Generation Issues + +### Common Problems + +**No Rivers Generating:** +- Check precipitation settings +- Ensure adequate elevation gradients +- Verify template allows rivers + +**States Not Forming:** +- Increase culture count +- Check biome habitability +- Ensure enough land area + +**Performance Issues:** +- Reduce cell count +- Simplify heightmap +- Disable unused features + +For more help, see [Performance Tips](https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Tips#performance-tips). + +## Next Steps + +- [Data Model](Data-Model.md) - Understanding the data structures +- [Modules Reference](Modules-Reference.md) - Detailed module documentation +- [Architecture](Architecture.md) - System design overview diff --git a/wiki/Getting-Started.md b/wiki/Getting-Started.md new file mode 100644 index 00000000..c2ccc59e --- /dev/null +++ b/wiki/Getting-Started.md @@ -0,0 +1,780 @@ +# Getting Started + +Welcome! This guide will help you get started with the Fantasy Map Generator, whether you're a user wanting to create maps or a developer wanting to contribute. + +## Table of Contents + +1. [For Users](#for-users) +2. [For Developers](#for-developers) +3. [Quick Start Tutorial](#quick-start-tutorial) +4. [Contributing](#contributing) +5. [Resources](#resources) + +--- + +## For Users + +### Using the Online Version + +The easiest way to use the Fantasy Map Generator is through the web application: + +**Link:** [azgaar.github.io/Fantasy-Map-Generator](https://azgaar.github.io/Fantasy-Map-Generator) + +**Requirements:** +- Modern web browser (Chrome, Firefox, Safari, or Edge) +- JavaScript enabled +- Recommended: Desktop or laptop (mobile works but with limitations) + +**No installation needed!** Just open the link and start generating maps. + +--- + +### Using the Desktop Version + +For offline use or better performance, download the Electron desktop application: + +**Download:** [GitHub Releases](https://github.com/Azgaar/Fantasy-Map-Generator/releases) + +**Installation:** + +1. Go to the releases page +2. Download the archive for your platform: + - **Windows**: `FMG-windows-x64.zip` + - **macOS**: `FMG-darwin-x64.zip` + - **Linux**: `FMG-linux-x64.zip` +3. Extract the archive +4. Run the executable: + - **Windows**: `FMG.exe` + - **macOS**: `FMG.app` + - **Linux**: `FMG` + +**Benefits:** +- Works offline +- Better performance +- No browser limitations +- Easier file management + +--- + +### Creating Your First Map + +**Step 1: Open the Generator** + +Visit the website or open the desktop app. + +**Step 2: Generate** + +Click the **"Generate New Map"** button (or it generates automatically on first load). + +**Step 3: Explore** + +Your map is ready! You'll see: +- Terrain with mountains, plains, and water +- Rivers and lakes +- Political boundaries (states) +- Cities and towns +- Labels and names + +**Step 4: Customize** + +Use the toolbar to: +- Toggle layers on/off +- Zoom and pan +- Open editors to modify the map +- Change visual style + +**Step 5: Save** + +Click **File → Save Map** to download your map as a `.map` file. + +**Congratulations!** You've created your first fantasy map. + +--- + +### Basic Controls + +**Mouse Controls:** +- **Left Click**: Select elements +- **Right Click**: Context menu (in editors) +- **Drag**: Pan the map +- **Scroll**: Zoom in/out +- **Hover**: Show tooltips + +**Keyboard Shortcuts:** +- **Ctrl+Z**: Undo +- **Ctrl+Y**: Redo +- **Ctrl+S**: Save +- **Ctrl+O**: Open +- **F11**: Fullscreen +- **Space**: Toggle pan mode + +--- + +### Common Tasks + +#### Changing Terrain + +1. Click **Layers → Heightmap** +2. Click **Edit Heightmap** +3. Use brush tools to raise/lower terrain +4. Click **Apply** + +#### Adding a City + +1. Click **Layers → Burgs** +2. Click **Add Burg** +3. Click on map where you want the city +4. Fill in name and details +5. Click **Add** + +#### Customizing Colors + +1. Click **Style → Edit Style** +2. Select element to customize (states, terrain, etc.) +3. Choose colors +4. Click **Apply** + +#### Exporting + +1. Click **File → Export** +2. Choose format (SVG, PNG, etc.) +3. Configure options +4. Click **Export** + +--- + +### Learning Resources + +**Official Resources:** +- [Wiki](https://github.com/Azgaar/Fantasy-Map-Generator/wiki) - Comprehensive guides +- [YouTube Channel](https://www.youtube.com/channel/UCb0_JfUg6t2k_dYuLBrGg_g) - Video tutorials +- [Blog](https://azgaar.wordpress.com) - Articles and tips + +**Community:** +- [Discord](https://discordapp.com/invite/X7E84HU) - Live chat and support +- [Reddit](https://www.reddit.com/r/FantasyMapGenerator) - Share maps and discuss + +**Examples:** +- [Gallery](https://www.reddit.com/r/FantasyMapGenerator/search?q=flair%3AShowcase&restrict_sr=1) - Community maps for inspiration + +--- + +## For Developers + +### Setting Up Development Environment + +#### Prerequisites + +- **Git** - Version control +- **Modern Browser** - Chrome/Firefox with DevTools +- **Text Editor** - VS Code, Sublime, Atom, etc. +- **Optional**: Node.js (for local server) + +#### Clone the Repository + +```bash +git clone https://github.com/Azgaar/Fantasy-Map-Generator.git +cd Fantasy-Map-Generator +``` + +#### Run Locally + +**Option 1: Python Server** + +```bash +# Python 3 +python -m http.server 8080 + +# Python 2 +python -m SimpleHTTPServer 8080 +``` + +**Option 2: Node.js Server** + +```bash +npx http-server -p 8080 +``` + +**Option 3: VS Code Live Server** + +1. Install "Live Server" extension +2. Right-click `index.html` +3. Select "Open with Live Server" + +**Option 4: Direct File Access** + +Open `index.html` directly in browser (some features may not work due to CORS). + +#### Access the Application + +Open your browser and navigate to: +``` +http://localhost:8080 +``` + +--- + +### Project Structure + +``` +Fantasy-Map-Generator/ +├── index.html # Main HTML file +├── index.css # Main stylesheet +├── main.js # Core application logic +├── versioning.js # Map version migration +├── modules/ # Feature modules +│ ├── heightmap-generator.js +│ ├── river-generator.js +│ ├── cultures-generator.js +│ ├── burgs-and-states.js +│ ├── religions-generator.js +│ ├── routes-generator.js +│ ├── military-generator.js +│ ├── markers-generator.js +│ ├── names-generator.js +│ ├── coa-generator.js +│ ├── coa-renderer.js +│ ├── biomes.js +│ ├── lakes.js +│ ├── voronoi.js +│ ├── fonts.js +│ ├── relief-icons.js +│ ├── ocean-layers.js +│ ├── io/ # Save/load/export +│ ├── ui/ # 41+ editor dialogs +│ ├── renderers/ # Visualization +│ └── dynamic/ # On-demand utilities +├── libs/ # Third-party libraries +│ ├── d3.min.js +│ ├── delaunator.min.js +│ ├── jquery.min.js +│ └── jquery-ui.min.js +├── utils/ # Utility functions +├── config/ # Configuration files +├── styles/ # Additional stylesheets +├── images/ # Image assets +├── charges/ # Heraldic charges (200+) +└── heightmaps/ # Template heightmaps +``` + +--- + +### Making Your First Change + +#### Example: Changing Default Sea Level + +**File:** `modules/heightmap-generator.js` + +**Find:** +```javascript +const seaLevel = 20; // Default sea level +``` + +**Change to:** +```javascript +const seaLevel = 25; // Raised sea level +``` + +**Save and reload** - Sea level is now higher. + +--- + +### Development Workflow + +#### 1. Create a Branch + +```bash +git checkout -b feature/my-feature +``` + +#### 2. Make Changes + +Edit files in your preferred editor. + +#### 3. Test Changes + +- Reload the browser +- Test affected features +- Check browser console for errors + +#### 4. Commit Changes + +```bash +git add . +git commit -m "Add description of changes" +``` + +#### 5. Push Branch + +```bash +git push origin feature/my-feature +``` + +#### 6. Create Pull Request + +1. Go to GitHub repository +2. Click "Pull Requests" +3. Click "New Pull Request" +4. Select your branch +5. Describe changes +6. Submit + +--- + +### Code Style Guidelines + +#### JavaScript Style + +**Use strict mode:** +```javascript +"use strict"; +``` + +**Module pattern:** +```javascript +window.MyModule = (function() { + // Private + function privateFunction() {} + + // Public + function publicFunction() {} + + return { publicFunction }; +})(); +``` + +**Naming conventions:** +- Variables: `camelCase` +- Constants: `UPPER_SNAKE_CASE` +- Functions: `camelCase` +- Modules: `PascalCase` + +**Comments:** +```javascript +// Single-line for brief explanations + +/* Multi-line for + longer explanations */ +``` + +#### Formatting + +- **Indentation**: 2 spaces (no tabs) +- **Semicolons**: Use them +- **Quotes**: Prefer double quotes +- **Line length**: ~100 characters + +#### Best Practices + +1. **No global pollution** - Use modules +2. **Use typed arrays** for cell data +3. **Cache DOM selections** - Don't query repeatedly +4. **Minimize D3 updates** - Batch when possible +5. **Comment complex logic** - Help future maintainers + +--- + +### Understanding the Codebase + +#### Key Concepts + +**1. Global State** + +```javascript +grid // Voronoi diagram + terrain +pack // Civilizations + derived data +seed // Random seed +``` + +All modules access these globals. + +**2. Generation Pipeline** + +```javascript +generateGrid() +→ generateHeightmap() +→ markFeatures() +→ calculateClimate() +→ generateRivers() +→ defineBiomes() +→ generateCultures() +→ generateStates() +→ render() +``` + +Each step builds on the previous. + +**3. Data Structures** + +Heavily uses typed arrays: +```javascript +pack.cells.h = new Uint8Array(n); // Heights +pack.cells.s = new Uint16Array(n); // State IDs +``` + +See [Data Model](Data-Model.md) for details. + +**4. Rendering** + +Uses D3.js for SVG manipulation: +```javascript +d3.select('#states').selectAll('path') + .data(pack.states) + .enter().append('path') + .attr('d', drawStatePath) + .attr('fill', d => d.color); +``` + +--- + +### Debugging Tips + +#### Browser DevTools + +**Console:** +- View errors and warnings +- Log values: `console.log(grid)` +- Inspect objects: `console.dir(pack.states[0])` + +**Debugger:** +- Set breakpoints in sources +- Step through code +- Inspect variables + +**Performance:** +- Profile generation +- Identify slow functions +- Monitor memory usage + +#### Common Issues + +**Problem: Changes not appearing** +- Hard refresh (Ctrl+Shift+R) +- Clear browser cache +- Check console for errors + +**Problem: Map not generating** +- Check console for errors +- Verify module loading order +- Test with lower cell count + +**Problem: Performance issues** +- Reduce cell count +- Profile in DevTools +- Check for infinite loops + +--- + +### Testing + +Currently, the project lacks automated tests. Manual testing is required: + +#### Test Checklist + +- [ ] Map generates successfully +- [ ] All layers render correctly +- [ ] Editors open without errors +- [ ] Changes persist after save/load +- [ ] Export formats work +- [ ] No console errors + +#### Test Different Scenarios + +- Different templates +- Different cell counts +- Edge cases (very high/low values) +- Browser compatibility + +--- + +## Quick Start Tutorial + +### Tutorial: Adding a Custom Biome + +This tutorial shows how to add a new biome type called "Jungle". + +**Step 1: Define Biome Data** + +Edit `modules/biomes.js`: + +```javascript +// Add to biomesData.i array +14 // New ID for Jungle + +// Add to biomesData.name array +"Jungle" + +// Add to biomesData.color array +"#2d5016" // Dark green + +// Add to biomesData.habitability array +50 // Medium habitability + +// Add to other arrays... +``` + +**Step 2: Update Biome Matrix** + +Add logic to assign "Jungle" biome: + +```javascript +// In high temp + high precipitation +if (temp > 80 && prec > 200) { + return 14; // Jungle +} +``` + +**Step 3: Test** + +1. Reload the application +2. Generate a new map +3. Look for jungle biomes in hot, wet regions +4. Check if rendering works correctly + +**Step 4: Add Icons (Optional)** + +Add jungle-specific relief icons in `modules/relief-icons.js`. + +**Congratulations!** You've added a custom biome. + +--- + +### Tutorial: Creating a Simple Editor + +This tutorial shows how to create a basic editor dialog. + +**Step 1: Create Editor File** + +Create `modules/ui/my-editor.js`: + +```javascript +"use strict"; + +function editMyFeature() { + // Create dialog + $("#myEditor").dialog({ + title: "My Feature Editor", + width: 400, + height: 300, + buttons: { + Apply: applyChanges, + Close: function() { $(this).dialog("close"); } + } + }); + + function applyChanges() { + // Implement your logic + const value = $("#myInput").val(); + console.log("Applied:", value); + } +} +``` + +**Step 2: Add HTML Dialog** + +In `index.html`, add: + +```html +