settlemaker 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +162 -277
  2. package/dist/output/geojson-builder.d.ts +1 -1
  3. package/dist/output/geojson-builder.js +1 -1
  4. package/dist/settlemaker.browser.js +1 -1
  5. package/docs/README.md +54 -0
  6. package/docs/api.md +175 -0
  7. package/docs/artwork-integration.md +104 -0
  8. package/docs/current-symbol-library.md +62 -42
  9. package/docs/development.md +102 -0
  10. package/docs/examples/gallery/coastal-city.png +0 -0
  11. package/docs/examples/gallery/coastal-city.svg +4253 -0
  12. package/docs/examples/gallery/coastal-village.png +0 -0
  13. package/docs/examples/gallery/coastal-village.svg +1211 -0
  14. package/docs/examples/gallery/copperline-city.png +0 -0
  15. package/docs/examples/gallery/copperline-city.svg +1139 -0
  16. package/docs/examples/gallery/copperline-village.png +0 -0
  17. package/docs/examples/gallery/copperline-village.svg +2382 -0
  18. package/docs/examples/gallery/desert-city.png +0 -0
  19. package/docs/examples/gallery/desert-city.svg +3509 -0
  20. package/docs/examples/gallery/desert-village.png +0 -0
  21. package/docs/examples/gallery/desert-village.svg +455 -0
  22. package/docs/examples/gallery/fixtures.json +449 -0
  23. package/docs/examples/gallery/temperate-city-night.png +0 -0
  24. package/docs/examples/gallery/temperate-city-night.svg +3511 -0
  25. package/docs/examples/gallery/temperate-city.png +0 -0
  26. package/docs/examples/gallery/temperate-city.svg +3511 -0
  27. package/docs/examples/gallery/temperate-village.png +0 -0
  28. package/docs/examples/gallery/temperate-village.svg +3227 -0
  29. package/docs/examples/gallery/tropical-city.png +0 -0
  30. package/docs/examples/gallery/tropical-city.svg +3508 -0
  31. package/docs/examples/gallery/tropical-village.png +0 -0
  32. package/docs/examples/gallery/tropical-village.svg +3761 -0
  33. package/docs/examples/gallery/tundra-city.png +0 -0
  34. package/docs/examples/gallery/tundra-city.svg +3509 -0
  35. package/docs/examples/gallery/tundra-village.png +0 -0
  36. package/docs/examples/gallery/tundra-village.svg +1549 -0
  37. package/docs/fmg-embed-zoom.md +54 -0
  38. package/docs/gallery.md +139 -0
  39. package/docs/geojson.md +188 -0
  40. package/docs/getting-started.md +157 -0
  41. package/docs/landscape-character-review.md +55 -0
  42. package/docs/releases/3.0.1.md +18 -0
  43. package/docs/scene-schema.md +160 -0
  44. package/docs/schema-v3.md +38 -0
  45. package/docs/skins.md +52 -0
  46. package/docs/test-urls.md +39 -0
  47. package/docs/url-api.md +252 -0
  48. package/docs/water-context-v1.md +384 -0
  49. package/package.json +15 -8
  50. package/scripts/check-docs.mjs +106 -0
  51. package/scripts/generate-copperline.mjs +255 -0
  52. package/scripts/generate-examples.mjs +54 -0
  53. package/scripts/render-copperline.mjs +36 -0
  54. package/src/output/geojson-builder.ts +1 -1
  55. package/symbols/copperline/README.md +10 -3
package/README.md CHANGED
@@ -1,322 +1,207 @@
1
- # Settlemaker
1
+ # SettleMaker
2
2
 
