@codexo/exojs-tilemap 0.13.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 (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +187 -0
  3. package/dist/esm/TileChunk.d.ts +136 -0
  4. package/dist/esm/TileChunk.js +192 -0
  5. package/dist/esm/TileChunk.js.map +1 -0
  6. package/dist/esm/TileChunkNode.d.ts +59 -0
  7. package/dist/esm/TileChunkNode.js +89 -0
  8. package/dist/esm/TileChunkNode.js.map +1 -0
  9. package/dist/esm/TileLayer.d.ts +229 -0
  10. package/dist/esm/TileLayer.js +450 -0
  11. package/dist/esm/TileLayer.js.map +1 -0
  12. package/dist/esm/TileLayerNode.d.ts +81 -0
  13. package/dist/esm/TileLayerNode.js +142 -0
  14. package/dist/esm/TileLayerNode.js.map +1 -0
  15. package/dist/esm/TileMap.d.ts +178 -0
  16. package/dist/esm/TileMap.js +262 -0
  17. package/dist/esm/TileMap.js.map +1 -0
  18. package/dist/esm/TileMapBand.d.ts +97 -0
  19. package/dist/esm/TileMapBand.js +161 -0
  20. package/dist/esm/TileMapBand.js.map +1 -0
  21. package/dist/esm/TileMapNode.d.ts +71 -0
  22. package/dist/esm/TileMapNode.js +113 -0
  23. package/dist/esm/TileMapNode.js.map +1 -0
  24. package/dist/esm/TileMapView.d.ts +182 -0
  25. package/dist/esm/TileMapView.js +342 -0
  26. package/dist/esm/TileMapView.js.map +1 -0
  27. package/dist/esm/TileSet.d.ts +99 -0
  28. package/dist/esm/TileSet.js +157 -0
  29. package/dist/esm/TileSet.js.map +1 -0
  30. package/dist/esm/chunkGeometry.d.ts +71 -0
  31. package/dist/esm/chunkGeometry.js +98 -0
  32. package/dist/esm/chunkGeometry.js.map +1 -0
  33. package/dist/esm/index.d.ts +1 -0
  34. package/dist/esm/index.js +10 -0
  35. package/dist/esm/index.js.map +1 -0
  36. package/dist/esm/pixelSnap.d.ts +12 -0
  37. package/dist/esm/pixelSnap.js +19 -0
  38. package/dist/esm/pixelSnap.js.map +1 -0
  39. package/dist/esm/public.d.ts +18 -0
  40. package/dist/esm/register.d.ts +1 -0
  41. package/dist/esm/register.js +20 -0
  42. package/dist/esm/register.js.map +1 -0
  43. package/dist/esm/tilemapExtension.d.ts +18 -0
  44. package/dist/esm/tilemapExtension.js +52 -0
  45. package/dist/esm/tilemapExtension.js.map +1 -0
  46. package/dist/esm/types.d.ts +139 -0
  47. package/dist/esm/types.js +121 -0
  48. package/dist/esm/types.js.map +1 -0
  49. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts +39 -0
  50. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js +339 -0
  51. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js.map +1 -0
  52. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts +42 -0
  53. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js +390 -0
  54. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js.map +1 -0
  55. package/package.json +48 -0
@@ -0,0 +1,71 @@
1
+ import type { Texture } from '@codexo/exojs';
2
+ import type { ReadonlyTileChunk } from './TileChunk';
3
+ import type { TileSet } from './TileSet';
4
+ import type { TileTransform } from './types';
5
+ /**
6
+ * One textured tile quad in chunk-local pixel space.
7
+ *
8
+ * `u0/v0/u1/v1` are the raw (min/max) source UV bounds of the tile within its
9
+ * tileset texture — flip/orientation is **not** baked here; it travels in
10
+ * {@link TileQuad.orient} and is applied by the per-backend renderer (flipX/Y
11
+ * via UV-corner swap, diagonal via an axis swap in the shader). Keeping the
12
+ * geometry orientation-neutral lets both backends share one CPU builder.
13
+ * @internal
14
+ */
15
+ export interface TileQuad {
16
+ /** Local destination rect, left/top (chunk-local pixels). */
17
+ readonly x0: number;
18
+ readonly y0: number;
19
+ /** Local destination rect, right/bottom (chunk-local pixels). */
20
+ readonly x1: number;
21
+ readonly y1: number;
22
+ /** Normalised source UV bounds (always min ≤ max). */
23
+ readonly u0: number;
24
+ readonly v0: number;
25
+ readonly u1: number;
26
+ readonly v1: number;
27
+ /** Orientation code: bit0 = flipX, bit1 = flipY, bit2 = diagonal. */
28
+ readonly orient: number;
29
+ }
30
+ /**
31
+ * Geometry for one tileset "page" within a chunk: every tile in the chunk that
32
+ * draws from a single tileset texture, grouped so the renderer can batch by
33
+ * `(shader, texture)`.
34
+ * @internal
35
+ */
36
+ export interface ChunkPage {
37
+ /** The tileset all quads in this page draw from. */
38
+ readonly tileset: TileSet;
39
+ /** The underlying GPU texture (the tileset's atlas), bound once per page. */
40
+ readonly texture: Texture;
41
+ /** The tile quads for this page, in deterministic row-major order. */
42
+ readonly quads: readonly TileQuad[];
43
+ }
44
+ /** Pack a {@link TileTransform} into a 3-bit orientation code. @internal */
45
+ export declare function orientCode(transform: TileTransform): number;
46
+ /** Read the cumulative chunk-geometry rebuild count. @internal */
47
+ export declare function getTileGeometryRebuildCount(): number;
48
+ /** Reset the chunk-geometry rebuild counter (call before a measured frame). @internal */
49
+ export declare function resetTileGeometryRebuildCount(): void;
50
+ /**
51
+ * Build per-tileset page geometry for a single chunk.
52
+ *
53
+ * Iterates the chunk's packed cells in deterministic row-major order, skipping
54
+ * empties, out-of-range tilesets, and out-of-range local tile ids (all treated
55
+ * as empty — this is the renderer's half of the G-GID contract). Each surviving
56
+ * cell is resolved to its source UV rect (from `tileset.getTileRect` + the
57
+ * tileset `TextureRegion`) and a chunk-local destination rect (bottom-left
58
+ * aligned per Tiled orthogonal semantics, so tilesets whose tiles are taller
59
+ * than the map grid extend upward).
60
+ *
61
+ * Allocation happens here only — the result is cached on the owning
62
+ * {@link import('./TileChunkNode').TileChunkNode} keyed by `chunk.revision`, so
63
+ * unchanged chunks never rebuild and the per-frame path stays allocation-free.
64
+ *
65
+ * @param chunk The readonly chunk view to build from.
66
+ * @param tilesets The layer's tileset array (packed `tilesetIndex` selects one).
67
+ * @param tileWidth Map/layer tile cell width in pixels.
68
+ * @param tileHeight Map/layer tile cell height in pixels.
69
+ * @internal
70
+ */
71
+ export declare function buildChunkPages(chunk: ReadonlyTileChunk, tilesets: readonly TileSet[], tileWidth: number, tileHeight: number): ChunkPage[];
@@ -0,0 +1,98 @@
1
+ import { unpackTile } from './types.js';
2
+
3
+ /** Pack a {@link TileTransform} into a 3-bit orientation code. @internal */
4
+ function orientCode(transform) {
5
+ return (transform.flipX ? 1 : 0) | (transform.flipY ? 2 : 0) | (transform.diagonal ? 4 : 0);
6
+ }
7
+ /**
8
+ * Build per-tileset page geometry for a single chunk.
9
+ *
10
+ * Iterates the chunk's packed cells in deterministic row-major order, skipping
11
+ * empties, out-of-range tilesets, and out-of-range local tile ids (all treated
12
+ * as empty — this is the renderer's half of the G-GID contract). Each surviving
13
+ * cell is resolved to its source UV rect (from `tileset.getTileRect` + the
14
+ * tileset `TextureRegion`) and a chunk-local destination rect (bottom-left
15
+ * aligned per Tiled orthogonal semantics, so tilesets whose tiles are taller
16
+ * than the map grid extend upward).
17
+ *
18
+ * Allocation happens here only — the result is cached on the owning
19
+ * {@link import('./TileChunkNode').TileChunkNode} keyed by `chunk.revision`, so
20
+ * unchanged chunks never rebuild and the per-frame path stays allocation-free.
21
+ *
22
+ * @param chunk The readonly chunk view to build from.
23
+ * @param tilesets The layer's tileset array (packed `tilesetIndex` selects one).
24
+ * @param tileWidth Map/layer tile cell width in pixels.
25
+ * @param tileHeight Map/layer tile cell height in pixels.
26
+ * @internal
27
+ */
28
+ function buildChunkPages(chunk, tilesets, tileWidth, tileHeight) {
29
+ if (chunk.empty) {
30
+ return [];
31
+ }
32
+ const buckets = new Map();
33
+ const width = chunk.width;
34
+ const height = chunk.height;
35
+ for (let ly = 0; ly < height; ly++) {
36
+ for (let lx = 0; lx < width; lx++) {
37
+ const packed = chunk.getRawAt(lx, ly);
38
+ if (packed === 0) {
39
+ continue;
40
+ }
41
+ const decoded = unpackTile(packed);
42
+ if (decoded === null) {
43
+ continue;
44
+ }
45
+ const tileset = tilesets[decoded.tilesetIndex];
46
+ // Out-of-range tileset or local id → treat as empty (G-GID). getTileRect
47
+ // throws on an out-of-range id, so the bounds check must precede it.
48
+ if (tileset === undefined || decoded.localTileId >= tileset.tileCount) {
49
+ continue;
50
+ }
51
+ const region = tileset.texture;
52
+ const texture = region.texture;
53
+ const textureWidth = texture.width;
54
+ const textureHeight = texture.height;
55
+ if (textureWidth <= 0 || textureHeight <= 0) {
56
+ continue;
57
+ }
58
+ const rect = tileset.getTileRect(decoded.localTileId);
59
+ // Absolute source pixel rect = tileset-region offset + in-atlas tile rect.
60
+ const sx = region.x + rect.x;
61
+ const sy = region.y + rect.y;
62
+ // Exact tile UVs, no half-texel inset. This assumes NEAREST filtering on
63
+ // the tileset atlas (the typical pixel-art case). Under LINEAR/mipmap
64
+ // filtering an atlas WITHOUT extrusion padding can bleed neighbouring
65
+ // tiles at the edges; author tilesets with extruded margins for linear
66
+ // sampling. (Extrusion-aware tilemap UV insetting — already done on the
67
+ // NineSlice/RepeatingSprite geometry paths — is a v0.14 follow-up.)
68
+ const u0 = sx / textureWidth;
69
+ const v0 = sy / textureHeight;
70
+ const u1 = (sx + rect.width) / textureWidth;
71
+ const v1 = (sy + rect.height) / textureHeight;
72
+ // Bottom-left aligned destination (Tiled orthogonal). Uniform tiles
73
+ // (rect.height === tileHeight) collapse to a plain cell rect.
74
+ const x0 = lx * tileWidth;
75
+ const y0 = ly * tileHeight + tileHeight - rect.height;
76
+ const x1 = x0 + rect.width;
77
+ const y1 = y0 + rect.height;
78
+ let bucket = buckets.get(tileset);
79
+ if (bucket === undefined) {
80
+ bucket = [];
81
+ buckets.set(tileset, bucket);
82
+ }
83
+ bucket.push({ x0, y0, x1, y1, u0, v0, u1, v1, orient: orientCode(decoded.transform) });
84
+ }
85
+ }
86
+ // Emit pages in tileset-array order for deterministic, reproducible builds.
87
+ const pages = [];
88
+ for (const tileset of tilesets) {
89
+ const quads = buckets.get(tileset);
90
+ if (quads !== undefined && quads.length > 0) {
91
+ pages.push({ tileset, texture: tileset.texture.texture, quads });
92
+ }
93
+ }
94
+ return pages;
95
+ }
96
+
97
+ export { buildChunkPages, orientCode };
98
+ //# sourceMappingURL=chunkGeometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunkGeometry.js","sources":["../../../src/chunkGeometry.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from './public';
@@ -0,0 +1,10 @@
1
+ export { tilemapExtension } from './tilemapExtension.js';
2
+ export { TileLayer } from './TileLayer.js';
3
+ export { TileMap } from './TileMap.js';
4
+ export { TileSet } from './TileSet.js';
5
+ export { TileLayerNode } from './TileLayerNode.js';
6
+ export { TileMapNode } from './TileMapNode.js';
7
+ export { TileMapBand } from './TileMapBand.js';
8
+ export { TileMapView } from './TileMapView.js';
9
+ export { TILE_TRANSFORM_IDENTITY, tileToChunkCoord, tileToLocalInChunk } from './types.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,12 @@
1
+ import type { PixelSnapMode } from '@codexo/exojs/rendering';
2
+ /**
3
+ * Throw a deterministic error when `mode` is not a valid {@link PixelSnapMode}.
4
+ *
5
+ * Mirrors the core `Drawable` setter's guard so the tilemap node passthroughs
6
+ * (`TileMapView` / `TileMapNode` / `TileLayerNode`) reject JavaScript-invalid
7
+ * values atomically — even for an empty layer that has no chunk drawable to
8
+ * delegate the validation to. Kept local because the core guard is not part of
9
+ * the public API surface.
10
+ * @internal
11
+ */
12
+ export declare function assertPixelSnapMode(mode: PixelSnapMode): void;
@@ -0,0 +1,19 @@
1
+ const validPixelSnapModes = new Set(['none', 'position', 'geometry']);
2
+ /**
3
+ * Throw a deterministic error when `mode` is not a valid {@link PixelSnapMode}.
4
+ *
5
+ * Mirrors the core `Drawable` setter's guard so the tilemap node passthroughs
6
+ * (`TileMapView` / `TileMapNode` / `TileLayerNode`) reject JavaScript-invalid
7
+ * values atomically — even for an empty layer that has no chunk drawable to
8
+ * delegate the validation to. Kept local because the core guard is not part of
9
+ * the public API surface.
10
+ * @internal
11
+ */
12
+ function assertPixelSnapMode(mode) {
13
+ if (typeof mode !== 'string' || !validPixelSnapModes.has(mode)) {
14
+ throw new Error(`pixelSnapMode must be 'none', 'position', or 'geometry' (got ${String(mode)}).`);
15
+ }
16
+ }
17
+
18
+ export { assertPixelSnapMode };
19
+ //# sourceMappingURL=pixelSnap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixelSnap.js","sources":["../../../src/pixelSnap.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEA,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAS,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAElG;;;;;;;;;AASG;AACG,SAAU,mBAAmB,CAAC,IAAmB,EAAA;AACrD,IAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAC9D,MAAM,IAAI,KAAK,CAAC,CAAA,6DAAA,EAAgE,MAAM,CAAC,IAAI,CAAC,CAAA,EAAA,CAAI,CAAC;IACnG;AACF;;;;"}
@@ -0,0 +1,18 @@
1
+ export { tilemapExtension } from './tilemapExtension';
2
+ export type { Extension } from '@codexo/exojs/extensions';
3
+ export type { ReadonlyTileChunk } from './TileChunk';
4
+ export type { TileLayerOptions } from './TileLayer';
5
+ export { TileLayer } from './TileLayer';
6
+ export type { TileMapOptions } from './TileMap';
7
+ export { TileMap } from './TileMap';
8
+ export type { TileSetOptions } from './TileSet';
9
+ export { TileSet } from './TileSet';
10
+ export type { TileLayerNodeOptions } from './TileLayerNode';
11
+ export { TileLayerNode } from './TileLayerNode';
12
+ export type { TileMapNodeOptions } from './TileMapNode';
13
+ export { TileMapNode } from './TileMapNode';
14
+ export { TileMapBand } from './TileMapBand';
15
+ export type { TileLayerSelector, TileMapBandDefinition, TileMapViewOptions, } from './TileMapView';
16
+ export { TileMapView } from './TileMapView';
17
+ export type { ChunkCoord, PackedTile, ResolvedTile, TileDefinition, TileProperties, TilePropertyValue, TileTransform, } from './types';
18
+ export { TILE_TRANSFORM_IDENTITY, tileToChunkCoord, tileToLocalInChunk, } from './types';
@@ -0,0 +1 @@
1
+ export * from './public';
@@ -0,0 +1,20 @@
1
+ import { ExtensionRegistry } from '@codexo/exojs/extensions';
2
+ import { tilemapExtension } from './tilemapExtension.js';
3
+ export { TileLayer } from './TileLayer.js';
4
+ export { TileMap } from './TileMap.js';
5
+ export { TileSet } from './TileSet.js';
6
+ export { TileLayerNode } from './TileLayerNode.js';
7
+ export { TileMapNode } from './TileMapNode.js';
8
+ export { TileMapBand } from './TileMapBand.js';
9
+ export { TileMapView } from './TileMapView.js';
10
+ export { TILE_TRANSFORM_IDENTITY, tileToChunkCoord, tileToLocalInChunk } from './types.js';
11
+
12
+ // @codexo/exojs-tilemap/register — explicit registration entry.
13
+ // Importing this entry registers the default tilemapExtension descriptor
14
+ // in the global ExtensionRegistry. Subsequently constructed Applications
15
+ // that use global defaults will receive the tilemap extension.
16
+ // This is the only side-effectful entry in this package.
17
+ ExtensionRegistry.register(tilemapExtension);
18
+
19
+ export { tilemapExtension };
20
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sources":["../../../src/register.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AAMA,iBAAiB,CAAC,QAAQ,CAAC,gBAAgB,CAAC;;;;"}
@@ -0,0 +1,18 @@
1
+ import type { Extension } from '@codexo/exojs/extensions';
2
+ /**
3
+ * Default immutable tilemap extension descriptor.
4
+ *
5
+ * Registers the WebGL2/WebGPU tile chunk renderers (`renderers`); it carries no
6
+ * asset bindings — there is no generic on-disk tilemap format in this slice, so
7
+ * format adapters (e.g. `@codexo/exojs-tiled`) own loading and depend on this
8
+ * descriptor to pull in rendering.
9
+ *
10
+ * Install + register directly for procedural / hand-built maps
11
+ * (`extensions: [tilemapExtension]` plus a `TileMap` built via the runtime), or
12
+ * receive it transitively through a format adapter's `dependencies`.
13
+ *
14
+ * Use with `ApplicationOptions.extensions` or call
15
+ * `import '@codexo/exojs-tilemap/register'` for global auto-registration.
16
+ * @advanced
17
+ */
18
+ export declare const tilemapExtension: Extension;
@@ -0,0 +1,52 @@
1
+ import { RenderBackendType } from '@codexo/exojs/rendering';
2
+ import { TileChunkNode } from './TileChunkNode.js';
3
+ import { WebGl2TileChunkRenderer } from './webgl2/WebGl2TileChunkRenderer.js';
4
+ import { WebGpuTileChunkRenderer } from './webgpu/WebGpuTileChunkRenderer.js';
5
+
6
+ /** Per-tile instance batch size for the WebGL2 tile chunk renderer. */
7
+ const tileRendererBatchSize = 4096;
8
+ /**
9
+ * Build the renderer binding that wires the per-backend
10
+ * {@link import('./TileChunkNode').TileChunkNode} renderers. The binding targets
11
+ * the internal chunk drawable; applications never construct it directly — they
12
+ * build {@link import('./TileMapNode').TileMapNode} /
13
+ * {@link import('./TileLayerNode').TileLayerNode}, whose chunk children resolve
14
+ * to this renderer through the registry prototype walk.
15
+ */
16
+ function buildTileChunkRendererBinding(batchSize) {
17
+ return {
18
+ targets: [TileChunkNode],
19
+ create(backend) {
20
+ if (backend.backendType === RenderBackendType.WebGl2) {
21
+ return new WebGl2TileChunkRenderer(batchSize);
22
+ }
23
+ if (backend.backendType === RenderBackendType.WebGpu) {
24
+ return new WebGpuTileChunkRenderer();
25
+ }
26
+ throw new Error(`Unsupported render backend: ${String(backend.backendType)}`);
27
+ },
28
+ };
29
+ }
30
+ /**
31
+ * Default immutable tilemap extension descriptor.
32
+ *
33
+ * Registers the WebGL2/WebGPU tile chunk renderers (`renderers`); it carries no
34
+ * asset bindings — there is no generic on-disk tilemap format in this slice, so
35
+ * format adapters (e.g. `@codexo/exojs-tiled`) own loading and depend on this
36
+ * descriptor to pull in rendering.
37
+ *
38
+ * Install + register directly for procedural / hand-built maps
39
+ * (`extensions: [tilemapExtension]` plus a `TileMap` built via the runtime), or
40
+ * receive it transitively through a format adapter's `dependencies`.
41
+ *
42
+ * Use with `ApplicationOptions.extensions` or call
43
+ * `import '@codexo/exojs-tilemap/register'` for global auto-registration.
44
+ * @advanced
45
+ */
46
+ const tilemapExtension = Object.freeze({
47
+ id: '@codexo/exojs-tilemap',
48
+ renderers: [buildTileChunkRendererBinding(tileRendererBatchSize)],
49
+ });
50
+
51
+ export { tilemapExtension };
52
+ //# sourceMappingURL=tilemapExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tilemapExtension.js","sources":["../../../src/tilemapExtension.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;AAQA;AACA,MAAM,qBAAqB,GAAG,IAAI;AAElC;;;;;;;AAOG;AACH,SAAS,6BAA6B,CAAC,SAAiB,EAAA;IACtD,OAAO;QACL,OAAO,EAAE,CAAC,aAAa,CAAC;AACxB,QAAA,MAAM,CAAC,OAAsB,EAAA;YAC3B,IAAI,OAAO,CAAC,WAAW,KAAK,iBAAiB,CAAC,MAAM,EAAE;AACpD,gBAAA,OAAO,IAAI,uBAAuB,CAAC,SAAS,CAAC;YAC/C;YAEA,IAAI,OAAO,CAAC,WAAW,KAAK,iBAAiB,CAAC,MAAM,EAAE;gBACpD,OAAO,IAAI,uBAAuB,EAAE;YACtC;AAEA,YAAA,MAAM,IAAI,KAAK,CAAC,CAAA,4BAAA,EAA+B,MAAM,CAAC,OAAO,CAAC,WAA2B,CAAC,CAAA,CAAE,CAAC;QAC/F,CAAC;KACF;AACH;AAEA;;;;;;;;;;;;;;;AAeG;AACI,MAAM,gBAAgB,GAAc,MAAM,CAAC,MAAM,CAAC;AACvD,IAAA,EAAE,EAAE,uBAAuB;AAC3B,IAAA,SAAS,EAAE,CAAC,6BAA6B,CAAC,qBAAqB,CAAC,CAAC;AAClE,CAAA;;;;"}
@@ -0,0 +1,139 @@
1
+ import type { TileSet } from './TileSet';
2
+ /**
3
+ * Union of legal tile-property value types in the generic runtime.
4
+ * Format-neutral; adapters map their native property systems into this set.
5
+ * @advanced
6
+ */
7
+ export type TilePropertyValue = null | boolean | number | string;
8
+ /**
9
+ * An immutable, flat key-value bag of generic tile properties.
10
+ * Adapters copy and freeze source properties; the runtime never retains
11
+ * a caller-owned mutable object.
12
+ * @advanced
13
+ */
14
+ export type TileProperties = Readonly<Record<string, TilePropertyValue>>;
15
+ /**
16
+ * Describes the orientation of a placed tile independent of source-format
17
+ * flip-bit encodings. The eight legal combinations map to the eight distinct
18
+ * 90°-rotation-and-flip states of a rectangular texture quad.
19
+ *
20
+ * Applying the transform at geometry-build time (reordering UV corners)
21
+ * avoids per-tile runtime cost and per-frame matrix allocation.
22
+ * @stable
23
+ */
24
+ export interface TileTransform {
25
+ /** Horizontal flip (mirror left-right). */
26
+ readonly flipX: boolean;
27
+ /** Vertical flip (mirror top-bottom). */
28
+ readonly flipY: boolean;
29
+ /** Anti-diagonal flip (transpose of the UV axes). Combined with flips produces 90° rotations. */
30
+ readonly diagonal: boolean;
31
+ }
32
+ /** The identity transform: no flip, no diagonal. */
33
+ export declare const TILE_TRANSFORM_IDENTITY: Readonly<TileTransform>;
34
+ /**
35
+ * Short string label for a {@link TileTransform} (debug / serialisation).
36
+ * Returns one of the eight deterministic names, e.g. `"flipX"` or `"diag+flipX+flipY"`.
37
+ * @internal
38
+ */
39
+ export declare function tileTransformLabel(t: TileTransform): string;
40
+ /**
41
+ * Opaque packed tile data stored in a {@link TileChunk}'s compact array.
42
+ * 0 means "empty cell". Any non-zero value encodes localTileId, tilesetIndex,
43
+ * and flip bits according to the bit-layout constants below.
44
+ *
45
+ * A `PackedTile` is **not** a source-format GID — it is a fully resolved
46
+ * internal compact representation. Use {@link packTile} / {@link unpackTile}
47
+ * (package-internal) to convert between packed form and a {@link ResolvedTile}
48
+ * if writing adapters.
49
+ *
50
+ * In public APIs, prefer {@link ResolvedTile} or null for queries.
51
+ * `PackedTile` is exposed as `@advanced` so `ReadonlyTileChunk.getRawAt()`
52
+ * has a self-documenting return type.
53
+ * @advanced
54
+ */
55
+ export type PackedTile = number;
56
+ /** Bit width allocated to the local tile ID within a packed tile word. */
57
+ export declare const PACKED_LOCAL_BITS = 20;
58
+ /** Bit width allocated to the tileset index within a packed tile word. */
59
+ export declare const PACKED_TILESET_BITS = 9;
60
+ /** Bit width allocated to the transform/flip bits. */
61
+ export declare const PACKED_TRANSFORM_BITS = 3;
62
+ export declare const PACKED_LOCAL_MASK: number;
63
+ export declare const PACKED_TILESET_MASK: number;
64
+ export declare const PACKED_TRANSFORM_MASK: number;
65
+ export declare const PACKED_TILESET_SHIFT = 20;
66
+ export declare const PACKED_TRANSFORM_SHIFT: number;
67
+ /** Maximum tileset index representable in a packed tile. */
68
+ export declare const MAX_TILESET_INDEX: number;
69
+ /** Maximum local tile ID representable in a packed tile (1-based storage). */
70
+ export declare const MAX_LOCAL_TILE_ID: number;
71
+ /**
72
+ * Encode a tileset-local tile reference and transform into a packed word.
73
+ * The localTileId is stored as (localTileId + 1) so that a packed value of 0
74
+ * cleanly represents an empty cell, while tile 0 from tileset 0 with identity
75
+ * transform is stored as 1 (non-zero).
76
+ * Returns 0 for an empty cell.
77
+ * @internal
78
+ */
79
+ export declare function packTile(tilesetIndex: number, localTileId: number, transform: TileTransform): PackedTile;
80
+ /**
81
+ * Decode a packed word into its components.
82
+ * Returns null for an empty cell (packed === 0).
83
+ * @internal
84
+ */
85
+ export declare function unpackTile(packed: PackedTile): {
86
+ tilesetIndex: number;
87
+ localTileId: number;
88
+ transform: TileTransform;
89
+ } | null;
90
+ /**
91
+ * A fully resolved, format-independent tile reference returned by queries.
92
+ * Materialised on-demand from the packed storage; never stored as a per-cell
93
+ * heap object.
94
+ * @advanced
95
+ */
96
+ export interface ResolvedTile {
97
+ /** The owning tileset (already resolved from source-format GID). */
98
+ readonly tileset: TileSet;
99
+ /** 0-based tile index within the tileset. */
100
+ readonly localTileId: number;
101
+ /** Orientation transform for this placed tile. */
102
+ readonly transform: TileTransform;
103
+ }
104
+ /**
105
+ * Optional per-tile metadata in a {@link TileSet}. Sparse — only defined
106
+ * tiles carry a definition. May carry animation data in future slices.
107
+ * @advanced
108
+ */
109
+ export interface TileDefinition {
110
+ /** The local tile ID this definition belongs to. */
111
+ readonly localTileId: number;
112
+ /** Tile properties (copied and frozen by the tileset). */
113
+ readonly properties?: TileProperties;
114
+ }
115
+ /** A signed chunk coordinate pair. */
116
+ export interface ChunkCoord {
117
+ readonly cx: number;
118
+ readonly cy: number;
119
+ }
120
+ /** Convert tile coordinates to chunk coordinates given a chunk size. */
121
+ export declare function tileToChunkCoord(tx: number, ty: number, chunkW: number, chunkH: number): ChunkCoord;
122
+ /** Convert tile coordinates to local-in-chunk coordinates. */
123
+ export declare function tileToLocalInChunk(tx: number, ty: number, chunkW: number, chunkH: number): {
124
+ lx: number;
125
+ ly: number;
126
+ };
127
+ /**
128
+ * Validate that a value is a finite, safe, positive integer.
129
+ * Used for dimensions, tile counts, chunk sizes.
130
+ */
131
+ export declare function validatePositiveInteger(value: number, label: string): void;
132
+ /**
133
+ * Validate a non-negative finite integer.
134
+ */
135
+ export declare function validateNonNegativeInteger(value: number, label: string): void;
136
+ /**
137
+ * Validate that a value is a finite integer (may be negative).
138
+ */
139
+ export declare function validateInteger(value: number, label: string): void;
@@ -0,0 +1,121 @@
1
+ /** The identity transform: no flip, no diagonal. */
2
+ const TILE_TRANSFORM_IDENTITY = Object.freeze({
3
+ flipX: false,
4
+ flipY: false,
5
+ diagonal: false,
6
+ });
7
+ /** Bit width allocated to the local tile ID within a packed tile word. */
8
+ const PACKED_LOCAL_BITS = 20;
9
+ /** Bit width allocated to the tileset index within a packed tile word. */
10
+ const PACKED_TILESET_BITS = 9;
11
+ /** Bit width allocated to the transform/flip bits. */
12
+ const PACKED_TRANSFORM_BITS = 3;
13
+ const PACKED_LOCAL_MASK = (1 << PACKED_LOCAL_BITS) - 1;
14
+ const PACKED_TILESET_MASK = ((1 << PACKED_TILESET_BITS) - 1) << PACKED_LOCAL_BITS;
15
+ const PACKED_TRANSFORM_MASK = ((1 << PACKED_TRANSFORM_BITS) - 1) << (PACKED_LOCAL_BITS + PACKED_TILESET_BITS);
16
+ const PACKED_TILESET_SHIFT = PACKED_LOCAL_BITS;
17
+ const PACKED_TRANSFORM_SHIFT = PACKED_LOCAL_BITS + PACKED_TILESET_BITS;
18
+ /** Maximum tileset index representable in a packed tile. */
19
+ const MAX_TILESET_INDEX = (1 << PACKED_TILESET_BITS) - 1;
20
+ /** Maximum local tile ID representable in a packed tile (1-based storage). */
21
+ const MAX_LOCAL_TILE_ID = (1 << PACKED_LOCAL_BITS) - 2;
22
+ // Transform bit-field values (bit 0 = flipX, bit 1 = flipY, bit 2 = diagonal).
23
+ const TRANSFORM_FLIP_X = 1 << 0;
24
+ const TRANSFORM_FLIP_Y = 1 << 1;
25
+ const TRANSFORM_DIAGONAL = 1 << 2;
26
+ /**
27
+ * Encode a tileset-local tile reference and transform into a packed word.
28
+ * The localTileId is stored as (localTileId + 1) so that a packed value of 0
29
+ * cleanly represents an empty cell, while tile 0 from tileset 0 with identity
30
+ * transform is stored as 1 (non-zero).
31
+ * Returns 0 for an empty cell.
32
+ * @internal
33
+ */
34
+ function packTile(tilesetIndex, localTileId, transform) {
35
+ if (tilesetIndex < 0 || tilesetIndex > MAX_TILESET_INDEX) {
36
+ throw new Error(`Tileset index ${tilesetIndex} exceeds maximum ${MAX_TILESET_INDEX}.`);
37
+ }
38
+ if (localTileId < 0 || localTileId > MAX_LOCAL_TILE_ID) {
39
+ throw new Error(`Local tile ID ${localTileId} exceeds maximum ${MAX_LOCAL_TILE_ID}.`);
40
+ }
41
+ let bits = 0;
42
+ if (transform.flipX)
43
+ bits |= TRANSFORM_FLIP_X;
44
+ if (transform.flipY)
45
+ bits |= TRANSFORM_FLIP_Y;
46
+ if (transform.diagonal)
47
+ bits |= TRANSFORM_DIAGONAL;
48
+ // +1 so 0 means "empty" not "tile 0 without transform"
49
+ const storedId = localTileId + 1;
50
+ return (storedId & PACKED_LOCAL_MASK)
51
+ | ((tilesetIndex << PACKED_TILESET_SHIFT) & PACKED_TILESET_MASK)
52
+ | ((bits << PACKED_TRANSFORM_SHIFT) & PACKED_TRANSFORM_MASK);
53
+ }
54
+ /**
55
+ * Decode a packed word into its components.
56
+ * Returns null for an empty cell (packed === 0).
57
+ * @internal
58
+ */
59
+ function unpackTile(packed) {
60
+ if (packed === 0)
61
+ return null;
62
+ const storedId = packed & PACKED_LOCAL_MASK;
63
+ // Undo the +1 offset applied during packTile.
64
+ const localTileId = storedId - 1;
65
+ const tilesetIndex = (packed & PACKED_TILESET_MASK) >>> PACKED_TILESET_SHIFT;
66
+ const rawTransform = (packed & PACKED_TRANSFORM_MASK) >>> PACKED_TRANSFORM_SHIFT;
67
+ return {
68
+ tilesetIndex,
69
+ localTileId,
70
+ transform: {
71
+ flipX: !!(rawTransform & TRANSFORM_FLIP_X),
72
+ flipY: !!(rawTransform & TRANSFORM_FLIP_Y),
73
+ diagonal: !!(rawTransform & TRANSFORM_DIAGONAL),
74
+ },
75
+ };
76
+ }
77
+ /** Convert tile coordinates to chunk coordinates given a chunk size. */
78
+ function tileToChunkCoord(tx, ty, chunkW, chunkH) {
79
+ return {
80
+ cx: Math.floor(tx / chunkW),
81
+ cy: Math.floor(ty / chunkH),
82
+ };
83
+ }
84
+ /** Convert tile coordinates to local-in-chunk coordinates. */
85
+ function tileToLocalInChunk(tx, ty, chunkW, chunkH) {
86
+ return {
87
+ lx: ((tx % chunkW) + chunkW) % chunkW,
88
+ ly: ((ty % chunkH) + chunkH) % chunkH,
89
+ };
90
+ }
91
+ /**
92
+ * Validate that a value is a finite, safe, positive integer.
93
+ * Used for dimensions, tile counts, chunk sizes.
94
+ */
95
+ function validatePositiveInteger(value, label) {
96
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {
97
+ throw new Error(`${label} must be a positive integer (got ${value}).`);
98
+ }
99
+ if (value > Number.MAX_SAFE_INTEGER) {
100
+ throw new Error(`${label} exceeds safe integer range (got ${value}).`);
101
+ }
102
+ }
103
+ /**
104
+ * Validate a non-negative finite integer.
105
+ */
106
+ function validateNonNegativeInteger(value, label) {
107
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {
108
+ throw new Error(`${label} must be a non-negative integer (got ${value}).`);
109
+ }
110
+ }
111
+ /**
112
+ * Validate that a value is a finite integer (may be negative).
113
+ */
114
+ function validateInteger(value, label) {
115
+ if (!Number.isFinite(value) || !Number.isInteger(value)) {
116
+ throw new Error(`${label} must be a finite integer (got ${value}).`);
117
+ }
118
+ }
119
+
120
+ export { MAX_LOCAL_TILE_ID, MAX_TILESET_INDEX, PACKED_LOCAL_BITS, PACKED_LOCAL_MASK, PACKED_TILESET_BITS, PACKED_TILESET_MASK, PACKED_TILESET_SHIFT, PACKED_TRANSFORM_BITS, PACKED_TRANSFORM_MASK, PACKED_TRANSFORM_SHIFT, TILE_TRANSFORM_IDENTITY, packTile, tileToChunkCoord, tileToLocalInChunk, unpackTile, validateInteger, validateNonNegativeInteger, validatePositiveInteger };
121
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":["../../../src/types.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}