Enaction Engine is a deterministic, type-safe game engine for worlds shaped through perception, affect, intention, action and consequence.
The name describes the intended whole: agents and worlds continuously constitute
and alter one another through situated action. The current code is deliberately
smaller than that destination. It is an early deterministic timing and
interpolation substrate, implemented in Rust and tested as one crate.
n
The simulation advances only in whole, equal steps, and render interpolation never feeds simulation state.
Variable frame time must not become simulation input. enaction-time therefore
turns elapsed wall time into a count of whole fixed steps and a render-only
fraction. A host simulates the whole steps, then may use that fraction to draw
continuous values between two completed states. Discrete values are read from
the current state, never blended.
What exists is a timing crate plus one deliberately small typed event seam:
The repository currently provides enaction-time:
| Artifact | Implemented behaviour | Evidence and provenance |
|---|---|---|
|
Fixed-timestep accumulation, whole-step counts, a render fraction, hostile input handling, and a configurable spiral-of-death guard. |
Unit and doctests in this repository. New engine code; it has not yet run in a released game. |
|
Two inline fixed-size state buffers, commit/prime/snap operations, exact endpoints, and render-only interpolation of continuous values. |
Tests inherited or derived from IDApTIK experience. The interpolation design has served in IDApTIK; this extracted crate has not yet replaced that game code. |
|
Clamped, endpoint-exact interpolation, including measured floating-point edge cases. |
Unit tests, doctests, and size checks. No heap allocation appears in these operations or in the fixed-size buffer representation. |
Discontinuities such as teleports, restarts, loads, or resynchronisation use
commit followed by snap: the new state first enters the buffer, then stale
history is discarded.
Enaction Engine is intended to grow into a complete game engine. Its destination includes deterministic simulation; world and event models; agency and embodiment; physics and interaction; rendering and presentation; sound and music; input; networking and multiplayer; persistence and replay; assets and content; host contracts; tools; and Universal Modding Studio integration.
That direction is not a claim that those systems exist today. There is currently no renderer, ECS, audio system, input layer, asset pipeline, networking stack, general AI framework, physical simulation, or complete cognitive, affective, or conative implementation here. New modules must arrive with a real use, implementation, and tests; empty subsystem crates are explicitly disallowed.
These are sibling dimensions of agency, not competing names for the engine:
-
cognition covers perception, attention, memory, belief, inference, and planning;
-
affect covers appraisal, mood, atmosphere, trust, fear, attachment, and significance;
-
conation covers needs, motives, goals, commitment, inhibition, and action selection.
They operate over host-defined entities, events, worlds, ecologies, and institutions. Games retain their domain ontology and game-specific rules.
IDApTIK is the first proving
ground. Its deterministic, event-sourced Rust core supplied the operational
experience behind DoubleBuffer, discontinuity handling, continuous-versus-
discrete rendering, replay, and snapshot concerns. FixedStep itself is new
engine code and is not yet integrated into IDApTIK.
Chronicles of Slavia is the planned second abstraction test. A facility should not be called general merely because one game can use it: the second game must exercise the boundary without importing IDApTIK-specific ontology into the engine.
Universal Modding Studio (UMS) will author, generate, validate, preview, and package content through versioned game profiles and contracts. Enaction Engine is runtime infrastructure; it must not depend on the UMS application. Released games consume validated, compiled packages rather than the editor UI. See UMS integration.
use enaction_time::{DoubleBuffer, FixedStep};
let mut clock = FixedStep::from_hz(60.0);
let mut buffer: DoubleBuffer<f64, 1> = DoubleBuffer::new();
buffer.prime(&[world.x()]);
for _ in 0..clock.advance(real_dt) {
world.step(); // whole steps only
buffer.commit(&[world.x()]);
}
draw(buffer.sample(0, clock.alpha())); // render-onlycrates/enaction-time/tests/idaptik_parity.rs covers healthy fixed-step
accounting, hostile elapsed time, interpolation, discrete versus continuous
state, discontinuities and snapshot/restart interaction. It proves the
extracted interpolation boundary; it does not prove that IDApTIK uses
FixedStep. IDApTIK still uses Bevy’s accumulator, and this pass deliberately
does not replace it.
Enaction is a runtime dependency candidate below games. It does not depend on
UMS. An optional UMS preview adapter may be added later, but released games must
not depend on the UMS UI. The current IDApTIK appraisal example is game-local;
the general enaction-trace seam is new and remains unadopted.
The intended long-term implementation language is AffineScript. This is Rust, deliberately and for now: AffineScript is a real working compiler, but it ships no release artefact and its typed-wasm bridge is still gated. The port is gated on both of those, and would pin to a compiler commit rather than a version. See ADR-0004.
crates/enaction-time/ current Rust timing and interpolation crate
docs/architecture/ target architecture and integration boundaries
docs/decisions/ accepted architecture decisions
docs/status/ROADMAP.adoc evidence-gated staged direction
.machine_readable/ RSR metadata, policies, and contracts
build/just/ recipes imported by the root Justfile
scripts/ repository and verification gatescargo fmt --all -- --check
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
just test
just verifyThe exact RSR gates behind just verify are defined in Justfile and
build/just/. EXPLAINME.adoc maps the major claims above to implementation
artifacts and checks.
Rust is the implementation language now. AffineScript is a future direction only when it has a genuine release artefact and the required typed-Wasm path is ready. Any later port must preserve behaviour and tests, pin its toolchain, and earn adoption through working integration; no AffineScript build is claimed today. See ADR-0004.
-
The crate supplies timing and interpolation utilities, not a frame loop or a complete engine runtime.
-
Determinism of a whole game still depends on the host using deterministic state, ordering, arithmetic, inputs, and side-effect boundaries.
-
FixedStepdrops excess accumulated time when its step cap is reached; hosts should observetook_shortcut()and decide how to surface degraded timing. -
The no-allocation evidence covers the current fixed-size value representation and its operations, not an instrumented whole-process allocator trace.
-
Current extracted code has not yet been validated as a reusable contract by two games.
Code, configuration, and scripts are GNU Affero General Public
License v3.0 or later (AGPL-3.0-or-later). Prose documentation is
CC-BY-SA-4.0. Full texts are in LICENSES/; per-file SPDX headers remain
authoritative. Long-term attribution uses Quantum-Safe Provenance as described
in the provenance exhibit.