@edv4h/usketch-plugin-map 0.6.0 → 0.8.0

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 (43) hide show
  1. package/README.md +34 -0
  2. package/dist/autotile.d.ts +22 -0
  3. package/dist/autotile.d.ts.map +1 -1
  4. package/dist/autotile.js +46 -0
  5. package/dist/autotile.js.map +1 -1
  6. package/dist/base-terrain.d.ts +58 -0
  7. package/dist/base-terrain.d.ts.map +1 -0
  8. package/dist/base-terrain.js +107 -0
  9. package/dist/base-terrain.js.map +1 -0
  10. package/dist/generators/noise.d.ts +3 -1
  11. package/dist/generators/noise.d.ts.map +1 -1
  12. package/dist/generators/noise.js +8 -3
  13. package/dist/generators/noise.js.map +1 -1
  14. package/dist/generators/rng.d.ts +6 -1
  15. package/dist/generators/rng.d.ts.map +1 -1
  16. package/dist/generators/rng.js +7 -1
  17. package/dist/generators/rng.js.map +1 -1
  18. package/dist/index.d.ts +5 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +14 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/infinite-terrain.d.ts +34 -0
  23. package/dist/infinite-terrain.d.ts.map +1 -0
  24. package/dist/infinite-terrain.js +64 -0
  25. package/dist/infinite-terrain.js.map +1 -0
  26. package/dist/map-layer.d.ts.map +1 -1
  27. package/dist/map-layer.js +107 -9
  28. package/dist/map-layer.js.map +1 -1
  29. package/dist/map-tool.d.ts.map +1 -1
  30. package/dist/map-tool.js +93 -30
  31. package/dist/map-tool.js.map +1 -1
  32. package/dist/plugin.d.ts.map +1 -1
  33. package/dist/plugin.js +58 -1
  34. package/dist/plugin.js.map +1 -1
  35. package/dist/tilemap-shape.d.ts +30 -0
  36. package/dist/tilemap-shape.d.ts.map +1 -1
  37. package/dist/tilemap-shape.js +35 -0
  38. package/dist/tilemap-shape.js.map +1 -1
  39. package/dist/use-infinite-terrain.d.ts +19 -0
  40. package/dist/use-infinite-terrain.d.ts.map +1 -0
  41. package/dist/use-infinite-terrain.js +45 -0
  42. package/dist/use-infinite-terrain.js.map +1 -0
  43. package/package.json +1 -1
