Skip to content
Konjure / spatial intelligence

Spatial applications

Build visible scenes with shared coordinates, geometry and physics.

Spatial work starts with ordinary entities and typed components. Transform places an entity, geometry makes it visible, and Material controls its appearance. The spatial host uses a right-handed frame: +X is right, +Y is up, and −Z is forward. Positions use meters; Transform.rotation stores XYZ Euler angles in radians.

Animate a scene

Compile the activity fixture and press Play or Step. The Rotate system changes each spinner’s transform. Select an entity to inspect its components; the Reverse scene control invokes the function stored in its typed action field.

Tick 0 · 0.00 sThis device
main.kj⌘ / Ctrl + Enter
Loading…Drag to orbit · select to inspect
0 entities
Loading the language runtime…
Output 0
No output.

One entity may carry one geometry component. Geometry entities receive default Transform and Material during spatial normalization when absent, after initialization, an action, or a tick’s systems finish. Add those components explicitly whenever code in the same operation needs to read them.

Add physics deliberately

Compile the physics fixture, step it, then invoke Jump. Dynamic bodies fall under gravity and the action adds a one-time upward Impulse.

Tick 0 · 0.00 sThis device
main.kj⌘ / Ctrl + Enter
Loading…Drag to orbit · select to inspect
0 entities
Loading the language runtime…
Output 0
No output.

The spatial host advances a fixed 1 / 60 second tick. RigidBody.kind is "dynamic", "fixed", or "kinematic"; current physical collision shapes are Sphere and Box. Dynamic-body position and rotation belong to physics: move one using velocity, persistent Force, or one-time Impulse. Kinematic bodies accept pose edits and integrate declared velocities. A physical sphere requires uniform scale. The physics bridge uses 32-bit floating point, so use numeric tolerances when comparing its results to language Number values.

Gravity is (0, -9.81, 0) in meters per second squared. A Force persists across ticks; an Impulse is consumed once and its vector resets to zero. Both require a dynamic body. Fixed bodies reject nonzero linear or angular velocity; missing or unsupported collision shapes fail validation.

Connect typed controls

Button.action accepts func() -> Res[Unit, DataError]; Slider.action accepts func(Number) -> Res[Unit, DataError] and receives the selected value. Supply a function value, not a string containing its name. The compiler checks the signature before running the program; callbacks stored on components do not require export.

Tick 0 · 0.00 sThis device
main.kj⌘ / Ctrl + Enter
Loading the language runtime…
Output 0
No output.

Press Count twice, then choose the counter in Debug: clicks is 2. Move Value to call set with a Number. Each callback resolves the current Counter component through bind[Counter](item) and commits its changes transactionally. A returned Err rolls the host interaction back. It does not capture a stale copy of the component. The slider renders Slider.value, so Counter.set updates that field in the same transaction as the counter’s value.

Try assigning the slider’s .set method to Button.action: compilation rejects the extra required argument. An entity removed after binding causes a runtime diagnostic; its stored callback cannot bring the entity back.

These host calls are separate from lifecycle callbacks. Media and stream components describe resources; consult their standard library entries for current support before depending on capture or playback.

Edit exercise

In the activity fixture, change one spinner’s speed from 1.2 to 2.4 and step once: its inspected rotation should advance twice as far as before. In the physics fixture, change the floor body from "fixed" to "dynamic". After a step, its inspected position should move downward under gravity; change it back when the floor should remain a stable collision surface.

A spatial tick runs systems, validates and reconciles the candidate scene, applies forces and impulses, integrates physics and contacts, writes results back, then commits as one transaction. A failure rolls back language and physics state together. Contact pairs are reports, not language event handlers. Read the language reference for transaction and execution rules, built-ins for component fields, and language design for planned capabilities.