Forge Universe

JavaScript API

Scripts load in dependency order. UniverseWorld has no DOM dependency; renderer modules attach to globalThis.

UniverseWorld (universe-world.js)

Constants

Export Description
SOLID_TYPES Allowed type strings.
TYPE_ALIASES e.g. { cube: 'hexahedron' }.
HEXAHEDRON_EDGES Cube edge index pairs.

Scene loading

Function Returns Description
loadScene(json) scene JSON.parse if string; runs validateScene.
validateScene(scene) scene Throws on invalid version, nodes, or types.
createSolid(type, id, pose, opts) node Builder for a single node (opts.size, opts.radius).
createPlatonicScene() scene Six-node demo layout.

Pose and geometry

Function Description
normalizeType(type) Resolves aliases (cubehexahedron).
applyPose(point, pose) Rotate [x,y,z] then translate.
getSolidWireframe(node) { vertices, edges } or { sphereRings, isSphere }.
getNodeHalfSize(node) Half-edge from size.
getNodeRadius(node) Radius from radius or size.

Projection

Function Description
projectOrtho(point, scale) 2D orthographic (Y flipped).
projectPerspective(point, camera, w, h) Pinhole projection; returns { x, y, z }.
projectNodeWireframe(node, camera, w, h, mode, scale) Full node projection. Modes: 'ortho', 'perspective'. Returns { kind: 'wireframe' \| 'sphereWire', … }.
projectNodeAxisPanel(node, axis, w, h, scale) Orthographic onto XY, XZ, or YZ plane.
wireframeToSvg(data, stroke, strokeWidth) SVG markup string from projection data.

Governance helper

Function Description
hashAttrs(hash, name) hash="…" data-ks-hash="…" data-ks-type="universe" data-ks-name="…".

UniverseProject2D (universe-project-2d.js)

Export Description
HASH 'Up2'
mount(container, sceneUrl) Fetch scene; render ortho + perspective panels for hexahedron and sphere.
renderPanel(scene, mode) HTML string for one panel ('ortho' or 'perspective').

Scripts: universe-world.js, universe-project-2d.js, universe-demo-boot.js

UniverseStaticCss (universe-static-css.js)

Export Description
HASH 'Us3'
mount(container, sceneUrl) Gallery grid; wires flyout if UniverseSolidFlyout is present.
renderScene(scene) HTML string for all solid cards.

Hexahedron tiles use CSS preserve-3d cube; other solids use SVG wireframes.

Scripts: universe-world.js, universe-static-css.js (+ Three.js stack for flyout — see below)

UniverseSolidFlyout (universe-solid-flyout.js)

Export Description
HASH 'Ufl'
open(node) Show modal with dronie WebGL and XYZ SVG panels.
close() Hide modal and dispose WebGL.
wireGallery(galleryEl, nodes) Click / keyboard handlers on .fu-solid-card.

Dronie orbit pauses when prefers-reduced-motion: reduce is set (static camera instead).

Requires: THREE, UniverseWorld. Optional: UniverseDynamicGl (reuses dronieCamera).

UniverseDynamicGl (universe-dynamic-gl.js)

Export Description
HASH 'Udr'
mount(container, sceneUrl, opts) Promise → WebGL scene with play/pause dronie.
dronieCamera(t, radius, height, target) Orbital camera position for time t.

Scripts: three.min.js, universe-world.js, universe-fps-hud.js, universe-dynamic-gl.js

UniverseSim (universe-sim.js)

Low-cost rigid-body integrator (semi-implicit Euler). Requires UniverseWorld loaded first.

Export Description
createSim(scene) Build sim state from scene.sim; link bodies to nodes; snapshot origins for reset.
step(sim, dt?) Integrate one timestep; sync node.pose for each body; increment sim.time. Optional dt overrides sim.dt.
reset(sim) Restore positions and velocities from create-time snapshot; sim.time = 0.
maxSpeed(sim) Maximum linear speed across bodies (tests / diagnostics).

The returned sim object exposes dt, integrator ("semi_implicit_euler"), gravity, ground, bodies, time, and scene.

Scripts: universe-world.js, universe-sim.js

UniverseSimGl (universe-sim-gl.js)

WebGL view driven by UniverseSim — fetches a scene, builds Three.js meshes for all nodes, steps physics while playing, and syncs mesh positions from node.pose each frame.

Export Description
HASH 'Usb'
mount(container, sceneUrl, opts) Promise → { destroy }. Renders ground plane, play/pause (or step-once under reduced motion), reset. Sets data-ks-hash="Usb" on root. opts.height defaults canvas height (default 480).

Requires: THREE, UniverseWorld, UniverseSim. Optional: UniverseFpsHud.

Scripts (sim-bounce page order):

<script src="/js/vendor/three.min.js"></script>
<script src="/js/universe-world.js"></script>
<script src="/js/universe-sim.js"></script>
<script src="/js/universe-fps-hud.js"></script>
<script src="/js/universe-sim-gl.js"></script>
<script src="/js/universe-demo-boot.js"></script>

universe-demo-boot.js mounts #mount-sim with /assets/scenes/sim-bounce.json when UniverseSimGl is present.

Construction assets (js/forge-universe-assets/*.mjs)

ES modules for GLB loading and kinematic articulation. Not loaded via universe-demo-boot.js — the construction demo is self-contained.

Module Exports
asset-world.mjs validateScene, loadScene, resolveAssetUri, poseValues
articulation-runtime.mjs ArticulationController
asset-renderer.mjs mount(container, sceneUrl, opts) → app with setJoint, describe, assets
state-bridge.mjs ForgeStateBridge for forge-universe/state-v1 WebSocket messages

Import map (construction-assets page):

<script type="importmap">
{ "imports": {
    "three": "/js/vendor/three/three.module.min.js",
    "three/addons/": "/js/vendor/three/addons/"
}}
</script>
<script type="module">
  import { mount } from '/js/forge-universe-assets/asset-renderer.mjs';
  const app = await mount('#forge-stage', '/assets/scenes/construction-site.json');
</script>

See Construction assets. Hash Uca.

UniverseFpsHud (universe-fps-hud.js)

FPS overlay on WebGL root. Instantiated internally by UniverseDynamicGl and UniverseSimGl.

Demo boot (universe-demo-boot.js)

Reads mount element IDs and calls the matching mount() with default scene URLs under /assets/scenes/:

Element ID Module Scene
#mount-projections UniverseProject2D projections-demo.json
#mount-static UniverseStaticCss five-solids-static.json
#mount-drone UniverseDynamicGl five-solids-drone.json
#mount-sim UniverseSimGl sim-bounce.json

Typical integration

<div id="mount-static"></div>
<script src="/js/vendor/three.min.js"></script>
<script src="/js/universe-world.js"></script>
<script src="/js/universe-dynamic-gl.js"></script>
<script src="/js/universe-solid-flyout.js"></script>
<script src="/js/universe-static-css.js"></script>
<script>
  UniverseStaticCss.mount('#mount-static', '/assets/scenes/five-solids-static.json');
</script>