package/README.md CHANGED
@@ -42,3 +42,37 @@ const plugins = [
42
42
  | `tile` | `40` | タイル辺(world 単位) |
43
43
  | `defaultColorMode` | `"color"` | 初期配色(`color` / `mono`) |
44
44
  | `defaultLineStyle` | `"wobble"` | 初期線種(`wobble` / `clean`) |
45
+
46
+ ## ツール状態の公開 API(#927 / v0.6.0)
47
+
48
+ Control HUD(`debug-hud`)以外の**ホスト独自 UI**(ActionRing / ラジアルメニュー / 独自ツールバー)
49
+ からツールの mode / terrain / icon を切り替えられるよう、内部の app-local reactive store を公開している。
50
+ `renderConfigStore` と同じ **public reactive store(`get()` / `set(patch)` / `subscribe()`)** パターン。
51
+ いずれも同期対象外(presentation/interaction state)。
52
+
53
+ | export | 内容 |
54
+ |---|---|
55
+ | `toolStateStore` / `MapToolState` / `useMapToolState()` | `mode` / `terrain` / `iconKey` / `excludeTerrains` |
56
+ | `MAP_MODES` | モードの順序付き配列(`brush\|eraser\|fill\|region\|stamp\|generate\|base`)。`MapMode` はここから派生(実行時に列挙可能) |
57
+ | `rangeEraseStore` / `RangeEraseTargets` / `useRangeEraseTargets()` | 範囲消しの対象 |
58
+ | `genStateStore` / `GenState` / `WorldRect` / `useGenState()` | 生成 UI(アルゴリズム / seed / params / ドラッグ矩形) |
59
+ | `baseStateStore` / `BaseToolState` / `useBaseState()` | 拠点ツールの選択状態 |
60
+ | `ReactiveStore` | 各 store の共通インターフェース |
61
+ | `TERRAINS` / `ICONS` | 既存 export(terrain / icon の定義一覧) |
62
+
63
+ ```tsx
64
+ import { toolStateStore, MAP_MODES, TERRAINS, useMapToolState } from "@edv4h/usketch-plugin-map";
65
+
66
+ // 独自 ActionRing から直接セット
67
+ toolStateStore.set({ mode: "brush", terrain: "grass" });
68
+
69
+ // React で購読
70
+ function ModePicker() {
71
+ const { mode } = useMapToolState();
72
+ return MAP_MODES.map((m) => (
73
+ <button key={m} aria-pressed={m === mode} onClick={() => toolStateStore.set({ mode: m })}>
74
+ {m}
75
+ </button>
76
+ ));
77
+ }
78
+ ```
@@ -49,4 +49,26 @@ export declare function floodFill(cells: Cells, startCol: number, startRow: numb
49
49
  * e.g. water, untouched).
50
50
  */
51
51
  export declare function regionFillCells(cells: Cells, startCol: number, startRow: number, exclude: ReadonlySet<string>, box?: CellBox): string[];
52
+ /** A terrain lookup for any cell (override ?? base ?? empty); may be undefined. */
53
+ export type CellSampler = (col: number, row: number) => TerrainKey | undefined;
54
+ export interface SamplerFloodResult {
55
+ /** Cell keys forming the connected region (empty when the start is undefined). */
56
+ cells: string[];
57
+ /**
58
+ * `true` if the flood hit `maxCells` before the region closed — i.e. the region
59
+ * is not enclosed (or is larger than the cap). Callers should treat this as
60
+ * "cannot fill" rather than filling an arbitrary blob.
61
+ */
62
+ truncated: boolean;
63
+ }
64
+ /**
65
+ * Flood fill over a **sampler** (override ?? base ?? empty) rather than the sparse
66
+ * override map — this is what makes region fill work on the infinite base terrain,
67
+ * where unpainted cells still have a real (generated) terrain. Because that field
68
+ * is boundless, the flood is capped by `maxCells` and uses **breadth-first** order
69
+ * so a capped result is a compact blob around the start. If it hits the cap before
70
+ * the region closes, `truncated` is set and the caller aborts (the region is open,
71
+ * e.g. an infinite ocean). An `undefined` start terrain yields an empty region.
72
+ */
73
+ export declare function samplerFloodFill(sample: CellSampler, startCol: number, startRow: number, maxCells: number): SamplerFloodResult;
52
74
  //# sourceMappingURL=autotile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"autotile.d.ts","sourceRoot":"","sources":["../src/autotile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE/C,iCAAiC;AACjC,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAGpE;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAE1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,GACvB,UAAU,GAAG,SAAS,CAExB;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAmBnE;AAED,MAAM,WAAW,YAAY;IAC5B,CAAC,EAAE,OAAO,CAAC;IACX,CAAC,EAAE,OAAO,CAAC;IACX,CAAC,EAAE,OAAO,CAAC;IACX,CAAC,EAAE,OAAO,CAAC;CACX;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,GACvB,YAAY,CASd;AAED,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACxB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,OAAO,GACX,MAAM,EAAE,CAuBV;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAC5B,GAAG,CAAC,EAAE,OAAO,GACX,MAAM,EAAE,CAIV"}
1
+ {"version":3,"file":"autotile.d.ts","sourceRoot":"","sources":["../src/autotile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE/C,iCAAiC;AACjC,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAGpE;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAE1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,GACvB,UAAU,GAAG,SAAS,CAExB;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAmBnE;AAED,MAAM,WAAW,YAAY;IAC5B,CAAC,EAAE,OAAO,CAAC;IACX,CAAC,EAAE,OAAO,CAAC;IACX,CAAC,EAAE,OAAO,CAAC;IACX,CAAC,EAAE,OAAO,CAAC;CACX;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,GACvB,YAAY,CASd;AAED,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACxB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,OAAO,GACX,MAAM,EAAE,CAuBV;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAC5B,GAAG,CAAC,EAAE,OAAO,GACX,MAAM,EAAE,CAIV;AAED,mFAAmF;AACnF,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;AAE/E,MAAM,WAAW,kBAAkB;IAClC,kFAAkF;IAClF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACd,kBAAkB,CAiCpB"}
package/dist/autotile.js CHANGED
@@ -108,4 +108,50 @@ export function regionFillCells(cells, startCol, startRow, exclude, box) {
108
108
  return [];
109
109
  return floodFill(cells, startCol, startRow, box);
110
110
  }
111
+ /**
112
+ * Flood fill over a **sampler** (override ?? base ?? empty) rather than the sparse
113
+ * override map — this is what makes region fill work on the infinite base terrain,
114
+ * where unpainted cells still have a real (generated) terrain. Because that field
115
+ * is boundless, the flood is capped by `maxCells` and uses **breadth-first** order
116
+ * so a capped result is a compact blob around the start. If it hits the cap before
117
+ * the region closes, `truncated` is set and the caller aborts (the region is open,
118
+ * e.g. an infinite ocean). An `undefined` start terrain yields an empty region.
119
+ */
120
+ export function samplerFloodFill(sample, startCol, startRow, maxCells) {
121
+ const target = sample(startCol, startRow);
122
+ if (target === undefined)
123
+ return { cells: [], truncated: false };
124
+ // Non-positive cap: nothing can be filled. Return a deterministic empty result
125
+ // rather than reporting a bogus truncation.
126
+ if (maxCells <= 0)
127
+ return { cells: [], truncated: false };
128
+ const out = [];
129
+ const seen = new Set([cellKey(startCol, startRow)]);
130
+ const queue = [[startCol, startRow]];
131
+ let head = 0;
132
+ while (head < queue.length) {
133
+ const [c, r] = queue[head++];
134
+ if (sample(c, r) !== target)
135
+ continue;
136
+ // A matching cell we have no room for ⇒ the region extends past the cap, so
137
+ // it is not (provably) enclosed. A region of *exactly* maxCells cells closes
138
+ // with no matching cell left to dequeue, and is correctly reported enclosed.
139
+ if (out.length >= maxCells)
140
+ return { cells: out, truncated: true };
141
+ out.push(cellKey(c, r));
142
+ for (const [nc, nr] of [
143
+ [c + 1, r],
144
+ [c - 1, r],
145
+ [c, r + 1],
146
+ [c, r - 1],
147
+ ]) {
148
+ const k = cellKey(nc, nr);
149
+ if (!seen.has(k)) {
150
+ seen.add(k);
151
+ queue.push([nc, nr]);
152
+ }
153
+ }
154
+ }
155
+ return { cells: out, truncated: false };
156
+ }
111
157
  //# sourceMappingURL=autotile.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"autotile.js","sourceRoot":"","sources":["../src/autotile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"autotile.js","sourceRoot":"","sources":["../src/autotile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { type Cells } from "./autotile.js";
2
+ import type { TerrainKey } from "./terrain.js";
3
+ /**
4
+ * Parameters that fully pin the infinite base terrain's appearance. Recorded on
5
+ * the tilemap shape (see `TileMapShapeData.baseGen`) so a board's world is FROZEN
6
+ * at creation: tuning these defaults later — or swapping the algorithm — will not
7
+ * silently mutate existing boards, because each carries the exact inputs it was
8
+ * generated with. `version` selects the generation *algorithm* implementation
9
+ * (kept around per version for backward-compat); the rest are its tunable inputs.
10
+ *
11
+ * - `scale` base frequency of the elevation field (smaller ⇒ larger continents)
12
+ * - `seaLevel` fraction of the normalised range below which is water
13
+ * - `gMin/gMax` fixed global contrast window: measured `fbm` output is ~[-0.4, 0.4]
14
+ * centred near 0, so this window stretches its bulk to [0,1], giving `seaLevel`
15
+ * a stable meaning AND keeping bands continuous across the whole infinite plane
16
+ * (a box-local stretch would seam at chunk borders).
17
+ */
18
+ export interface BaseGenParams {
19
+ version: number;
20
+ scale: number;
21
+ seaLevel: number;
22
+ gMin: number;
23
+ gMax: number;
24
+ }
25
+ /** Current generation-algorithm version. Bump when the algorithm changes shape. */
26
+ export declare const BASE_GEN_VERSION = 1;
27
+ /**
28
+ * Params stamped onto NEW boards. Points at the current recommended version and
29
+ * may advance later; a shape's own recorded `baseGen` always wins over this, so
30
+ * advancing the default never touches an existing board.
31
+ */
32
+ export declare const DEFAULT_BASE_GEN: BaseGenParams;
33
+ /**
34
+ * Resolve a shape's (possibly `undefined`) `baseGen` to concrete params. A missing
35
+ * value means the shape predates versioning ⇒ it is v1 by definition. `baseGen` is
36
+ * untrusted synced/persisted data, so it is also **validated**: corrupted params
37
+ * (NaN/Infinity, `gMin >= gMax`, `seaLevel`/`scale` out of range) or an
38
+ * unsupported `version` fall back to the FROZEN v1 params rather than producing a
39
+ * NaN-normalised, all-"snow" base across the whole infinite plane.
40
+ */
41
+ export declare function resolveBaseGen(gen: BaseGenParams | undefined): BaseGenParams;
42
+ /**
43
+ * Base terrain for a world cell — deterministic for a given `seed`, defined for
44
+ * every integer coord, and seamless (sampled in continuous world space).
45
+ */
46
+ export declare function baseTerrainAt(seed: number, col: number, row: number, gen?: BaseGenParams): TerrainKey;
47
+ /** Drop all cached chunks (e.g. on seed change). */
48
+ export declare function clearBaseCache(): void;
49
+ /**
50
+ * A terrain sampler for one render: a painted override wins, otherwise the
51
+ * generated base (when `baseSeed` is set), otherwise the flat `empty` fallback.
52
+ * With a `baseSeed` it is **total** (always returns a terrain) — that is what
53
+ * lets rendering fill the whole viewport and lets autotiling resolve every
54
+ * neighbour without a chunk-boundary gap.
55
+ */
56
+ export type TerrainSampler = (col: number, row: number) => TerrainKey | undefined;
57
+ export declare function makeTerrainSampler(cells: Cells, baseSeed: number | null, empty: TerrainKey | null, gen?: BaseGenParams): TerrainSampler;
58
+ //# sourceMappingURL=base-terrain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-terrain.d.ts","sourceRoot":"","sources":["../src/base-terrain.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,KAAK,EAAW,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACb;AAED,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAWlC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,aAAsB,CAAC;AAKtD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,SAAS,GAAG,aAAa,CAc5E;AA+CD;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,GAAG,GAAE,aAAgC,GACnC,UAAU,CAGZ;AAED,oDAAoD;AACpD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;AAElF,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,GAAG,GAAE,aAAgC,GACnC,cAAc,CAKhB"}
@@ -0,0 +1,107 @@
1
+ // Deterministic, infinite base terrain — a pure function of (seed, world cell).
2
+ // Because every cell is defined for any integer coord, the map can be panned
3
+ // forever (no stored data for unedited space) AND autotiling never sees an
4
+ // "unset" neighbour at a chunk boundary (there are no boundaries in the field).
5
+ import { cellKey } from "./autotile.js";
6
+ import { elevationToTerrain } from "./generators/index.js";
7
+ import { fbm } from "./generators/noise.js";
8
+ /** Current generation-algorithm version. Bump when the algorithm changes shape. */
9
+ export const BASE_GEN_VERSION = 1;
10
+ /** The v1 parameter set — FROZEN. Never edit these values; add a new version. */
11
+ const V1_GEN = {
12
+ version: 1,
13
+ scale: 0.05,
14
+ seaLevel: 0.42,
15
+ gMin: -0.25,
16
+ gMax: 0.25,
17
+ };
18
+ /**
19
+ * Params stamped onto NEW boards. Points at the current recommended version and
20
+ * may advance later; a shape's own recorded `baseGen` always wins over this, so
21
+ * advancing the default never touches an existing board.
22
+ */
23
+ export const DEFAULT_BASE_GEN = V1_GEN;
24
+ /** Generation versions this build knows how to render. */
25
+ const SUPPORTED_VERSIONS = new Set([1]);
26
+ /**
27
+ * Resolve a shape's (possibly `undefined`) `baseGen` to concrete params. A missing
28
+ * value means the shape predates versioning ⇒ it is v1 by definition. `baseGen` is
29
+ * untrusted synced/persisted data, so it is also **validated**: corrupted params
30
+ * (NaN/Infinity, `gMin >= gMax`, `seaLevel`/`scale` out of range) or an
31
+ * unsupported `version` fall back to the FROZEN v1 params rather than producing a
32
+ * NaN-normalised, all-"snow" base across the whole infinite plane.
33
+ */
34
+ export function resolveBaseGen(gen) {
35
+ if (!gen)
36
+ return V1_GEN;
37
+ const { version, scale, seaLevel, gMin, gMax } = gen;
38
+ const valid = SUPPORTED_VERSIONS.has(version) &&
39
+ Number.isFinite(scale) &&
40
+ scale > 0 &&
41
+ Number.isFinite(seaLevel) &&
42
+ seaLevel >= 0 &&
43
+ seaLevel <= 1 &&
44
+ Number.isFinite(gMin) &&
45
+ Number.isFinite(gMax) &&
46
+ gMin < gMax;
47
+ return valid ? gen : V1_GEN;
48
+ }
49
+ const clamp01 = (v) => (v < 0 ? 0 : v > 1 ? 1 : v);
50
+ // ── Per-chunk cache ──
51
+ // `baseTerrainAt` is called per visible cell every frame; caching a chunk's
52
+ // terrains once and evicting far chunks (LRU) keeps it cheap while panning.
53
+ const CHUNK = 16;
54
+ const MAX_CHUNKS = 1024;
55
+ const cache = new Map();
56
+ /** Compact signature so chunks generated with different params never collide. */
57
+ const genSig = (g) => `${g.version}|${g.scale}|${g.seaLevel}|${g.gMin}|${g.gMax}`;
58
+ function chunkGrid(seed, cx, cy, gen) {
59
+ const key = `${genSig(gen)}:${seed}:${cx}:${cy}`;
60
+ const hit = cache.get(key);
61
+ if (hit) {
62
+ // LRU touch: re-insert so it's most-recently-used.
63
+ cache.delete(key);
64
+ cache.set(key, hit);
65
+ return hit;
66
+ }
67
+ const grid = new Array(CHUNK * CHUNK);
68
+ const baseC = cx * CHUNK;
69
+ const baseR = cy * CHUNK;
70
+ // v1 is the only algorithm today; `gen.version` is recorded so a future
71
+ // version can branch here while old boards keep rendering via their own params.
72
+ for (let r = 0; r < CHUNK; r++) {
73
+ for (let c = 0; c < CHUNK; c++) {
74
+ const e = fbm(seed, baseC + c, baseR + r, gen.scale);
75
+ const n = clamp01((e - gen.gMin) / (gen.gMax - gen.gMin));
76
+ grid[r * CHUNK + c] = elevationToTerrain(n, gen.seaLevel);
77
+ }
78
+ }
79
+ if (cache.size >= MAX_CHUNKS) {
80
+ const oldest = cache.keys().next().value;
81
+ if (oldest !== undefined)
82
+ cache.delete(oldest);
83
+ }
84
+ cache.set(key, grid);
85
+ return grid;
86
+ }
87
+ /** Positive modulo so negative world coords index into a chunk correctly. */
88
+ const mod = (n, m) => ((n % m) + m) % m;
89
+ /**
90
+ * Base terrain for a world cell — deterministic for a given `seed`, defined for
91
+ * every integer coord, and seamless (sampled in continuous world space).
92
+ */
93
+ export function baseTerrainAt(seed, col, row, gen = DEFAULT_BASE_GEN) {
94
+ const grid = chunkGrid(seed, Math.floor(col / CHUNK), Math.floor(row / CHUNK), gen);
95
+ return grid[mod(row, CHUNK) * CHUNK + mod(col, CHUNK)];
96
+ }
97
+ /** Drop all cached chunks (e.g. on seed change). */
98
+ export function clearBaseCache() {
99
+ cache.clear();
100
+ }
101
+ export function makeTerrainSampler(cells, baseSeed, empty, gen = DEFAULT_BASE_GEN) {
102
+ if (baseSeed != null) {
103
+ return (col, row) => cells[cellKey(col, row)] ?? baseTerrainAt(baseSeed, col, row, gen);
104
+ }
105
+ return (col, row) => cells[cellKey(col, row)] ?? empty ?? undefined;
106
+ }
107
+ //# sourceMappingURL=base-terrain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-terrain.js","sourceRoot":"","sources":["../src/base-terrain.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * fractal Brownian motion: sum of octaves of value noise. `scale` sets the base
3
- * frequency (world-cell → noise space). Returns a value normalised to [0,1].
3
+ * frequency (world-cell → noise space). The amplitude-weighted average keeps the
4
+ * output in the same **zero-centred ~[-0.5, 0.5)** domain as the value noise
5
+ * (empirically ≈[-0.41, 0.40] at the default scale) — it is NOT [0, 1].
4
6
  */
5
7
  export declare function fbm(seed: number, cx: number, cy: number, scale: number, octaves?: number): number;
6
8
  //# sourceMappingURL=noise.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"noise.d.ts","sourceRoot":"","sources":["../../src/generators/noise.ts"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,MAAM,CAa5F"}
1
+ {"version":3,"file":"noise.d.ts","sourceRoot":"","sources":["../../src/generators/noise.ts"],"names":[],"mappings":"AA0BA;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,MAAM,CAa5F"}
@@ -1,10 +1,13 @@
1
1
  // Deterministic value-noise elevation field (fBm) — no external deps.
2
- // Elevation is sampled per cell and normalised to [0,1].
2
+ // Elevation is sampled per cell. `hash2` is zero-centred (~[-0.5, 0.5)), so the
3
+ // noise and fBm below are likewise **centred on 0** (roughly [-0.5, 0.5)), NOT
4
+ // [0, 1). Consumers that want a band split apply their own contrast window.
3
5
  import { hash2 } from "./rng.js";
4
6
  function smoothstep(t) {
5
7
  return t * t * (3 - 2 * t);
6
8
  }
7
- /** Bilinear value noise at (x,y) using a seeded integer lattice. Range ~[0,1). */
9
+ /** Bilinear value noise at (x,y) using a seeded integer lattice. Zero-centred,
10
+ * range ~[-0.5, 0.5) (inherited from `hash2`). */
8
11
  function valueNoise2D(seed, x, y) {
9
12
  const x0 = Math.floor(x);
10
13
  const y0 = Math.floor(y);
@@ -20,7 +23,9 @@ function valueNoise2D(seed, x, y) {
20
23
  }
21
24
  /**
22
25
  * fractal Brownian motion: sum of octaves of value noise. `scale` sets the base
23
- * frequency (world-cell → noise space). Returns a value normalised to [0,1].
26
+ * frequency (world-cell → noise space). The amplitude-weighted average keeps the
27
+ * output in the same **zero-centred ~[-0.5, 0.5)** domain as the value noise
28
+ * (empirically ≈[-0.41, 0.40] at the default scale) — it is NOT [0, 1].
24
29
  */
25
30
  export function fbm(seed, cx, cy, scale, octaves = 4) {
26
31
  let amp = 1;
@@ -1 +1 @@
1
- {"version":3,"file":"noise.js","sourceRoot":"","sources":["../../src/generators/noise.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,yDAAyD;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,SAAS,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,kFAAkF;AAClF,SAAS,YAAY,CAAC,IAAY,EAAE,CAAS,EAAE,CAAS;IACvD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IACtC,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAU,EAAE,EAAU,EAAE,KAAa,EAAE,OAAO,GAAG,CAAC;IACnF,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,mDAAmD;QACnD,GAAG,IAAI,GAAG,GAAG,YAAY,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QACjE,IAAI,IAAI,GAAG,CAAC;QACZ,GAAG,IAAI,GAAG,CAAC;QACX,IAAI,IAAI,CAAC,CAAC;IACX,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"noise.js","sourceRoot":"","sources":["../../src/generators/noise.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,SAAS,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED;kDACkD;AAClD,SAAS,YAAY,CAAC,IAAY,EAAE,CAAS,EAAE,CAAS;IACvD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IACtC,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAU,EAAE,EAAU,EAAE,KAAa,EAAE,OAAO,GAAG,CAAC;IACnF,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,mDAAmD;QACnD,GAAG,IAAI,GAAG,GAAG,YAAY,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QACjE,IAAI,IAAI,GAAG,CAAC;QACZ,GAAG,IAAI,GAAG,CAAC;QACX,IAAI,IAAI,CAAC,CAAC;IACX,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC"}
@@ -2,6 +2,11 @@
2
2
  export declare function mulberry32(seed: number): () => number;
3
3
  /** Coerce a user-entered seed (number or string) to a 32-bit unsigned int. */
4
4
  export declare function hashSeed(seed: number | string): number;
5
- /** Stable per-lattice-point value in [0,1) from (seed, x, y) — no allocation. */
5
+ /**
6
+ * Stable per-lattice-point value from (seed, x, y) — no allocation.
7
+ * NOTE: the final `h ^ (h >>> 16)` is a JS bitwise op, so it yields a *signed*
8
+ * int32; divided by 2^32 the result is **centred on 0 in ~[-0.5, 0.5)**, not
9
+ * [0, 1). Callers (value noise / fBm) rely on this zero-centring.
10
+ */
6
11
  export declare function hash2(seed: number, x: number, y: number): number;
7
12
  //# sourceMappingURL=rng.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rng.d.ts","sourceRoot":"","sources":["../../src/generators/rng.ts"],"names":[],"mappings":"AAGA,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,MAAM,CASrD;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAQtD;AAED,iFAAiF;AACjF,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAIhE"}
1
+ {"version":3,"file":"rng.d.ts","sourceRoot":"","sources":["../../src/generators/rng.ts"],"names":[],"mappings":"AAGA,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,MAAM,CASrD;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAQtD;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKhE"}
@@ -22,10 +22,16 @@ export function hashSeed(seed) {
22
22
  }
23
23
  return h >>> 0;
24
24
  }
25
- /** Stable per-lattice-point value in [0,1) from (seed, x, y) — no allocation. */
25
+ /**
26
+ * Stable per-lattice-point value from (seed, x, y) — no allocation.
27
+ * NOTE: the final `h ^ (h >>> 16)` is a JS bitwise op, so it yields a *signed*
28
+ * int32; divided by 2^32 the result is **centred on 0 in ~[-0.5, 0.5)**, not
29
+ * [0, 1). Callers (value noise / fBm) rely on this zero-centring.
30
+ */
26
31
  export function hash2(seed, x, y) {
27
32
  let h = (seed ^ Math.imul(x | 0, 374761393) ^ Math.imul(y | 0, 668265263)) >>> 0;
28
33
  h = Math.imul(h ^ (h >>> 13), 1274126177) >>> 0;
34
+ // Signed int32 (top bit → negative) / 2^32 ⇒ ~[-0.5, 0.5).
29
35
  return (h ^ (h >>> 16)) / 4294967296;
30
36
  }
31
37
  //# sourceMappingURL=rng.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rng.js","sourceRoot":"","sources":["../../src/generators/rng.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,qDAAqD;AAErD,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,IAAY;IACtC,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;IACnB,OAAO,GAAG,EAAE;QACX,CAAC,IAAI,CAAC,CAAC;QACP,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC;IAC9C,CAAC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,QAAQ,CAAC,IAAqB;IAC7C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,KAAK,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,SAAS;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AAChB,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,CAAS,EAAE,CAAS;IACvD,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC;IACjF,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAChD,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"rng.js","sourceRoot":"","sources":["../../src/generators/rng.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,qDAAqD;AAErD,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,IAAY;IACtC,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;IACnB,OAAO,GAAG,EAAE;QACX,CAAC,IAAI,CAAC,CAAC;QACP,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC;IAC9C,CAAC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,QAAQ,CAAC,IAAqB;IAC7C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,KAAK,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,SAAS;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,CAAS,EAAE,CAAS;IACvD,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC;IACjF,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAChD,2DAA2D;IAC3D,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC;AACtC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  export { BASE_MAP_TYPE, type BaseInfo, type BaseMapShapeData, } from "./base/base-map-shape.js";
2
2
  export { type BaseToolState, baseStateStore, useBaseState } from "./base/base-state.js";
3
3
  export { computeTerritory, type Territory } from "./base/territory.js";
4
+ export { type BaseGenParams, baseTerrainAt, DEFAULT_BASE_GEN } from "./base-terrain.js";
4
5
  export { type GenState, genStateStore, useGenState, type WorldRect } from "./gen-state.js";
6
+ export { resolveTilemap } from "./generate.js";
5
7
  export { GENERATORS, type GenContext, type GenParam, type MapGenerator, } from "./generators/index.js";
6
8
  export { ICONS, type IconCategory, type IconDef } from "./icons.js";
9
+ export { DEFAULT_INFINITE_SEED, disableInfiniteTerrain, type EnableInfiniteTerrainOptions, enableInfiniteTerrain, getInfiniteSeed, isInfiniteTerrainEnabled, setInfiniteSeed, } from "./infinite-terrain.js";
7
10
  export { MAP_ICON_TYPE, type MapIconShapeData } from "./map-icon-shape.js";
8
11
  export { MAP_TOOL_ID } from "./map-tool-id.js";
9
12
  export type { ColorMode } from "./palette.js";
@@ -12,6 +15,7 @@ export { type RangeEraseTargets, rangeEraseStore, useRangeEraseTargets, } from "
12
15
  export type { ReactiveStore } from "./reactive-store.js";
13
16
  export { type LineStyle, type MapRenderConfig, renderConfigStore, } from "./render-config.js";
14
17
  export { TERRAINS, type TerrainDef, type TerrainKey } from "./terrain.js";
15
- export { DEFAULT_TILE, TILEMAP_TYPE, type TileMapShapeData } from "./tilemap-shape.js";
18
+ export { DEFAULT_TILE, isTileMap, lowestTilemap, makeTileMap, seededTilemap, TILEMAP_TYPE, type TileMapShapeData, } from "./tilemap-shape.js";
16
19
  export { MAP_MODES, type MapMode, type MapToolState, toolStateStore, useMapToolState, } from "./tool-state.js";
20
+ export { type InfiniteTerrainControls, useInfiniteTerrain, } from "./use-infinite-terrain.js";
17
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,gBAAgB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,KAAK,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EACN,UAAU,EACV,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EACN,KAAK,iBAAiB,EACtB,eAAe,EACf,oBAAoB,GACpB,MAAM,wBAAwB,CAAC;AAMhC,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EACN,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,iBAAiB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EACN,SAAS,EACT,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,cAAc,EACd,eAAe,GACf,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,gBAAgB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,KAAK,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,KAAK,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAK3F,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACN,UAAU,EACV,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,YAAY,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAMpE,OAAO,EACN,qBAAqB,EACrB,sBAAsB,EACtB,KAAK,4BAA4B,EACjC,qBAAqB,EACrB,eAAe,EACf,wBAAwB,EACxB,eAAe,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EACN,KAAK,iBAAiB,EACtB,eAAe,EACf,oBAAoB,GACpB,MAAM,wBAAwB,CAAC;AAMhC,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EACN,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,iBAAiB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EACN,YAAY,EACZ,SAAS,EACT,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,KAAK,gBAAgB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,SAAS,EACT,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,cAAc,EACd,eAAe,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,KAAK,uBAAuB,EAC5B,kBAAkB,GAClB,MAAM,2BAA2B,CAAC"}
package/dist/index.js CHANGED
@@ -1,15 +1,28 @@
1
1
  export { BASE_MAP_TYPE, } from "./base/base-map-shape.js";
2
2
  export { baseStateStore, useBaseState } from "./base/base-state.js";
3
3
  export { computeTerritory } from "./base/territory.js";
4
+ export { baseTerrainAt, DEFAULT_BASE_GEN } from "./base-terrain.js";
4
5
  export { genStateStore, useGenState } from "./gen-state.js";
6
+ // NOTE: `resolveTilemap` returns the FIRST tilemap in iteration order (or creates
7
+ // one) — NOT deterministic across synced peers when several tilemaps exist. For
8
+ // deterministic selection use `seededTilemap` / `lowestTilemap`, or the
9
+ // `enableInfiniteTerrain` API which already picks deterministically.
10
+ export { resolveTilemap } from "./generate.js";
5
11
  export { GENERATORS, } from "./generators/index.js";
6
12
  export { ICONS } from "./icons.js";
13
+ // ── Infinite base terrain public API (#946 / #937 follow-up) ──
14
+ // Enable/disable/seed the infinite base terrain from a host's own UI without the
15
+ // Control HUD. Same logic the HUD toggle runs; the seed lives on the tilemap
16
+ // shape (synced/persisted), so these take a BoardStore. Use the functions for
17
+ // imperative control, or `useInfiniteTerrain(store)` for a reactive React binding.
18
+ export { DEFAULT_INFINITE_SEED, disableInfiniteTerrain, enableInfiniteTerrain, getInfiniteSeed, isInfiniteTerrainEnabled, setInfiniteSeed, } from "./infinite-terrain.js";
7
19
  export { MAP_ICON_TYPE } from "./map-icon-shape.js";
8
20
  export { MAP_TOOL_ID } from "./map-tool-id.js";
9
21
  export { createMapPlugin } from "./plugin.js";
10
22
  export { rangeEraseStore, useRangeEraseTargets, } from "./range-erase-state.js";
11
23
  export { renderConfigStore, } from "./render-config.js";
12
24
  export { TERRAINS } from "./terrain.js";
13
- export { DEFAULT_TILE, TILEMAP_TYPE } from "./tilemap-shape.js";
25
+ export { DEFAULT_TILE, isTileMap, lowestTilemap, makeTileMap, seededTilemap, TILEMAP_TYPE, } from "./tilemap-shape.js";
14
26
  export { MAP_MODES, toolStateStore, useMapToolState, } from "./tool-state.js";
27
+ export { useInfiniteTerrain, } from "./use-infinite-terrain.js";
15
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,GAGb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAsB,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAkB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAiB,aAAa,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EACN,UAAU,GAIV,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAmC,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,aAAa,EAAyB,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAyB,MAAM,aAAa,CAAC;AACrE,OAAO,EAEN,eAAe,EACf,oBAAoB,GACpB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EAGN,iBAAiB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAoC,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AACvF,OAAO,EACN,SAAS,EAGT,cAAc,EACd,eAAe,GACf,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,GAGb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAsB,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAkB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAsB,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAiB,aAAa,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAC3F,kFAAkF;AAClF,gFAAgF;AAChF,wEAAwE;AACxE,qEAAqE;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACN,UAAU,GAIV,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAmC,MAAM,YAAY,CAAC;AACpE,iEAAiE;AACjE,iFAAiF;AACjF,6EAA6E;AAC7E,8EAA8E;AAC9E,mFAAmF;AACnF,OAAO,EACN,qBAAqB,EACrB,sBAAsB,EAEtB,qBAAqB,EACrB,eAAe,EACf,wBAAwB,EACxB,eAAe,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAyB,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAyB,MAAM,aAAa,CAAC;AACrE,OAAO,EAEN,eAAe,EACf,oBAAoB,GACpB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EAGN,iBAAiB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAoC,MAAM,cAAc,CAAC;AAC1E,OAAO,EACN,YAAY,EACZ,SAAS,EACT,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,GAEZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,SAAS,EAGT,cAAc,EACd,eAAe,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEN,kBAAkB,GAClB,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { BoardStore } from "@edv4h/usketch-shared";
2
+ /** Seed used when enabling without an explicit one (matches the HUD default). */
3
+ export declare const DEFAULT_INFINITE_SEED = 12345;
4
+ export interface EnableInfiniteTerrainOptions {
5
+ /**
6
+ * Seed for the world. Rounded to an integer. Omitted → keep the current seed if
7
+ * already enabled, else {@link DEFAULT_INFINITE_SEED}.
8
+ */
9
+ seed?: number;
10
+ /** Tile size for a tilemap created on a blank board. Default {@link DEFAULT_TILE}. */
11
+ tile?: number;
12
+ }
13
+ /** The board's effective infinite-terrain seed, or `null` when disabled. */
14
+ export declare function getInfiniteSeed(store: BoardStore): number | null;
15
+ /** Whether the infinite base terrain is enabled on the board. */
16
+ export declare function isInfiniteTerrainEnabled(store: BoardStore): boolean;
17
+ /**
18
+ * Enable (or re-seed) the infinite base terrain — the same operation the HUD
19
+ * toggle runs. Stamps `baseSeed` + a frozen `baseGen` onto the deterministically
20
+ * chosen tilemap: an already-seeded one, else the lowest-id tilemap, else a freshly
21
+ * created one on a blank board. Persists + syncs (it's shape data). Returns the
22
+ * integer seed applied. Throws `RangeError` on a non-finite seed or a non-finite /
23
+ * non-positive `tile`.
24
+ */
25
+ export declare function enableInfiniteTerrain(store: BoardStore, opts?: EnableInfiniteTerrainOptions): number;
26
+ /** Disable the infinite base terrain (clears `baseSeed` on every seeded tilemap). */
27
+ export declare function disableInfiniteTerrain(store: BoardStore): void;
28
+ /**
29
+ * Set the seed: a number enables/re-seeds, `null` disables — the "reactive setter"
30
+ * ergonomics requested in #946 (`set({ seed })` / `set({ seed: null })`), backed by
31
+ * the functions above so behaviour is identical to the HUD.
32
+ */
33
+ export declare function setInfiniteSeed(store: BoardStore, seed: number | null): void;
34
+ //# sourceMappingURL=infinite-terrain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infinite-terrain.d.ts","sourceRoot":"","sources":["../src/infinite-terrain.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAWxD,iFAAiF;AACjF,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C,MAAM,WAAW,4BAA4B;IAC5C;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAEhE;AAED,iEAAiE;AACjE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAEnE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE,4BAAiC,GACrC,MAAM,CAyBR;AAED,qFAAqF;AACrF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAG5E"}
@@ -0,0 +1,64 @@
1
+ import { DEFAULT_BASE_GEN } from "./base-terrain.js";
2
+ import { resolveTilemap } from "./generate.js";
3
+ import { DEFAULT_TILE, isTileMap, lowestTilemap, seededTilemap, } from "./tilemap-shape.js";
4
+ /** Seed used when enabling without an explicit one (matches the HUD default). */
5
+ export const DEFAULT_INFINITE_SEED = 12345;
6
+ /** The board's effective infinite-terrain seed, or `null` when disabled. */
7
+ export function getInfiniteSeed(store) {
8
+ return seededTilemap(store.getShapes().values())?.baseSeed ?? null;
9
+ }
10
+ /** Whether the infinite base terrain is enabled on the board. */
11
+ export function isInfiniteTerrainEnabled(store) {
12
+ return getInfiniteSeed(store) != null;
13
+ }
14
+ /**
15
+ * Enable (or re-seed) the infinite base terrain — the same operation the HUD
16
+ * toggle runs. Stamps `baseSeed` + a frozen `baseGen` onto the deterministically
17
+ * chosen tilemap: an already-seeded one, else the lowest-id tilemap, else a freshly
18
+ * created one on a blank board. Persists + syncs (it's shape data). Returns the
19
+ * integer seed applied. Throws `RangeError` on a non-finite seed or a non-finite /
20
+ * non-positive `tile`.
21
+ */
22
+ export function enableInfiniteTerrain(store, opts = {}) {
23
+ const raw = opts.seed ?? getInfiniteSeed(store) ?? DEFAULT_INFINITE_SEED;
24
+ const seed = Math.trunc(Number(raw));
25
+ if (!Number.isFinite(seed)) {
26
+ throw new RangeError(`enableInfiniteTerrain: seed must be a finite number, got ${String(raw)}`);
27
+ }
28
+ // Validate the tile size — it feeds cell math (move/viewport divide by tile), so
29
+ // a non-finite/non-positive value would later cause NaN/÷0 cells.
30
+ const tile = opts.tile ?? DEFAULT_TILE;
31
+ if (!Number.isFinite(tile) || tile <= 0) {
32
+ throw new RangeError(`enableInfiniteTerrain: tile must be a finite positive number, got ${String(opts.tile)}`);
33
+ }
34
+ // Deterministic target so every synced client agrees (see seededTilemap). Reuse
35
+ // the target's own recorded gen if present so re-enabling keeps the same world
36
+ // even after the default gen advances.
37
+ const target = seededTilemap(store.getShapes().values()) ?? lowestTilemap(store.getShapes().values());
38
+ const id = target?.id ?? resolveTilemap(store, tile).id;
39
+ store.updateShape(id, {
40
+ baseSeed: seed,
41
+ baseGen: target?.baseGen ?? DEFAULT_BASE_GEN,
42
+ });
43
+ return seed;
44
+ }
45
+ /** Disable the infinite base terrain (clears `baseSeed` on every seeded tilemap). */
46
+ export function disableInfiniteTerrain(store) {
47
+ for (const [id, s] of store.getShapes()) {
48
+ if (isTileMap(s) && s.baseSeed != null) {
49
+ store.updateShape(id, { baseSeed: undefined });
50
+ }
51
+ }
52
+ }
53
+ /**
54
+ * Set the seed: a number enables/re-seeds, `null` disables — the "reactive setter"
55
+ * ergonomics requested in #946 (`set({ seed })` / `set({ seed: null })`), backed by
56
+ * the functions above so behaviour is identical to the HUD.
57
+ */
58
+ export function setInfiniteSeed(store, seed) {
59
+ if (seed == null)
60
+ disableInfiniteTerrain(store);
61
+ else
62
+ enableInfiniteTerrain(store, { seed });
63
+ }
64
+ //# sourceMappingURL=infinite-terrain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infinite-terrain.js","sourceRoot":"","sources":["../src/infinite-terrain.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACN,YAAY,EACZ,SAAS,EACT,aAAa,EACb,aAAa,GAEb,MAAM,oBAAoB,CAAC;AAE5B,iFAAiF;AACjF,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAY3C,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,KAAiB;IAChD,OAAO,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAC;AACpE,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,wBAAwB,CAAC,KAAiB;IACzD,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACpC,KAAiB,EACjB,IAAI,GAAiC,EAAE;IAEvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,qBAAqB,CAAC;IACzE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,4DAA4D,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,iFAAiF;IACjF,kEAAkE;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,UAAU,CACnB,qEAAqE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxF,CAAC;IACH,CAAC;IACD,gFAAgF;IAChF,+EAA+E;IAC/E,uCAAuC;IACvC,MAAM,MAAM,GACX,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACxF,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,IAAI,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;IACxD,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE;QACrB,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,gBAAgB;KACf,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC;AACb,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,sBAAsB,CAAC,KAAiB;IACvD,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;QACzC,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;YACxC,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAA+B,CAAC,CAAC;QAC7E,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAiB,EAAE,IAAmB;IACrE,IAAI,IAAI,IAAI,IAAI;QAAE,sBAAsB,CAAC,KAAK,CAAC,CAAC;;QAC3C,qBAAqB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC"}