declarative-hex-worlds
v1.2.0
Published
Declarative React Three Fiber binding for 2.5D hex worlds — proxies koota (ECS) + honeycomb (hex math) + three/R3F behind first-class <HexWorld>/<Tile>/<Model> elements and a source-agnostic GLTF/tileset asset layer. Includes a runtime-free ./core tier (k
Maintainers
Readme
declarative-hex-worlds
Declarative, deterministic hex worlds for TypeScript games. Bind any assets — your own, or the suggested CC0 KayKit packs — to a hex world. First-class React + Three.js bindings.
A deterministic gameboard runtime for TypeScript games. Declare a harbor, a procedural forest, or a multi-depth cliff once; the library compiles it through recipe → blueprint → scenario into a koota ECS world your React + Three.js stack renders.
Read the docs → · Browse features → · API reference →
Quickstart
pnpm add declarative-hex-worlds
pnpm exec declarative-hex-worlds bootstrap --out public/assets/modelsimport { useEffect } from 'react';
import { Canvas } from '@react-three/fiber';
// Core (renderer-free): worldgen + runtime signals. No renderer installed for this import.
import { createGameboardBuilder, createGameboardRuntime } from 'declarative-hex-worlds';
// React bindings subscribe to the runtime's koota signals — the `/react` subpath
// (react is an OPTIONAL peer; you only install it if you import a binding subpath).
import { GameboardRuntimeProvider, useGameboardRuntime } from 'declarative-hex-worlds/react';
const plan = createGameboardBuilder({
seed: 'harbor-village-1',
shape: { kind: 'rectangle', width: 6, height: 6 },
}).build();
const runtime = createGameboardRuntime(plan);
export function HarborBoard() {
return (
<GameboardRuntimeProvider runtime={runtime}>
<Canvas><Scene /></Canvas>
</GameboardRuntimeProvider>
);
}
function Scene() {
const rt = useGameboardRuntime();
useEffect(() => { rt.tick(); }, [rt]);
return null; // subscribe to rt signals via a binding (declarative-hex-worlds/three) to draw
}That's it. The bootstrap command mirrors the 221 KayKit FREE models (456 files including buffers and textures) into <out>/addons/kaykit_medieval_hexagon_pack/Assets/gltf/ and writes a SHA-256 sidecar for integrity verification. Without --out it defaults to ./models (or an existing public/models/). The plan + runtime are deterministic — same seed, same render, byte-for-byte.
Bought the premium EXTRA pack on itch.io? Point the same command at your zip — the edition is auto-detected:
pnpm exec declarative-hex-worlds bootstrap --source zip --zip ~/Downloads/KayKit_Medieval_Hexagon_Pack_1.0_EXTRA.zipSee the asset bootstrap guide for the full FREE + EXTRA story.
@react-three/fiberis an optional companion (pnpm add @react-three/fiber). It's not a hard dep because some consumers prefer a different react-three layer; the library's own/threesubpath gives you the raw helpers if you'd rather skip it.
Why this exists
- Declarative API for hex worlds. Describe what you want (a harbor, a forest, a cliff with three depth tiers). The library handles tile selection, connectivity, prop scatter, and validation.
- Deterministic seed-driven generation. Same seed produces byte-identical output across processes and platforms. Server-authoritative simulation, save games, cross-process replay — all work out of the box.
- First-class React + Three.js bindings. Not optional peer-deps. The library tests against the versions it ships; install one package and start rendering.
Module map
The umbrella (declarative-hex-worlds) re-exports everything. For tighter tree-shaking and clearer intent, import from subpaths:
| Subpath | What it gives you |
|---|---|
| declarative-hex-worlds (umbrella) | Everything. Prototyping. |
| /core | The runtime-free, renderer-free tier: asset-source + tileset schemas, the recipe/scenario/blueprint → plan compilers, hex algebra + A* pathfinding, board-aware navigation + occupancy, plan validation, and interop snapshots. No koota, no three. |
| /gameboard | Plan builder, tile + placement spec types |
| /coordinates | Hex algebra, axial / world transforms |
| /scenario, /blueprint, /recipe | Scenario → blueprint → recipe compiler |
| /koota | ECS world + actor / placement spawn helpers |
| /runtime | Runtime facade + snapshot |
| /react | React provider + hooks |
| /three | three.js renderer binding — GLTF loaders + scene reconciliation (3D) |
| /canvas2d | canvas-2D renderer binding — tileset sprite blitting (2D), zero renderer deps |
| /react-elements | Declarative JSX elements (<HexWorld>/<Tile>/<Tileset>/<Model>/<GameboardObjects>) + hooks |
| /asset-source | The AssetSourceSpec schema + sources (createSourceFromSpec, createTilesetSource, tilesetHexGeometry), the bind/init/web scan core, and PNG atlas measurement |
| /bootstrap | Programmatic asset bootstrap (CLI alternative) |
| /errors | GameboardError + subclasses for instanceof catching |
| /manifest/free, /manifest/schema | The FREE manifest metadata + schema |
Full subpath list with API reference →
Dependency tiers
Every engine is an optional peer — you install only what the entrypoint you use needs:
| You import… | You need to install |
|---|---|
| declarative-hex-worlds/core | just this package (it bundles honeycomb-grid + zod) — no koota, no three, no react |
| declarative-hex-worlds (main) / runtime subpaths | + koota (+ react for the React bindings) |
| declarative-hex-worlds/three | + three (the 3D renderer binding) |
| declarative-hex-worlds/canvas2d | nothing extra — the 2D renderer binding draws to a standard 2D canvas context |
| declarative-hex-worlds/react | + react react-dom |
| declarative-hex-worlds/react-elements | + react react-dom three @react-three/fiber |
The /core tier is the "declare + JSON + validate + hex math, bring-your-own runtime/renderer" path: author and validate boards, run pathfinding, and mount into your own ECS via interop snapshots — without pulling in the koota ECS or a renderer.
Docs
| Get started | Features | Reference | |---|---|---| | Quickstart | Feature gallery | API reference | | Asset bootstrap | CLI | Errors | | Tilesets | Bindings + bundling | Determinism | | Bindings + bundling | Determinism contract | Architecture | | Testing | Design rationale | Deployment |
For AI agents (llms.txt standard): llms.txt · llms-small.txt (guides, fits one context window) · llms-full.txt (guides + complete API reference). AGENTS.md covers working on the repo.
CLI
The library ships a Node binary. Common commands:
declarative-hex-worlds bootstrap # download the suggested CC0 KayKit packs (run once)
declarative-hex-worlds doctor # check local setup
declarative-hex-worlds validate-scenario --scenario ./my-scenario.json
declarative-hex-worlds coverage --json # release-readiness ledgerBind your own assets → an AssetSourceSpec (three front-ends, one validated spec):
declarative-hex-worlds bind --dir public/assets --cols 5 --rows 10 # agent: flags in, JSON out
declarative-hex-worlds init --dir public/assets # human: a TTY wizard
declarative-hex-worlds web --dir public/assets # human: a local web formbind is non-interactive (scriptable, CI/agent-friendly); init walks you through the
bindings in the terminal; web serves a loopback config UI. Downloadable packs are
suggested defaults in the same flow as scanning your own assets — never a special path.
Full CLI reference → · llms.txt (agent quickstart)
What ships
- The npm tarball is small (~2.3 MB; ~175 files). It contains the manifest, the compiled JS + DTS, the README, and a handful of curated showcase PNGs.
- The KayKit FREE GLTF tree (~30 MB; 221 models) is bootstrap-fetched at install time. CC0 license; the bootstrap command also writes a SHA-256 integrity sidecar.
- The EXTRA edition is a paid itch.io purchase. The library supports it via
bootstrap --source zip --zip <your-extra.zip>but never bundles it.
Contributing
pnpm verify runs every CI gate locally. See CONTRIBUTING.md. The PRD in docs/PRD/1.0.md explains the why.
Conventional Commits required. PRs are squash-merged. Coverage gate enforces 100 / 100 / 100 / 100; regressions block merge.
License
MIT for the library code.
KayKit Medieval Hexagon Pack © Kay Lousberg, CC0-1.0. Adventurers / EXTRA pack and other KayKit content have their own licenses; see NOTICE.md.
