src/cli/commands/bootstrap/upstream-layout
declarative-hex-worlds / src/cli/commands/bootstrap/upstream-layout
src/cli/commands/bootstrap/upstream-layout
Typed description of the KayKit pack upstream layouts (RFC0-10).
Remarks
The library bootstraps assets at install time by mirroring the upstream GitHub source tree (or a user-supplied zip with identical layout) into the consumer's asset root. Two layout SHAPES are supported:
- Medieval Hexagon (
detection: 'medieval', the default): a top-level pack directory containingAssets/,Textures/,Samples/, marker files (License.txt, PDFs,contents_*.jpg), category subdirs underAssets/gltf/(tiles/buildings/decoration, +units/ for EXTRA), and textures in a separateTextures/. Detected via markers OR the primary texture. - Character pack (
detection: 'character', via characterPackLayout): the Adventurers/Skeletons shape. Verified against the real cloned repos (2026-07): a character pack ships TWO renderable gltf trees —Assets/gltf/(weapons/shields/accessories,.gltf+.bin+inline.png) ANDCharacters/gltf/(the character BODIES:Barbarian.glb,Knight.glb,Mage.glb,Rogue.glb, … as self-contained.glbwith embedded textures, plus sibling*_texture.png). Because a single hardcodedrelativeGltfRootsilently DROPPED every character body, a character layout setsmirrorAllGltfDirs: true: the mirror SCANS the pack root and mirrors every directory that contains a renderable.gltf/.glb, deriving the shape from the actual tree rather than a guessed constant. Detected by the presence of any.gltf/.glbunder relativeGltfRoot.
Renderable trees (.gltf/.glb + .bin + inline .png) are mirrored;
source-format trees (fbx, fbx(unity), obj) and Samples/ are filtered
out unless includeSourceFormats is set.
Interfaces
KayKitUpstreamLayout
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:42
Structural description of a single KayKit Medieval Hexagon pack edition as it appears on disk after extraction.
Properties
assetCategories
readonlyassetCategories: readonlystring[]
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:54
Asset category subdirectory names found directly under relativeGltfRoot.
detection?
readonlyoptionaldetection?:"medieval"|"character"
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:70
Detection strategy (RFC0-10). 'medieval' (default) uses the marker/texture +
required-category rules below — the Medieval Hexagon shape. 'character'
matches a flat Assets/gltf/ with ≥1 .gltf and no category/marker
requirements — the KayKit character packs (Adventurers/Skeletons), which ship
textures inline in Assets/gltf/ and carry no edition markers.
displayName
readonlydisplayName:string
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:46
Human-readable edition label (e.g. FREE, EXTRA).
editionName
readonlyeditionName:"free"|"extra"
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:44
Edition this layout describes.
expectedBinCount
readonlyexpectedBinCount:number
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:60
Expected total number of .bin companions under relativeGltfRoot.
expectedGltfCount
readonlyexpectedGltfCount:number
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:58
Expected total number of .gltf files under relativeGltfRoot.
markerFiles
readonlymarkerFiles: readonlystring[]
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:56
Files used as markers when detecting which edition a pack root belongs to.
mirrorAllGltfDirs?
readonlyoptionalmirrorAllGltfDirs?:boolean
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:80
When true, the mirror ignores relativeGltfRoot as a single source
and instead SCANS the pack root for every directory containing a renderable
.gltf/.glb, mirroring each (path preserved relative to the pack root).
This is how a character pack captures BOTH Assets/gltf/ (weapons) and
Characters/gltf/ (bodies) — the layout is derived from the real tree, not a
declared constant. Source-format dirs (fbx, obj, Samples) are excluded
by extension/name during the walk.
packFolderName
readonlypackFolderName:string
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:48
Top-level pack folder name as published by KayKit.
relativeGltfRoot
readonlyrelativeGltfRoot:string
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:50
Relative path under the pack root where .gltf assets live.
relativeTextureRoot
readonlyrelativeTextureRoot:string
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:52
Relative path under the pack root where shared .png textures live.
textureFiles
readonlytextureFiles: readonlystring[]
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:62
Texture filenames published with this edition's Textures/ directory.
Variables
KAYKIT_MEDIEVAL_EXTRA_LAYOUT
constKAYKIT_MEDIEVAL_EXTRA_LAYOUT:KayKitUpstreamLayout=UPSTREAM_LAYOUTS.extra
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:99
KayKit Medieval Hexagon Pack — EXTRA edition layout (purchased on itch.io).
Adds the units/ category, three seasonal texture variants, and a
contents_units.jpg + contents_textures.jpg marker pair. Otherwise
structurally identical to the FREE edition. Sourced from
src/config/upstream-layouts.json.
KAYKIT_MEDIEVAL_FREE_LAYOUT
constKAYKIT_MEDIEVAL_FREE_LAYOUT:KayKitUpstreamLayout=UPSTREAM_LAYOUTS.free
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:89
KayKit Medieval Hexagon Pack — FREE edition layout (CC0).
Mirrors https://github.com/KayKit-Game-Assets/KayKit-Medieval-Hexagon-Pack-1.0.
Values are sourced from src/config/upstream-layouts.json.
KAYKIT_UPSTREAM_LAYOUTS
constKAYKIT_UPSTREAM_LAYOUTS: readonlyKayKitUpstreamLayout[]
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:104
All supported KayKit upstream layouts, in declaration order.
Functions
characterPackLayout()
characterPackLayout(
packFolderName):KayKitUpstreamLayout
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:120
Build an upstream layout for a KayKit CHARACTER pack (Adventurers, Skeletons —
RFC0-10). Verified against the cloned repos: a character pack has TWO
renderable gltf trees under addons/<packFolderName>/ — Assets/gltf/
(weapons/accessories) and Characters/gltf/ (the .glb character bodies with
embedded textures). detection: 'character' matches on "the Assets/gltf
root exists with ≥1 .gltf/.glb"; mirrorAllGltfDirs: true then makes the
mirror SCAN for every renderable-gltf directory (so Characters/gltf/ is
captured too — a single hardcoded root dropped the bodies). Counts are 0
(irrelevant for character packs); the mirror walks recursively regardless.
Parameters
packFolderName
string
Returns
detectKayKitLayout()
detectKayKitLayout(
rootPath):KayKitUpstreamLayout|undefined
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:155
Inspect a candidate pack root and return its matching layout descriptor.
Detection rule: a candidate matches a layout when the GLTF category
directories exist AND at least one of two provenance signals is present:
A) All KayKitUpstreamLayout.markerFiles exist (itch.io zip).
B) The primary texture file exists under
KayKitUpstreamLayout.relativeTextureRoot (GitHub archive — omits
License.txt, PDFs, and contents_*.jpg but includes the texture).
EXTRA is tested before FREE (EXTRA categories are a superset of FREE's).
Parameters
rootPath
string
Returns
KayKitUpstreamLayout | undefined
detectLayoutFrom()
detectLayoutFrom(
rootPath,candidates):KayKitUpstreamLayout|undefined
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:165
Detect which of the given candidate layouts a pack root matches (RFC0-10).
detectKayKitLayout is the medieval-hexagon-only default; the pack bootstrap
passes its specific target layout (e.g. a character-pack layout) so a
non-medieval pack is detected against the right shape.
Parameters
rootPath
string
candidates
readonly KayKitUpstreamLayout[]
Returns
KayKitUpstreamLayout | undefined
expectedTexturePaths()
expectedTexturePaths(
rootPath,layout): readonlystring[]
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:185
List the texture files that should appear under
<root>/<relativeTextureRoot> for a given layout. Returns the absolute
paths so callers can verify presence + checksum.
Parameters
rootPath
string
layout
Returns
readonly string[]
kayKitLayoutForEdition()
kayKitLayoutForEdition(
edition):KayKitUpstreamLayout
Defined in: packages/declarative-hex-worlds/src/cli/commands/bootstrap/upstream-layout.ts:140
Resolve the canonical layout descriptor for a known pack edition.
Parameters
edition
"free" | "extra"
