@diceforge-sdk/assets-forge
v0.7.0
Published
The first-party DiceForge die set: d4-d20 models, a two-faced coin, and texture atlases in five colours, resolved to URLs your bundler emits.
Maintainers
Readme
@diceforge-sdk/assets-forge
The first-party DiceForge die set, installable from npm: d4, d6, d8, d10, d12, d20, and a coin whose heads and tails are textured separately — in ivory, red, blue, green and yellow.
This package carries the art. It has no dependencies, contains no renderer code, and decides nothing: it hands you URLs. The engine resolves the roll, and the renderer's animation ends on the face the engine chose.
Install
npm install @diceforge-sdk/assets-forge @diceforge-sdk/renderer-webUse
import { forgeAssets } from "@diceforge-sdk/assets-forge";
import { createDicePresenter, forgeTheme } from "@diceforge-sdk/renderer-web";
const presenter = createDicePresenter({
container: document.querySelector("#stage")!,
theme: forgeTheme(forgeAssets({ color: "red" })),
});
await presenter.present(engine.roll("4d6dl1"));forgeAssets() returns { color, urls }, which is exactly what forgeTheme() takes: the colour picks the 2D fallback tiles, the URLs point at the models and atlases. It defaults to ivory.
How the URLs resolve
Every URL is a literal new URL("...", import.meta.url) — the pattern Vite, webpack 5 and Rollup recognise. They copy the file into your build output and rewrite the URL to match, so there is no copying, no public/ directory, and no path configuration.
Two things follow from that:
- A bundler emits all five colours (~1.6 MB of models and textures), because the URL table is static and cannot be tree-shaken by colour. If that matters, import single files through the
./forge/*subpath, or serve the directory yourself withbaseUrl(below). - Without a bundler the same expressions resolve to
file:URLs beside the installed package — useful for a copy step or a static server, not for a browser.
Serving the files yourself
If you would rather host the art — a CDN, a public/ directory, an app that does not bundle — copy it and point the theme at it:
cp -r node_modules/@diceforge-sdk/assets-forge/forge public/diceforgeTheme({ baseUrl: "/dice", color: "red" });The directory layout is stable: d<sides>.glb, coin.glb, face-rotations.json, and textures/<colour>/*.png. FORGE_ASSET_FILES lists every file if you need it in a copy script or a service-worker precache list.
To locate the installed directory from Node:
import { fileURLToPath } from "node:url";
const dir = fileURLToPath(
new URL(".", import.meta.resolve("@diceforge-sdk/assets-forge/forge/d20.glb")),
);
app.use("/dice", express.static(dir));Exports
| | |
| --- | --- |
| forgeAssets({ color }) | { color, urls } for one colour — the everyday entry point |
| FORGE_MODEL_URLS / FORGE_COIN_URL | Model URLs, shared by every colour |
| FORGE_TEXTURE_URLS | Texture URLs per colour |
| FORGE_FACE_ROTATIONS_URL | The generator's manifest: face counts, UV atlas, rotation tables |
| FORGE_ASSET_FILES | Every shipped file, relative to forge/ |
| FORGE_COLORS / FORGE_SHAPES | What the set covers |
One model serves every colour — a theme swaps the texture atlas, not the mesh.
Where these come from
The models and textures are generated by a committed, headless Blender pipeline (tools/blender/, ADR-0011). Faces are numbered so opposite faces sum to N+1, which makes the face-up rotation table exact by construction rather than hand-calibrated — the renderer can therefore prove which orientation shows which value, and never imply a face the core did not resolve.
Regenerating is a maintainer task; consuming this package never requires Blender.
Versioning
Released in lockstep with @diceforge-sdk/core and @diceforge-sdk/renderer-web at a matching version (ADR-0009). Art may change between minor versions before 1.0 — pin an exact version if a visual diff would break your tests.
Licence
MIT, art included. Provenance is recorded in assets/LICENSES.md.
