Skip to content

Public API tier table

declarative-hex-worlds publishes one umbrella entry plus a wide set of subpath exports. Every subpath stays supported through 1.0 — this is an asset-bundled library where mod authors, custom-renderer builders, and data-inspection tooling all have legitimate reasons to reach internals.

What changes between tiers is the stability contract, not the availability. Pick the tier that matches your tolerance for breakage; the tooling and TSDoc tags tell you which tier a symbol belongs to.

Semver-strict. Breaking changes only on major versions, always with a migration guide.

SubpathPurpose
. (umbrella)Default entry. Re-exports the consumer-facing surface from every tier-1 sub-package.
./reactReact bindings. First-class (NOT peer-gated). Hooks, providers, components.
./threeThree.js bindings. First-class (NOT peer-gated). Loaders, disposers, scene helpers.
./cliCLI entry (also installed as the declarative-hex-worlds bin).
./manifest/schemaMedievalHexagonManifest shape + validators.
./manifest/freePre-baked FREE-edition manifest metadata.
./scenarioGameboardScenario, blueprint/recipe/catalog/registry.
./blueprintGameboardBlueprintOptions and procedural board generation.
./gameboardBoard lifecycle, occupancy, navigation.
./recipeRecipe DSL.
./coverageRelease-readiness coverage ledger surface.
./compatibilityManifest/version compatibility helpers.
./errorsGameboardError + typed subclasses (Epic D2).
./traitsSingle trait umbrella (all trait() declarations).
./typesShared primitive types + branded IDs (HexKey, ActorId, etc.).
./examples/*.jsonBundled example scenario JSON.

TSDoc tag: @public.

Semver-strict for what’s documented, but the surface contract is smaller than tier 1. Mod authors and custom-renderer consumers can depend on these; breaking changes still require a major + migration guide but the “what’s breaking” frame may be narrower (a specific function signature changing rather than the whole module shape).

SubpathPurpose
./kootaWorld bootstrap, trait sets, query patterns.
./runtimeHigh-level runtime composition.
./actorsActor surface + queries.
./movementMovement-agent surface.
./patrolPatrol-route surface.
./questsQuest surface.
./piecesPiece declarations + placement helpers.
./projectionWorld-space placement projection.
./layoutSeeded board layout generation.
./gridHoneycomb-grid wrappers + hex algebra.
./coordinatesHex coordinate algebra (umbrella over grid/projection/layout).
./validationPlan-level validators.
./rulesRule definitions + evaluation.

TSDoc tag: @public (no distinct tag — tier 2 is documented here in the table, not on every symbol).

Semver-permissive: minor versions may change these surfaces in non-trivial ways. Consumers who pin tier-3 imports accept this tradeoff. Useful for very-deep modding, debugging, and tools that need to inspect or hook the implementation.

SubpathPurpose
./commandsInternal command-factory plumbing.
./selectorsPer-render shape pickers used by React/Three bindings.
./systemsTickable system functions.
./world-rulesRuntime rule-evaluation system.
./rule-typesRule typed shapes (re-exported from ./rules — prefer that).
./interopSchema migrations + ECS adapter glue.
./ingestSource-tree walker + manifest emission (precursor to bootstrap).
./registryTile/piece registries (re-exported from ./scenario).
./catalogKayKit asset catalog (re-exported from ./scenario).

TSDoc tag: @internal (still exported, still typed, still tested — just flagged so consumers see the support tier inline).

Phase 1’s architecture review (F1) noted that the 37+ subpath exports permanently pin every internal module as a semver surface point. The original recommendation was to demote ~10 subpaths and force everything through the umbrella.

Per PRD §4 Epic D1 (re-scoped), that was rejected: this library bundles the FREE KayKit pack so consumers get a working game out-of-box, and the “out-of-box” promise extends to consumers who want to reach internals for legitimate reasons (custom renderers, modding, data inspection). The right tradeoff is documented tiering, not gated demotion.

If a tier-3 surface stabilizes (a custom-renderer mod has been depending on ./selectors for two minor versions without breakage), it can be promoted to tier 2 via a CHANGELOG note. The reverse (demoting a tier-1 surface) is a major-version event.

Regardless of tier, every trait() declaration is exported from exactly one module. tsup’s splitting: true keeps shared chunks stable so that two consumers importing GameboardActor from different subpaths (e.g. one via ./actors, another via the umbrella) get the SAME trait identity — which is what koota’s useQuery reference-equality lookups depend on.

Don’t try to “optimize” by re-declaring a trait somewhere else. Don’t fork the trait file into a “local” copy. The trait-identity test (Epic E4, pending) pins this.