3
- A medieval fantasy settlement map generator for Node.js. TypeScript reimplementation of [watabou's Medieval Fantasy City Generator](https://watabou.itch.io/medieval-fantasy-city-generator).
3
+ **Generate settlement maps. Bring your own world.**
4
4
 
5
- <p align="center">
6
- <img src="docs/examples/hamlet.png" width="200" alt="Hamlet"/>
7
- <img src="docs/examples/town.png" width="200" alt="Walled town"/>
8
- <img src="docs/examples/city.png" width="200" alt="Large city"/>
9
- <img src="docs/examples/port.png" width="200" alt="Port city"/>
10
- </p>
11
- <p align="center">
12
- <img src="docs/examples/route-character.png" width="266" alt="Route character — growth follows the through road, the trail stays bare"/>
13
- <img src="docs/examples/core-capacity.png" width="266" alt="coreCapacity — compact walled old town inside a sprawling metropolis"/>
14
- <img src="docs/examples/coastal-full.png" width="266" alt="Coastal — wall along the water's edge, harbour gate, piers"/>
15
- </p>
16
- <p align="center">
17
- <img src="docs/examples/town-blueprint.png" width="266" alt="Same town, blueprint theme"/>
18
- <img src="docs/examples/town-night.png" width="266" alt="Same town, night theme"/>
19
- <img src="docs/examples/town-colour.png" width="266" alt="Same town, colour theme"/>
20
- </p>
21
- <p align="center"><sub>Hamlet · walled town · city · port — the contract showcases (route-driven growth, walled-core capacity, full coastal) — and the same walled town in <code>blueprint</code>, <code>night</code>, and <code>colour</code> themes: identical layout, only colors change. Every image regenerates from <a href="docs/test-urls.md">documented example URLs</a> via <code>scripts/generate-examples.ts</code>.</sub></p>
5
+ SettleMaker is a procedural map engine for Node.js and browsers. Give it a
6
+ settlement's population, roads, terrain and seed; get an SVG map, local GeoJSON
7
+ and a model you can inspect. It draws small villages and large cities through
8
+ separate planners, with shared input and output entry points.
22
9
 
23
- ## Features
10
+ The bundled artwork depicts medieval settlements. Portable **skins** can replace
11
+ buildings, vegetation, field textures and material colours for your own setting,
12
+ without forking the engine. Copperline includes industrial, steampunk and modern
13
+ examples. The city generator builds on
14
+ [watabou's TownGeneratorOS](https://github.com/watabou/TownGeneratorOS).
24
15
 
25
- - **Procedural settlement generation** from hamlets (pop 10) to metropolises (pop 200k+)
26
- - **Deterministic output** — same seed always produces identical results
27
- - **Lightweight runtime** — built-in Voronoi, A\*, and PRNG algorithms; polygon-clipping handles water polygon operations
28
- - **SVG and GeoJSON output** — render to vector graphics or geospatial features
29
- - **Tile-ready** — built-in SVG-to-tile slicing for map integration
30
- - **8 colour palettes** — default, blueprint, black & white, ink, night, ancient, colour, simple
31
-
32
- ### Settlement features
16
+ <p align="center">
17
+ <a href="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/temperate-village.svg"><img src="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/temperate-village.png" width="420" alt="Ashford: a generated temperate village with individual homes, roads and fields" /></a>
18
+ <a href="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/temperate-city.svg"><img src="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/temperate-city.png" width="420" alt="Thornwall: a generated walled city using the current city artwork" /></a>
19
+ </p>
33
20
 
34
- - Walled cities with towers and gates
35
- - Citadels, castles, markets, temples, parks
36
- - Ward types: craftsmen, merchants, patriciate, slums, administration, military
37
- - Road networks connecting gates to the city center
38
- - **Farmlands** with strip fields, furrows, and farmstead buildings
39
- - **Harbour/dock wards** with warehouses and piers for port cities
40
- - Farm belts hug the built edge; growth outside the walls follows route quality and terrain
21
+ Ashford, population 300, and Thornwall, population 10,000. Both are real
22
+ `generateSettlement` outputs, seed 2. Click an image for the full SVG.
23
+ [Explore the gallery and exact inputs](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/gallery.md).
41
24
 
42
- ## Installation
25
+ ## Install and generate a map
43
26
 
44
- ```bash
27
+ ```sh
45
28
  npm install settlemaker
46
29
  ```
47
30
 
48
- Version 3.0.0 is an ES module package. Use `import` in an ES module project
49
- (with `"type": "module"` in your package.json), or use `await import('settlemaker')`
50
- from CommonJS. TypeScript declarations and their GeoJSON types are included.
51
- The bundled browser entry is `settlemaker/dist/settlemaker.browser.js`.
52
-
53
- See the [3.0.0 release notes](docs/releases/3.0.0.md) for skin support and packaging
54
- changes. The npm package includes TypeScript source, source maps, build inputs,
55
- and artwork attribution. From a source checkout, `npm ci` followed by `npm pack`
56
- cleans the generated output and builds both library formats before packaging.
57
-
58
- ## Quick start
31
+ The package uses **ES modules** and includes TypeScript declarations. Save this
32
+ as `generate.mjs` and run `node generate.mjs`:
59
33
 
60
- ```typescript
61
- import { generateFromBurg } from 'settlemaker';
34
+ ```js
35
+ import { writeFile } from 'node:fs/promises';
36
+ import { generateSettlement } from 'settlemaker';
62
37
 
63
- const result = generateFromBurg({
64
- name: 'Thornwall',
65
- population: 5000,
38
+ const burg = {
39
+ name: 'Ashford',
40
+ population: 300,
41
+ biome: 'temperate',
66
42
  port: false,
67
- citadel: true,
68
- walls: true,
43
+ citadel: false,
44
+ walls: false,
69
45
  plaza: true,
70
46
  temple: true,
71
47
  shanty: false,
72
48
  capital: false,
73
- });
74
-
75
- // result.svg — SVG string
76
- // result.geojson — GeoJSON FeatureCollection
77
- // result.model — raw Model for further inspection
49
+ roadBearings: [
50
+ { bearing_deg: 18, kind: 'main', route_id: 'north-road' },
51
+ { bearing_deg: 142, kind: 'town', route_id: 'south-road' },
52
+ { bearing_deg: 267, kind: 'local', route_id: 'west-road' },
53
+ ],
54
+ };
55
+
56
+ const result = generateSettlement(burg, { seed: 2 });
57
+ await writeFile('ashford.svg', result.svg);
58
+ await writeFile('ashford.geojson', JSON.stringify(result.geojson, null, 2));
59
+ console.log(result.kind); // 'village'
78
60
  ```
79
61
 
80
- ### With a custom seed
62
+ For a city, change `population` to a value above 1,000. `walls`, `citadel`,
63
+ `plaza` and `temple` describe requested features; their treatment depends on the
64
+ planner and available geometry. Use `generateSettlement` as your normal entry
65
+ point. `generateFromBurg` explicitly invokes the city planner, even for a small
66
+ population.
81
67
 
82
- ```typescript
83
- const result = generateFromBurg(burg, { seed: 42 });
84
- ```
68
+ CommonJS callers can use `await import('settlemaker')` inside an async function.
69
+ In a browser app, import from `settlemaker` through your bundler, or serve the
70
+ standalone ESM file `node_modules/settlemaker/dist/settlemaker.browser.js` yourself.
71
+ The engine needs no rendering service or runtime artwork downloads.
85
72
 
86
- ### Villages
73
+ [Node, browser and TypeScript setup](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/getting-started.md)
87
74
 
88
- Settlements of 1,000 people or fewer are drawn by a separate engine — roads
89
- first, then the buildings that line them — rather than by the city pipeline.
90
- `generateSettlement` picks the engine from the population and tells you which
91
- one ran:
75
+ ## What the engine produces
92
76
 
93
- ```typescript
94
- import { generateSettlement } from 'settlemaker';
77
+ | Output | What you can use it for |
78
+ | --- | --- |
79
+ | `svg` | A complete vector map with embedded artwork; display, save or rasterize it. |
80
+ | `geojson` | Buildings, streets, water and engine-specific features in **local coordinates**, with version and scale metadata. These are not longitude/latitude coordinates. |
81
+ | `model` | The generated `VillageModel` or city `Model`, selected by `result.kind`. |
82
+ | `degradedFlags` | City requests such as walls or citadel that generation had to drop. The village branch returns an empty array. |
83
+ | `originShift` | The city's optional coastal output translation; zero for villages. |
84
+ | `waterContextResult` | Diagnostics when using the supported measured village-water contract. |
95
85
 
96
- const result = generateSettlement({ name: 'Ashford', population: 400, /* ... */ });
86
+ At population **1–1,000**, the village planner builds roads, lots, dwellings,
87
+ greens and landscape in metres. Above **1,000**, the city planner builds wards,
88
+ streets, lots, fortifications and outskirts in its own local units. Both return
89
+ SVG and GeoJSON, but their feature sets, IDs and model types differ.
97
90
 
98
- if (result.kind === 'village') {
99
- result.svg; // village SVG
100
- result.geojson; // village GeoJSON
101
- result.model; // VillageModel
102
- } else {
103
- result.model; // Model, as generateFromBurg returns
104
- }
105
- ```
91
+ Layouts and SVGs are repeatable for the same inputs, seed, rendering options and
92
+ package version. GeoJSON includes a changing `generated_at` timestamp. Save the
93
+ input, seed, package version and any skin alongside output you want to reproduce.
106
94
 
107
- The boundary is `VILLAGE_POP_CEILING` (1,000), inclusive. Both branches emit an
108
- SVG and a GeoJSON carrying the same `schema_version` and `settlemaker_version`
109
- metadata, so a consumer can treat the two uniformly.
95
+ [API and input reference](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/api.md)
96
+ · [GeoJSON, scale and identity](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/geojson.md)
110
97
 
111
- Village-only options go under `village`, settlement-only options under `svg` and
112
- `geojson`; the compiler rejects an option the chosen engine cannot honour rather
113
- than dropping it silently.
98
+ ## Biomes, roads and water
114
99
 
115
- ```typescript
116
- generateSettlement(burg, { village: { theme: villageThemeFor('desert') } });
117
- ```
100
+ The default artwork covers **temperate, desert, tundra, tropical and coastal**
101
+ settlements. These select different buildings, vegetation and landscape rules;
102
+ changing a biome can change the generated layout. A coastal artwork choice alone
103
+ does not supply a shoreline: provide water geometry or `oceanBearing`.
118
104
 
119
- Village roads use existing frontage before adding streets. Small settlements can
120
- stay as a green and a short access lane; larger ones add streets only when they
121
- provide useful housing capacity. Regional approaches retain their bearings and inbound classes, then join
122
- town, local or footpath streets inside villages. Small roadside hamlets can
123
- retain a major through road. FMG supplies each measured approach explicitly;
124
- `through` does not invent an exit. Local surfaces, reserved corridors and parcel setbacks are distinct
125
- ([width semantics](docs/schema-v3.md#village-road-cross-sections)).
126
-
127
- Run `npm run review:roads` to generate the local road gallery. The
128
- [road design report](docs/plans/2026-09-10-village-road-results.md) includes commands
129
- for matched historical comparisons, held-out seeds and validation results. The
130
- [follow-up review](docs/plans/2026-09-10-village-followup.md) covers road-shaped greens,
131
- landmark locations, junction transitions and the expanded landscape panel. The
132
- [route layout review](docs/plans/2026-09-10-village-route-layout.md) covers the
133
- shared street network, updated FMG contract and varied multi-approach gallery.
134
- The [water and roofs review](docs/plans/2026-09-10-village-water-roofs.md)
135
- covers dry road approaches, timber bridges and native tundra dwellings.
136
-
137
- Villages are themed by biome — `villageThemeFor(biome)` selects the ground,
138
- vegetation and dwelling glyphs. The review gallery includes desert and tundra
139
- examples, with native snowy dwelling artwork for tundra villages.
140
-
141
- Both engines now use the expanded [2.7.0 biome artwork](docs/releases/2.7.0.md) by default: rural and city
142
- buildings, religious and defensive forms, flora, fields, walls, bridges and
143
- henges. Run `npm run review:art` for a gallery generated through the public API.
144
- See [artwork integration](docs/artwork-integration.md) for selection rules,
145
- placement contracts and asset regeneration.
146
-
147
- See the [2.6.0 release notes](docs/releases/2.6.0.md) for measured village water,
148
- river meanders, temple henges and woodland. The [water-context v1 contract](docs/water-context-v1.md)
149
- defines the coordinated FMG rollout.
150
-
151
- See the [2.5.0 release notes](docs/releases/2.5.0.md) for city layouts, capacity
152
- accounting and the settlemaker-web submodule update.
153
-
154
- ### Port cities
155
-
156
- ```typescript
157
- const result = generateFromBurg({
158
- name: 'Harborton',
159
- population: 12000,
160
- port: true,
161
- citadel: true,
162
- walls: true,
163
- plaza: true,
164
- temple: true,
165
- shanty: false,
166
- capital: false,
167
- oceanBearing: 180, // ocean to the south
168
- harbourSize: 'large', // large harbour with more piers
169
- roadBearings: [0, 90, 270], // roads from N, E, W
170
- });
171
- ```
105
+ <p align="center">
106
+ <img src="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/desert-village.png" width="280" alt="Qasra: desert village with native buildings and field textures" />
107
+ <img src="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/tundra-village.png" width="280" alt="Snowmere: tundra village with snowy roofs and natural ground" />
108
+ <img src="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/tropical-village.png" width="280" alt="Reedbank: tropical village beside a supplied river" />
109
+ </p>
172
110
 
173
- ### Custom palettes
111
+ Supply every real road approach independently, using clockwise bearings from
112
+ north. `through: true` describes a continuing route; it does not create an
113
+ opposite exit. Use route IDs to retain provenance through shared streets and city
114
+ gates.
174
115
 
175
- ```typescript
176
- import { generateFromBurg, PALETTES } from 'settlemaker';
116
+ Water can come from filled polygons, village river centrelines, or a generated
117
+ coast from `oceanBearing`. The measured `waterContext` contract is supported only
118
+ by the village planner. Cities reject that mode; their legacy polygon input uses
119
+ city-local units. `port` requests infrastructure, rather than controlling whether
120
+ water is visible.
177
121
 
178
- const result = generateFromBurg(burg, {
179
- svg: { palette: PALETTES.night },
180
- });
181
- ```
122
+ [Road and water inputs](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/api.md#roads)
123
+ · [Measured-water contract](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/water-context-v1.md)
182
124
 
183
- Available palettes: `default`, `blueprint`, `bw`, `ink`, `night`, `ancient`, `colour`, `simple`.
125
+ ## Make it your own
184
126
 
185
- ### Custom skins
127
+ A skin is a JSON document loaded with `createSkin`. It can replace exact SVG
128
+ slots, set material tokens and define named biomes that inherit existing terrain
129
+ behaviour. Partial skins inherit any artwork they omit.
186
130
 
187
- Use one portable skin for village and city artwork, material colours, and named
188
- biomes. Partial skins inherit any artwork they omit:
131
+ Using `burg` from the first example:
189
132
 
190
- ```typescript
191
- import { createSkin, generateSettlement } from 'settlemaker';
133
+ ```js
134
+ import { createSkin } from 'settlemaker';
192
135
 
193
136
  const skin = createSkin({
194
- version: 1, id: 'moon-glass', name: 'Moon Glass',
137
+ version: 1,
138
+ id: 'moon-glass',
139
+ name: 'Moon Glass',
195
140
  tokens: { '--sm-stone': '#badcea' },
196
- biomes: { lunar: { base: 'tundra', village: { ground: '#68748c' }, city: { paper: '#68748c' } } },
141
+ biomes: {
142
+ lunar: {
143
+ base: 'tundra',
144
+ village: { ground: '#68748c' },
145
+ city: { paper: '#68748c' },
146
+ },
147
+ },
197
148
  });
198
- const result = generateSettlement({ ...burg, biome: 'lunar' }, { seed: 42, skin });
199
- ```
200
-
201
- See the [skin authoring specification](docs/skins.md),
202
- [JSON Schema](docs/skins.schema.json), and [working example](docs/examples/moon-glass.skin.json)
203
- for SVG replacements, placement constraints, and loading skins from JSON.
204
-
205
- For advanced technology, [Copperline](symbols/copperline/README.md) supplies 693 runtime SVG
206
- slot replacements with `industrial`, `steampunk`, and `modern` material presets:
207
- factories, rooftop machinery, solar arrays, and utility infrastructure.
208
- Browse the [artwork sheet](symbols/copperline/preview.svg) or load the
209
- [skin JSON](docs/examples/copperline.skin.json) with `createSkin`.
210
-
211
- ## Lower-level API
212
-
213
- For full control over the generation pipeline:
214
149
 
215
- ```typescript
216
- import { GenerationParams, Model, generateSvg, generateGeoJson } from 'settlemaker';
217
-
218
- const params = new GenerationParams({
219
- seed: 42,
220
- nPatches: 15,
221
- plazaNeeded: true,
222
- citadelNeeded: true,
223
- wallsNeeded: true,
224
- });
225
-
226
- const model = new Model(params).generate();
227
- const svg = generateSvg(model);
228
- const geojson = generateGeoJson(model);
229
- ```
230
-
231
- ## Input mapping
232
-
233
- The `AzgaarBurgInput` interface maps from [Azgaar's Fantasy Map Generator](https://azgaar.github.io/Fantasy-Map-Generator/) burg data:
234
-
235
- | Field | Type | Description |
236
- |-------|------|-------------|
237
- | `name` | `string` | Settlement name |
238
- | `population` | `number` | Population count (drives patch count and ward distribution) |
239
- | `port` | `boolean` | Is this a port settlement? |
240
- | `citadel` | `boolean` | Has a citadel/castle |
241
- | `walls` | `boolean` | Has defensive walls |
242
- | `plaza` | `boolean` | Has a central plaza/market |
243
- | `temple` | `boolean` | Has a temple/cathedral |
244
- | `shanty` | `boolean` | Has shanty town areas |
245
- | `capital` | `boolean` | Is a regional capital |
246
- | `culture` | `string?` | Culture name (future use) |
247
- | `biome` | `string?` | Biome name. Azgaar's own vocabulary is accepted and normalised (`hot desert` → desert, `taiga` → tundra, …). In a village this is **data, not styling**: it picks the ground, the dwellings, the field and canopy decks and the plot edges. To change only the look, pass a `VillageTheme` — see [Villages](#villages) |
248
- | `roadBearings` | `number[]?` | Compass bearings of approaching roads |
249
- | `oceanBearing` | `number?` | Bearing to nearest ocean. Enables a coastline; in a village it synthesises one with bays and headlands, standing off the settlement |
250
- | `harbourSize` | `'large' \| 'small'?` | Harbour scale for port cities |
251
-
252
- Population determines settlement size. The patch counts below describe the
253
- city pipeline; at 1,000 and under, `generateSettlement` uses the village
254
- engine instead, which does not work in patches (see [Villages](#villages)):
255
-
256
- | Population | Type | Patches |
257
- |-----------|------|---------|
258
- | < 100 | Hamlet | 3-4 |
259
- | 100 - 1,000 | Village | 5-9 |
260
- | 1,000 - 5,000 | Town | 10-15 |
261
- | 5,000 - 20,000 | City | 16-25 |
262
- | 20,000 - 100,000 | Large city | 26-36 |
263
- | > 100,000 | Metropolis | 36+ |
264
-
265
- ## Architecture
266
-
267
- Three-layer pipeline:
268
-
269
- 1. **Input mapping** — `AzgaarBurgInput` to `GenerationParams`
270
- 2. **Generation core** — 6-phase pipeline:
271
- - Build Voronoi patches
272
- - Optimize junctions
273
- - Build walls
274
- - Classify water + place harbour
275
- - Build streets (A\* pathfinding)
276
- - Create wards + build geometry (farmlands, buildings, alleys)
277
- 3. **Output rendering** — SVG string builder, GeoJSON feature builder, tile slicer
278
-
279
- All geometry algorithms (Voronoi via Bowyer-Watson, polygon cutting, oriented bounding box, PRNG) are implemented from scratch with no external dependencies.
280
-
281
- ## Development
282
-
283
- Requires [Nix](https://nixos.org/) with flakes:
284
-
285
- ```bash
286
- nix develop
287
-
288
- # Run tests
289
- npx vitest run
290
-
291
- # Run smoke test
292
- npx tsx smoke-test.ts
293
-
294
- # Type check
295
- npx tsc --noEmit
150
+ const moonVillage = generateSettlement(
151
+ { ...burg, biome: 'lunar' },
152
+ { seed: 2, skin },
153
+ );
154
+ await writeFile('moon-village.svg', moonVillage.svg);
296
155
  ```
297
156
 
298
- ## License
157
+ For artwork replacement, `SKIN_SLOTS` supplies the supported IDs, view boxes,
158
+ anchors and placement constraints. Skin format 1 exposes **693 runtime slots**.
159
+ The downloadable default artwork contains **852 drawings**; catalogue drawings
160
+ and runtime slots serve different purposes.
299
161
 
300
- **GPL-3.0-only** (`SPDX-License-Identifier: GPL-3.0-only`). Full text in [LICENSE](LICENSE);
301
- attribution and provenance in [NOTICE](NOTICE).
302
-
303
- settlemaker is a derivative work of [watabou's TownGeneratorOS](https://github.com/watabou/TownGeneratorOS),
304
- which is GPL-3.0. Upstream grants no "or any later version" option, so settlemaker is
305
- GPL-3.0-**only**, not `-or-later`.
306
-
307
- settlemaker.com is built from the private settlemaker-web repo, which pins
308
- this repo as a submodule and serves the library to browsers as a standalone
309
- GPL artifact (`/lib/settlemaker.js`, built by `npm run build:lib`). This
310
- repository is the library: generation core, symbols, tests, and tooling.
311
-
312
- Two things are *not* covered by that license:
162
+ <p align="center">
163
+ <a href="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/copperline-village.svg"><img src="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/copperline-village.png" width="420" alt="Copperline industrial artwork applied to the village engine" /></a>
164
+ <a href="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/copperline-city.svg"><img src="https://raw.githubusercontent.com/barrulus/settlemaker/v3.0.1/docs/examples/gallery/copperline-city.png" width="420" alt="Copperline steampunk artwork applied to the city engine" /></a>
165
+ </p>
313
166
 
314
- - **The SVG symbol library** (`symbols/`) is original artwork under
315
- [**CC BY 4.0 with a rendered-output exception**](symbols/LICENSE). **Maps you
316
- render with the symbols are yours and owe nothing** — no credit, no notice. Attribution
317
- applies only if you redistribute the *library itself* (the SVGs, the sprite, or a set
318
- derived from them), in which case credit the authors in
319
- [CREDITS](symbols/CREDITS). Contributions are accepted on those terms.
320
- - **[Azgaar's Fantasy Map Generator](https://github.com/Azgaar/Fantasy-Map-Generator)** (MIT)
321
- consumes settlemaker at arm's length over the [URL API](docs/url-api.md). Separate programs
322
- exchanging data, not a combined work — neither license reaches into the other.
167
+ Copperline covers all runtime slots and supplies `industrial`, `steampunk` and
168
+ `modern` presets. Skins change presentation and select an existing biome base;
169
+ they do not add new planning algorithms, occupancy rules or GeoJSON categories.
170
+ Some roads, walls and bridges are generated geometry rather than replaceable SVG
171
+ slots. Read the authoring guide for the supported controls and limits.
172
+
173
+ [Create a skin](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/skins.md)
174
+ · [JSON schema](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/skins.schema.json)
175
+ · [Copperline](https://github.com/barrulus/settlemaker/blob/v3.0.1/symbols/copperline/README.md)
176
+ · [Artwork catalogue](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/current-symbol-library.md)
177
+
178
+ ## Choose your integration
179
+
180
+ | Task | Guide |
181
+ | --- | --- |
182
+ | Generate and save maps in Node or a browser app | [Getting started](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/getting-started.md) |
183
+ | Understand every input and rendering option | [Library API](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/api.md) |
184
+ | Join features, place output on a map or crop tiles | [GeoJSON and coordinates](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/geojson.md) |
185
+ | Embed the separately hosted renderer in an iframe | [URL adapter contract](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/url-api.md) |
186
+ | Render an existing city scene | [Scene and rendering contract](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/scene-schema.md) |
187
+ | Draw a complete alternative setting | [Skin authoring](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/skins.md) |
188
+ | Build, test or regenerate documentation | [Development](https://github.com/barrulus/settlemaker/blob/v3.0.1/docs/development.md) |
189
+
190
+ The npm library runs in your application. The website at
191
+ [settlemaker.com](https://settlemaker.com) is a separate application with its own
192
+ deployment cycle. Publishing an npm release does not update that site. The URL
193
+ codec does not transport skins or fetch arbitrary skin files.
194
+
195
+ ## License and attribution
196
+
197
+ The engine is **GPL-3.0-only**. See
198
+ [LICENSE](https://github.com/barrulus/settlemaker/blob/v3.0.1/LICENSE) and
199
+ [NOTICE](https://github.com/barrulus/settlemaker/blob/v3.0.1/NOTICE) for the terms,
200
+ upstream attribution and dependency notices.
201
+
202
+ The six default artwork collections are distributed under **CC BY 4.0 with a
203
+ rendered-output exception**, described in
204
+ [symbols/LICENSE](https://github.com/barrulus/settlemaker/blob/v3.0.1/symbols/LICENSE).
205
+ Their [credits](https://github.com/barrulus/settlemaker/blob/v3.0.1/symbols/CREDITS)
206
+ ship with the package. **Copperline is GPL-3.0-only** and is outside that artwork
207
+ exception. Keep each collection's terms with redistributed artwork.
@@ -10,7 +10,7 @@ export declare const GEOJSON_SCHEMA_VERSION = 4;
10
10
  * Source-of-truth library version. Kept in sync with package.json manually —
11
11
  * cheaper than a JSON import assertion and lets tests pin a deterministic value.
12
12
  */
13
- export declare const SETTLEMAKER_VERSION = "3.0.0";
13
+ export declare const SETTLEMAKER_VERSION = "3.0.1";
14
14
  export interface GenerateGeoJsonOptions {
15
15
  /** ISO-8601 timestamp to stamp on the output. Defaults to `new Date().toISOString()`. */
16
16
  generatedAt?: string;
@@ -17,7 +17,7 @@ export const GEOJSON_SCHEMA_VERSION = 4;
17
17
  * Source-of-truth library version. Kept in sync with package.json manually —
18
18
  * cheaper than a JSON import assertion and lets tests pin a deterministic value.
19
19
  */
20
- export const SETTLEMAKER_VERSION = '3.0.0';
20
+ export const SETTLEMAKER_VERSION = '3.0.1';
21
21
  /**
22
22
  * Convert a generated Model to a GeoJSON FeatureCollection.
23
23
  *